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:
chamikaJ
2025-04-18 17:10:56 +05:30
parent 8825b0410a
commit e42819ef64
34 changed files with 948 additions and 376 deletions

View 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"

View File

@@ -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.

View File

@@ -0,0 +1,3 @@
-- Extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "unaccent";

View File

@@ -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,

View File

@@ -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

View File

@@ -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);