Update environment configuration, Docker setup, and frontend/backend dependencies
- Updated .env.example and .env files for backend and frontend with placeholder values. - Enhanced .gitignore to include additional files and directories. - Modified docker-compose.yml to change image names and improve service health checks. - Updated README.md and SETUP_THE_PROJECT.md for clearer setup instructions. - Added database initialization scripts and SQL files for structured database setup. - Updated frontend Dockerfile to use Node.js 22 and adjusted package.json scripts. - Improved error handling and logging in start scripts for better debugging. - Added reCAPTCHA support in the signup page with conditional loading based on environment variables.
This commit is contained in:
55
worklenz-backend/database/00-init-db.sh
Normal file
55
worklenz-backend/database/00-init-db.sh
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# This script controls the order of SQL file execution during database initialization
|
||||
echo "Starting database initialization..."
|
||||
|
||||
# Check if we have SQL files in expected locations
|
||||
if [ -f "/docker-entrypoint-initdb.d/sql/0_extensions.sql" ]; then
|
||||
SQL_DIR="/docker-entrypoint-initdb.d/sql"
|
||||
echo "Using SQL files from sql/ subdirectory"
|
||||
elif [ -f "/docker-entrypoint-initdb.d/0_extensions.sql" ]; then
|
||||
# First time setup - move files to subdirectory
|
||||
echo "Moving SQL files to sql/ subdirectory..."
|
||||
mkdir -p /docker-entrypoint-initdb.d/sql
|
||||
|
||||
# Move all SQL files (except this script) to the subdirectory
|
||||
for f in /docker-entrypoint-initdb.d/*.sql; do
|
||||
if [ -f "$f" ]; then
|
||||
cp "$f" /docker-entrypoint-initdb.d/sql/
|
||||
echo "Copied $f to sql/ subdirectory"
|
||||
fi
|
||||
done
|
||||
|
||||
SQL_DIR="/docker-entrypoint-initdb.d/sql"
|
||||
else
|
||||
echo "SQL files not found in expected locations!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute SQL files in the correct order
|
||||
echo "Executing 0_extensions.sql..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/0_extensions.sql"
|
||||
|
||||
echo "Executing 1_tables.sql..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/1_tables.sql"
|
||||
|
||||
echo "Executing indexes.sql..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/indexes.sql"
|
||||
|
||||
echo "Executing 4_functions.sql..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/4_functions.sql"
|
||||
|
||||
echo "Executing triggers.sql..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/triggers.sql"
|
||||
|
||||
echo "Executing 3_views.sql..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/3_views.sql"
|
||||
|
||||
echo "Executing 2_dml.sql..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/2_dml.sql"
|
||||
|
||||
echo "Executing 5_database_user.sql..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/5_database_user.sql"
|
||||
|
||||
echo "Database initialization completed successfully"
|
||||
@@ -1 +1,36 @@
|
||||
All database DDLs, DMLs and migrations relates to the application should be stored here as well.
|
||||
|
||||
# Worklenz Database
|
||||
|
||||
## Directory Structure
|
||||
|
||||
- `sql/` - Contains all SQL files needed for database initialization
|
||||
- `migrations/` - Contains database migration scripts
|
||||
- `00-init-db.sh` - Initialization script that executes SQL files in the correct order
|
||||
|
||||
## SQL File Execution Order
|
||||
|
||||
The database initialization files should be executed in the following order:
|
||||
|
||||
1. `sql/0_extensions.sql` - PostgreSQL extensions
|
||||
2. `sql/1_tables.sql` - Table definitions and constraints
|
||||
3. `sql/indexes.sql` - All database indexes
|
||||
4. `sql/4_functions.sql` - Database functions
|
||||
5. `sql/triggers.sql` - Database triggers
|
||||
6. `sql/3_views.sql` - Database views
|
||||
7. `sql/2_dml.sql` - Data Manipulation Language statements (inserts, updates)
|
||||
8. `sql/5_database_user.sql` - Database user setup
|
||||
|
||||
## Docker-based Setup
|
||||
|
||||
In the Docker environment, we use a shell script called `00-init-db.sh` to control the SQL file execution order:
|
||||
|
||||
1. The shell script creates a `sql/` subdirectory if it doesn't exist
|
||||
2. It copies all .sql files into this subdirectory
|
||||
3. It executes the SQL files from the subdirectory in the correct order
|
||||
|
||||
This approach prevents the SQL files from being executed twice by Docker's automatic initialization mechanism, which would cause errors for objects that already exist.
|
||||
|
||||
## Manual Setup
|
||||
|
||||
If you're setting up the database manually, please follow the execution order listed above. Ensure your SQL files are in the `sql/` subdirectory before executing the script.
|
||||
|
||||
3
worklenz-backend/database/sql/0_extensions.sql
Normal file
3
worklenz-backend/database/sql/0_extensions.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
-- Extensions
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "unaccent";
|
||||
@@ -1,7 +1,3 @@
|
||||
-- Extensions
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "unaccent";
|
||||
|
||||
-- Domains
|
||||
CREATE DOMAIN WL_HEX_COLOR AS TEXT CHECK (value ~* '^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$');
|
||||
CREATE DOMAIN WL_EMAIL AS TEXT CHECK (value ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');
|
||||
@@ -18,7 +14,27 @@ CREATE TYPE SCHEDULE_TYPE AS ENUM ('daily', 'weekly', 'yearly', 'monthly', 'ever
|
||||
|
||||
CREATE TYPE LANGUAGE_TYPE AS ENUM ('en', 'es', 'pt');
|
||||
|
||||
-- START: Users
|
||||
CREATE SEQUENCE IF NOT EXISTS users_user_no_seq START 1;
|
||||
|
||||
-- Utility and referenced tables
|
||||
-- Create sessions table for connect-pg-simple session store
|
||||
CREATE TABLE IF NOT EXISTS pg_sessions (
|
||||
sid VARCHAR NOT NULL PRIMARY KEY,
|
||||
sess JSON NOT NULL,
|
||||
expire TIMESTAMP(6) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS project_access_levels (
|
||||
id UUID DEFAULT uuid_generate_v4() NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
key TEXT NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE project_access_levels
|
||||
ADD CONSTRAINT project_access_levels_pk
|
||||
PRIMARY KEY (id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS countries (
|
||||
id UUID DEFAULT uuid_generate_v4() NOT NULL,
|
||||
code CHAR(2) NOT NULL,
|
||||
@@ -40,7 +56,6 @@ ALTER TABLE permissions
|
||||
ADD CONSTRAINT permissions_pk
|
||||
PRIMARY KEY (id);
|
||||
|
||||
-- Tables that reference utility tables
|
||||
CREATE TABLE IF NOT EXISTS archived_projects (
|
||||
user_id UUID NOT NULL,
|
||||
project_id UUID NOT NULL
|
||||
@@ -77,7 +92,6 @@ ALTER TABLE clients
|
||||
ADD CONSTRAINT clients_name_check
|
||||
CHECK (CHAR_LENGTH(name) <= 60);
|
||||
|
||||
-- Remaining tables
|
||||
CREATE TABLE IF NOT EXISTS cpt_phases (
|
||||
id UUID DEFAULT uuid_generate_v4() NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
@@ -232,11 +246,6 @@ ALTER TABLE email_invitations
|
||||
ADD CONSTRAINT email_invitations_pk
|
||||
PRIMARY KEY (id);
|
||||
|
||||
CREATE TRIGGER email_invitations_email_lower
|
||||
BEFORE INSERT OR UPDATE
|
||||
ON email_invitations
|
||||
EXECUTE PROCEDURE lower_email();
|
||||
|
||||
CREATE TABLE IF NOT EXISTS favorite_projects (
|
||||
user_id UUID NOT NULL,
|
||||
project_id UUID NOT NULL
|
||||
@@ -260,6 +269,35 @@ ALTER TABLE job_titles
|
||||
ADD CONSTRAINT job_titles_name_check
|
||||
CHECK (CHAR_LENGTH(name) <= 55);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS licensing_admin_users (
|
||||
id UUID DEFAULT uuid_generate_v4() NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
username TEXT NOT NULL,
|
||||
phone_no TEXT NOT NULL,
|
||||
otp TEXT,
|
||||
otp_expiry TIMESTAMP WITH TIME ZONE,
|
||||
active BOOLEAN DEFAULT TRUE NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE licensing_admin_users
|
||||
ADD CONSTRAINT licensing_admin_users_id_pk
|
||||
PRIMARY KEY (id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS licensing_app_sumo_batches (
|
||||
id UUID DEFAULT uuid_generate_v4() NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by UUID NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE licensing_app_sumo_batches
|
||||
ADD CONSTRAINT licensing_app_sumo_batches_pk
|
||||
PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE licensing_app_sumo_batches
|
||||
ADD CONSTRAINT licensing_app_sumo_batches_created_by_fk
|
||||
FOREIGN KEY (created_by) REFERENCES licensing_admin_users;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS licensing_coupon_codes (
|
||||
id UUID DEFAULT uuid_generate_v4() NOT NULL,
|
||||
coupon_code TEXT NOT NULL,
|
||||
@@ -283,11 +321,6 @@ ALTER TABLE licensing_coupon_codes
|
||||
ADD CONSTRAINT licensing_coupon_codes_pk
|
||||
PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE licensing_coupon_codes
|
||||
ADD CONSTRAINT licensing_coupon_codes_app_sumo_batches__fk
|
||||
FOREIGN KEY (batch_id) REFERENCES licensing_app_sumo_batches
|
||||
ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE licensing_coupon_codes
|
||||
ADD CONSTRAINT licensing_coupon_codes_created_by_fk
|
||||
FOREIGN KEY (created_by) REFERENCES licensing_admin_users;
|
||||
@@ -1466,33 +1499,6 @@ ALTER TABLE tasks
|
||||
ADD CONSTRAINT tasks_total_minutes_check
|
||||
CHECK ((total_minutes >= (0)::NUMERIC) AND (total_minutes <= (999999)::NUMERIC));
|
||||
|
||||
CREATE TRIGGER projects_tasks_counter_trigger
|
||||
BEFORE INSERT
|
||||
ON tasks
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE update_project_tasks_counter_trigger_fn();
|
||||
|
||||
CREATE TRIGGER set_task_updated_at
|
||||
BEFORE UPDATE
|
||||
ON tasks
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE set_task_updated_at_trigger_fn();
|
||||
|
||||
CREATE TRIGGER tasks_status_id_change
|
||||
AFTER UPDATE
|
||||
OF status_id
|
||||
ON tasks
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE task_status_change_trigger_fn();
|
||||
|
||||
CREATE TRIGGER tasks_task_subscriber_notify_done
|
||||
BEFORE UPDATE
|
||||
OF status_id
|
||||
ON tasks
|
||||
FOR EACH ROW
|
||||
WHEN (old.status_id IS DISTINCT FROM new.status_id)
|
||||
EXECUTE PROCEDURE tasks_task_subscriber_notify_done_trigger();
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tasks_assignees (
|
||||
task_id UUID NOT NULL,
|
||||
project_member_id UUID NOT NULL,
|
||||
@@ -1579,18 +1585,6 @@ ALTER TABLE team_members
|
||||
ADD CONSTRAINT team_members_role_id_fk
|
||||
FOREIGN KEY (role_id) REFERENCES roles;
|
||||
|
||||
CREATE TRIGGER insert_notification_settings
|
||||
AFTER INSERT
|
||||
ON team_members
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE notification_settings_insert_trigger_fn();
|
||||
|
||||
CREATE TRIGGER remove_notification_settings
|
||||
BEFORE DELETE
|
||||
ON team_members
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE notification_settings_delete_trigger_fn();
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id UUID DEFAULT uuid_generate_v4() NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
@@ -1640,18 +1634,10 @@ ALTER TABLE licensing_payment_details
|
||||
ADD CONSTRAINT licensing_payment_details_users_id_fk
|
||||
FOREIGN KEY (user_id) REFERENCES users;
|
||||
|
||||
ALTER TABLE licensing_user_payment_methods
|
||||
ADD CONSTRAINT licensing_user_payment_methods_users_id_fk
|
||||
FOREIGN KEY (user_id) REFERENCES users;
|
||||
|
||||
ALTER TABLE licensing_user_subscriptions
|
||||
ADD CONSTRAINT licensing_user_subscriptions_users_id_fk
|
||||
FOREIGN KEY (user_id) REFERENCES users;
|
||||
|
||||
ALTER TABLE licensing_user_subscriptions_log
|
||||
ADD CONSTRAINT licensing_user_subscriptions_log_users_id_fk
|
||||
FOREIGN KEY (user_id) REFERENCES users;
|
||||
|
||||
ALTER TABLE notification_settings
|
||||
ADD CONSTRAINT notification_settings_user_id_fk
|
||||
FOREIGN KEY (user_id) REFERENCES users
|
||||
@@ -1751,11 +1737,6 @@ ALTER TABLE users
|
||||
ADD CONSTRAINT users_name_check
|
||||
CHECK (CHAR_LENGTH(name) <= 55);
|
||||
|
||||
CREATE TRIGGER users_email_lower
|
||||
BEFORE INSERT OR UPDATE
|
||||
ON users
|
||||
EXECUTE PROCEDURE lower_email();
|
||||
|
||||
CREATE TABLE IF NOT EXISTS teams (
|
||||
id UUID DEFAULT uuid_generate_v4() NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
@@ -388,14 +388,14 @@ SELECT sys_insert_project_access_levels();
|
||||
SELECT sys_insert_task_status_categories();
|
||||
SELECT sys_insert_project_statuses();
|
||||
SELECT sys_insert_project_healths();
|
||||
SELECT sys_insert_project_templates();
|
||||
-- SELECT sys_insert_project_templates();
|
||||
|
||||
DROP FUNCTION sys_insert_task_priorities();
|
||||
DROP FUNCTION sys_insert_project_access_levels();
|
||||
DROP FUNCTION sys_insert_task_status_categories();
|
||||
DROP FUNCTION sys_insert_project_statuses();
|
||||
DROP FUNCTION sys_insert_project_healths();
|
||||
DROP FUNCTION sys_insert_project_templates();
|
||||
-- DROP FUNCTION sys_insert_project_templates();
|
||||
|
||||
INSERT INTO timezones (name, abbrev, utc_offset)
|
||||
SELECT name, abbrev, utc_offset
|
||||
@@ -26,12 +26,25 @@ CREATE UNIQUE INDEX IF NOT EXISTS cpt_task_statuses_template_id_name_uindex
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS custom_project_templates_name_team_id_uindex
|
||||
ON custom_project_templates (name, team_id);
|
||||
|
||||
-- Create index on expire field
|
||||
CREATE INDEX IF NOT EXISTS idx_pg_sessions_expire
|
||||
ON pg_sessions (expire);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS job_titles_name_team_id_uindex
|
||||
ON job_titles (name, team_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS job_titles_team_id_index
|
||||
ON job_titles (team_id);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS licensing_admin_users_name_uindex
|
||||
ON licensing_admin_users (name);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS licensing_admin_users_phone_no_uindex
|
||||
ON licensing_admin_users (phone_no);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS licensing_admin_users_username_uindex
|
||||
ON licensing_admin_users (username);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS licensing_coupon_codes_coupon_code_uindex
|
||||
ON licensing_coupon_codes (coupon_code);
|
||||
|
||||
@@ -53,6 +66,12 @@ CREATE INDEX IF NOT EXISTS notification_settings_team_user_id_index
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS personal_todo_list_index_uindex
|
||||
ON personal_todo_list (user_id, index);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS project_access_levels_key_uindex
|
||||
ON project_access_levels (key);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS project_access_levels_name_uindex
|
||||
ON project_access_levels (name);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS project_categories_name_team_id_uindex
|
||||
ON project_categories (name, team_id);
|
||||
|
||||
Reference in New Issue
Block a user