Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
2587b8a
user activity feed - backend
OminduHirushka Jul 9, 2025
5222d75
user activity feed - frontend
OminduHirushka Jul 9, 2025
7c04598
Merge pull request #253 from OminduHirushka/imp/user-activity-feed
chamikaJ Jul 11, 2025
5b1cbb0
Merge branch 'main' of https://github.com/Worklenz/worklenz into feat…
chamikaJ Jul 14, 2025
2a7019c
refactor(home-page): simplify layout by removing unnecessary Card com…
chamikaJ Jul 14, 2025
61461bb
feat(user-activity): enhance user activity logs with additional data …
chamikaJ Jul 14, 2025
f484764
Implement task deletion functionality in TaskCard component
shancds Jul 15, 2025
c80b00e
Add delete status confirmation modal with localization support
shancds Jul 15, 2025
5318f95
Merge branch 'release/v2.1.2' of https://github.com/Worklenz/worklenz…
shancds Jul 15, 2025
d89247e
Add delete phase confirmation modal with localization support
shancds Jul 15, 2025
d7416ff
Merge branch 'test/kanban-right-click-feature-v1.2.1' of https://gith…
shancds Jul 15, 2025
f03f6e6
Implement task order updates and socket emissions in EnhancedKanbanBo…
shancds Jul 15, 2025
6adf40f
Merge pull request #274 from shancds/test/kanban-order-v1.2.2
chamikaJ Jul 16, 2025
7226932
Enhance EnhancedKanbanBoardNativeDnD to support phase reordering
shancds Jul 17, 2025
fa08463
Enhance localization support in Kanban board
shancds Jul 17, 2025
22d2023
Update phase handling in EnhancedKanbanBoardNativeDnD component
shancds Jul 17, 2025
7f71e89
Enhance EnhancedKanbanBoardNativeDnD with task priority updates and s…
shancds Jul 17, 2025
1709fad
Add drag-and-drop data transfer support in EnhancedKanbanBoardNativeDnD
shancds Jul 17, 2025
8dc3133
Merge pull request #275 from shancds/test/kanban-order-v1.2.3
chamikaJ Jul 17, 2025
78d960b
feat(gantt): introduce advanced Gantt chart components and demo page
chamikaJ Jul 20, 2025
3419d7e
Merge branch 'feature/project-gantt-chart' of https://github.com/Work…
shancds Jul 21, 2025
5addcee
Merge branch 'release/v2.1.2' of https://github.com/Worklenz/worklenz…
shancds Jul 21, 2025
06da0d2
Enhance project member drawer localization and UI
shancds Jul 22, 2025
3373dcc
Update localization and UI for team member invitation feature
shancds Jul 22, 2025
da791e2
Enhance project member invitation feature with new localization and U…
shancds Jul 22, 2025
c4400d1
Refactor invite components to comment out unused UI elements
shancds Jul 23, 2025
aaaac09
Merge branch 'fix/release-v2.1.3' of https://github.com/Worklenz/work…
shancds Jul 23, 2025
300d476
Enhance project member management with search functionality and local…
shancds Jul 23, 2025
69b2fe1
feat(reporting): implement timezone support in reporting allocation a…
chamikaJ Jul 24, 2025
de26417
refactor(reporting): enhance timezone handling and clean up migration
chamikaJ Jul 24, 2025
daa6546
feat(reporting): add utility methods for date and time calculations i…
chamikaJ Jul 24, 2025
1931856
Merge branch 'main' of https://github.com/Worklenz/worklenz into fix/…
chamikaJ Jul 24, 2025
980af8b
Merge branch 'imp/invite--improvement' into test/invitation-process
chamikaJ Jul 24, 2025
070c643
Merge pull request #283 from shancds/test/invitation-process
chamikaJ Jul 24, 2025
15ff69a
refactor(styles): remove outdated HubSpot widget dark mode CSS overrides
chamikaJ Jul 24, 2025
fe7c15c
feat(surveys): implement account setup survey functionality
chamikaJ Jul 24, 2025
ff4b0ed
Merge pull request #287 from Worklenz/imp/invite--improvement
chamikaJ Jul 25, 2025
27605b4
feat(assignee-selector): enhance member invitation functionality and …
shancds Jul 25, 2025
e7e9cfc
Merge branch 'release-v2.1.4' of https://github.com/Worklenz/worklenz…
shancds Jul 25, 2025
b688f8e
feat(account-setup): enhance account setup process with new survey an…
chamikaJ Jul 25, 2025
a9d0244
fix(update-member-drawer): correct job title assignment in member upd…
shancds Jul 25, 2025
944acf9
feat(project-member-drawer): filter out already invited members from …
shancds Jul 25, 2025
7dc3ded
feat(account-setup): enhance localization and UI for account setup pr…
chamikaJ Jul 25, 2025
6e71a91
Merge pull request #288 from shancds/test/invitation-process
chamikaJ Jul 25, 2025
cabd05e
Merge pull request #290 from Worklenz/imp/invite--improvement
chamikaJ Jul 25, 2025
65745e3
Merge branch 'release-v2.1.4' into chore/added-sign-up-survey
chamikaJ Jul 25, 2025
f3b7479
Merge pull request #291 from Worklenz/chore/added-sign-up-survey
chamikaJ Jul 25, 2025
2aaf0fc
feat(account-setup): refactor language handling in account setup process
chamikaJ Jul 25, 2025
8380b35
refactor(template-drawer): remove unused parameters from TemplateDraw…
chamikaJ Jul 25, 2025
fd2fc79
Merge pull request #295 from Worklenz/chore/added-sign-up-survey
chamikaJ Jul 25, 2025
2a9e12a
feat(task-time-logs): enhance time log retrieval and formatting with …
chamikaJ Jul 28, 2025
1e6045c
Merge pull request #297 from Worklenz/fix/task-time-log-timezone-fix
chamikaJ Jul 28, 2025
2c860b0
feat(localization): update password-related translations in German an…
chamikaJ Jul 28, 2025
dd511b2
refactor(reporting-layout): streamline sidebar and content layout
chamikaJ Jul 28, 2025
2c0b0ac
Merge pull request #299 from Worklenz/fix/reporting-sidebar-style-fix
chamikaJ Jul 28, 2025
e2a749e
refactor(survey-submission): update validation logic and submission d…
chamikaJ Jul 28, 2025
e2c9e19
Merge pull request #300 from Worklenz/fix/reporting-sidebar-style-fix
chamikaJ Jul 28, 2025
703a642
feat(surveys): add survey tables and initial data for account setup q…
chamikaJ Jul 28, 2025
76adb89
feat(task-filters): enhance sorting functionality and localization up…
chamikaJ Jul 28, 2025
4debcd6
Merge pull request #301 from Worklenz/fix/reporting-sidebar-style-fix
chamikaJ Jul 28, 2025
2082934
feat(hubspot-integration): refine HubSpot widget styling and add acco…
chamikaJ Jul 28, 2025
a8d1446
Merge pull request #302 from Worklenz/fix/reporting-sidebar-style-fix
chamikaJ Jul 28, 2025
e8d21ee
feat(account-setup): implement skip functionality and update localiza…
chamikaJ Jul 28, 2025
25042ba
Merge pull request #303 from Worklenz/fix/reporting-sidebar-style-fix
chamikaJ Jul 28, 2025
c2e670c
feat(survey-localization): add survey localization files for multiple…
chamikaJ Jul 28, 2025
01a580d
Merge pull request #304 from Worklenz/fix/reporting-sidebar-style-fix
chamikaJ Jul 28, 2025
f24c0d8
Merge branch 'release-v2.1.4' into feature/task-activities-by-user
chamikaJ Jul 29, 2025
e8ccc2a
Merge pull request #306 from Worklenz/feature/task-activities-by-user
chamikaJ Jul 29, 2025
53a28cf
refactor(localization): update task-related translations and improve …
chamikaJ Jul 29, 2025
c2b231d
feat(survey-modal): add survey modal configuration to environment files
chamikaJ Jul 29, 2025
29b8c1b
feat(task-context-menu): add copy link functionality and update trans…
chamikaJ Jul 29, 2025
b915de2
feat(reporting): enhance date handling and export functionality
chamikaJ Jul 29, 2025
c53ab51
Merge branch 'main' of https://github.com/Worklenz/worklenz into rele…
chamikaJ Jul 29, 2025
8d17490
fix(reporting): update task logging queries for accuracy
chamikaJ Jul 29, 2025
5cce3bc
feat(localization): add timer conflict handling and update translations
chamikaJ Jul 30, 2025
81e1872
refactor(task-list): simplify drag-and-drop functionality and enhance…
chamikaJ Jul 30, 2025
b6c056d
feat(task-status-dropdown): enhance task status update and group move…
chamikaJ Jul 30, 2025
3745952
feat(task-list-v2): enhance sticky column behavior and dark mode support
chamikaJ Jul 30, 2025
2bd6c19
refactor(layouts): simplify MainLayout and enhance styling
chamikaJ Jul 30, 2025
7635676
feat(trial-user-limits): implement trial member limit checks in proje…
chamikaJ Jul 31, 2025
b1bdf0a
feat(hubspot): add dark mode support and light color scheme for chat …
chamikaJ Jul 31, 2025
14c89de
chore(tests): remove obsolete SQL test scripts for sort order validation
chamikaJ Jul 31, 2025
7c42087
feat(update-notification): implement update notification system for n…
chamikaJ Jul 31, 2025
d1bd36e
refactor(AdminCenterLayout): simplify layout structure and improve st…
chamikaJ Aug 4, 2025
884cb9c
refactor(SettingsLayout): streamline layout and improve styling
chamikaJ Aug 4, 2025
136dac1
feat(labels): implement label update functionality and enhance UI
chamikaJ Aug 4, 2025
0e21eac
feat(auth): implement mobile Google authentication endpoint
chamikaJ Aug 4, 2025
8188b5c
feat(auth): enhance Google authentication validation
chamikaJ Aug 4, 2025
6e37208
fix(password-validator): adjust password length validation to include…
chamikaJ Aug 4, 2025
210a9a7
fix(labels-controller): update color validation to use WorklenzColorS…
chamikaJ Aug 4, 2025
01ce34f
feat(auth): enhance token audience validation for Google authentication
chamikaJ Aug 4, 2025
f84d834
feat(auth): add logging for token audience validation in Google authe…
chamikaJ Aug 4, 2025
945c52b
Merge branch 'chore/added-google-login-from-mobile-app' of https://gi…
shancds Aug 5, 2025
81d5c85
feat(task-comments): enhance comment response with user avatar and at…
shancds Aug 5, 2025
f87fba9
refactor(task-comments): update response structure for comment data
shancds Aug 5, 2025
84f96b7
Merge pull request #309 from shancds/upstreame-release-v2.1.4
chamikaJ Aug 5, 2025
7bb020d
feat(auth): implement mobile Google authentication using Passport str…
chamikaJ Aug 5, 2025
8e5d55c
feat(auth): add detailed logging for authentication processes
chamikaJ Aug 6, 2025
5b00d83
feat(auth): enhance session handling and response logging in authenti…
chamikaJ Aug 6, 2025
11a31e5
feat(auth): improve session regeneration and response handling in log…
chamikaJ Aug 6, 2025
3cb44e8
fix(auth): correct type assertion for session passport property
chamikaJ Aug 6, 2025
57c7135
feat(auth): enhance session management and debugging capabilities
chamikaJ Aug 6, 2025
3ebf262
feat(auth): enhance session handling for mobile compatibility
chamikaJ Aug 6, 2025
cc68a5e
feat(auth): improve session cookie handling and logging in middleware
chamikaJ Aug 6, 2025
0959f3f
feat(auth): enhance session middleware logging and error handling
chamikaJ Aug 6, 2025
7ce4ba1
feat(auth): add cookie-signature dependency and enhance session cooki…
chamikaJ Aug 6, 2025
66edec2
feat(auth): enhance session ID generation and improve cookie handling
chamikaJ Aug 6, 2025
a1aaf9b
refactor(auth): remove debug logging from authentication methods
chamikaJ Aug 6, 2025
097c281
feat(auth): enhance session middleware logging and error handling
chamikaJ Aug 6, 2025
abc923a
refactor(auth): simplify session middleware and remove debug endpoint
chamikaJ Aug 6, 2025
2da186e
fix(hubspot): ensure production check is correctly applied for HubSpo…
chamikaJ Aug 7, 2025
66a28dd
feat(license-management): implement license expiration alerts and modal
chamikaJ Aug 7, 2025
b8aa29b
feat(task-comments): enhance reactions structure in comment response.
shancds Aug 7, 2025
fc5bc3c
Merge pull request #310 from shancds/upstreame-release-v2.1.4
chamikaJ Aug 7, 2025
7a2318c
feat(support): implement support contact functionality and enhance us…
chamikaJ Aug 7, 2025
17e5cc3
feat(navbar): add mobile menu and language selector components
chamikaJ Aug 11, 2025
8656286
Merge pull request #311 from Worklenz/chore/added-google-login-from-m…
chamikaJ Aug 11, 2025
c6cb30b
refactor(license-management): optimize user data retrieval and notifi…
chamikaJ Aug 11, 2025
c894a03
Merge branch 'release-v2.1.4' of https://github.com/Worklenz/worklenz…
chamikaJ Aug 11, 2025
6161b8b
feat(account-deletion): implement account deletion request and loggin…
chamikaJ Aug 11, 2025
83c9628
refactor(navbar-imports): update navbar import paths for consistency
chamikaJ Aug 11, 2025
10d5d0f
refactor(navbar-imports): standardize navbar import paths in layout f…
chamikaJ Aug 11, 2025
f18dc04
refactor(navbar-imports): correct navbar import paths in layout files
chamikaJ Aug 11, 2025
05e908d
Merge pull request #312 from Worklenz/release-v2.1.4
chamikaJ Aug 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions improved_deserialize_user.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
CREATE OR REPLACE FUNCTION deserialize_user(_id uuid) RETURNS json
LANGUAGE plpgsql
AS
$$
DECLARE
_result JSON;
BEGIN
-- Optimized version using CTEs for better performance and maintainability
WITH user_team_data AS (
SELECT
u.id,
u.name,
u.email,
u.timezone_id AS timezone,
u.avatar_url,
u.user_no,
u.socket_id,
u.created_at AS joined_date,
u.updated_at AS last_updated,
u.setup_completed AS my_setup_completed,
(is_null_or_empty(u.google_id) IS FALSE) AS is_google,
COALESCE(u.active_team, (SELECT id FROM teams WHERE user_id = u.id LIMIT 1)) AS team_id,
u.active_team
FROM users u
WHERE u.id = _id
),
team_org_data AS (
SELECT
utd.*,
t.name AS team_name,
t.user_id AS owner_id,
o.subscription_status,
o.license_type_id,
o.trial_expire_date
FROM user_team_data utd
INNER JOIN teams t ON t.id = utd.team_id
LEFT JOIN organizations o ON o.user_id = t.user_id
),
notification_data AS (
SELECT
tod.*,
COALESCE(ns.email_notifications_enabled, TRUE) AS email_notifications_enabled
FROM team_org_data tod
LEFT JOIN notification_settings ns ON (ns.user_id = tod.id AND ns.team_id = tod.team_id)
),
alerts_data AS (
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(alert_rec))), '[]'::JSON) AS alerts
FROM (SELECT description, type FROM worklenz_alerts WHERE active IS TRUE) alert_rec
),
complete_user_data AS (
SELECT
nd.*,
tz.name AS timezone_name,
slt.key AS subscription_type,
tm.id AS team_member_id,
ad.alerts,
CASE
WHEN nd.subscription_status = 'trialing' THEN nd.trial_expire_date::DATE
WHEN EXISTS(SELECT 1 FROM licensing_custom_subs WHERE user_id = nd.owner_id)
THEN (SELECT end_date FROM licensing_custom_subs WHERE user_id = nd.owner_id LIMIT 1)::DATE
WHEN EXISTS(SELECT 1 FROM licensing_user_subscriptions WHERE user_id = nd.owner_id AND active IS TRUE)
THEN (SELECT (next_bill_date)::DATE - INTERVAL '1 day'
FROM licensing_user_subscriptions
WHERE user_id = nd.owner_id AND active IS TRUE
LIMIT 1)::DATE
ELSE NULL
END AS valid_till_date,
CASE
WHEN is_owner(nd.id, nd.active_team) THEN nd.my_setup_completed
ELSE TRUE
END AS setup_completed,
is_owner(nd.id, nd.active_team) AS owner,
is_admin(nd.id, nd.active_team) AS is_admin
FROM notification_data nd
CROSS JOIN alerts_data ad
LEFT JOIN timezones tz ON tz.id = nd.timezone
LEFT JOIN sys_license_types slt ON slt.id = nd.license_type_id
LEFT JOIN team_members tm ON (tm.user_id = nd.id AND tm.team_id = nd.team_id AND tm.active IS TRUE)
)
SELECT ROW_TO_JSON(complete_user_data.*) INTO _result FROM complete_user_data;

-- Ensure notification settings exist using INSERT...ON CONFLICT for better concurrency
INSERT INTO notification_settings (user_id, team_id, email_notifications_enabled, popup_notifications_enabled, show_unread_items_count)
SELECT _id,
COALESCE((SELECT active_team FROM users WHERE id = _id),
(SELECT id FROM teams WHERE user_id = _id LIMIT 1)),
TRUE, TRUE, TRUE
ON CONFLICT (user_id, team_id) DO NOTHING;

RETURN _result;
END
$$;
41 changes: 0 additions & 41 deletions test_sort_fix.sql

This file was deleted.

30 changes: 0 additions & 30 deletions test_sort_orders.sql

This file was deleted.

3 changes: 3 additions & 0 deletions worklenz-backend/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ HOSTNAME=localhost:5000
SLACK_WEBHOOK=your_slack_webhook_url
USE_PG_NATIVE=false

# Teams Support Webhook
TEAMS_SUPPORT_WEBHOOK=your_teams_webhook_url

# JWT SECRET
JWT_SECRET=your_jwt_secret

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
-- Migration: Add survey tables for account setup questionnaire
-- Date: 2025-07-24
-- Description: Creates tables to store survey questions and user responses for account setup flow

BEGIN;

-- Create surveys table to define different types of surveys
CREATE TABLE IF NOT EXISTS surveys (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
description TEXT,
survey_type VARCHAR(50) DEFAULT 'account_setup' NOT NULL, -- 'account_setup', 'onboarding', 'feedback'
is_active BOOLEAN DEFAULT TRUE NOT NULL,
created_at TIMESTAMP DEFAULT now() NOT NULL,
updated_at TIMESTAMP DEFAULT now() NOT NULL
);

-- Create survey_questions table to store individual questions
CREATE TABLE IF NOT EXISTS survey_questions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
survey_id UUID REFERENCES surveys(id) ON DELETE CASCADE NOT NULL,
question_key VARCHAR(100) NOT NULL, -- Used for localization keys
question_type VARCHAR(50) NOT NULL, -- 'single_choice', 'multiple_choice', 'text'
is_required BOOLEAN DEFAULT FALSE NOT NULL,
sort_order INTEGER DEFAULT 0 NOT NULL,
options JSONB, -- For choice questions, store options as JSON array
created_at TIMESTAMP DEFAULT now() NOT NULL,
updated_at TIMESTAMP DEFAULT now() NOT NULL
);

-- Create survey_responses table to track user responses to surveys
CREATE TABLE IF NOT EXISTS survey_responses (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
survey_id UUID REFERENCES surveys(id) ON DELETE CASCADE NOT NULL,
user_id UUID REFERENCES users(id) ON DELETE CASCADE NOT NULL,
is_completed BOOLEAN DEFAULT FALSE NOT NULL,
started_at TIMESTAMP DEFAULT now() NOT NULL,
completed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT now() NOT NULL,
updated_at TIMESTAMP DEFAULT now() NOT NULL
);

-- Create survey_answers table to store individual question answers
CREATE TABLE IF NOT EXISTS survey_answers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
response_id UUID REFERENCES survey_responses(id) ON DELETE CASCADE NOT NULL,
question_id UUID REFERENCES survey_questions(id) ON DELETE CASCADE NOT NULL,
answer_text TEXT,
answer_json JSONB, -- For multiple choice answers stored as array
created_at TIMESTAMP DEFAULT now() NOT NULL,
updated_at TIMESTAMP DEFAULT now() NOT NULL
);

-- Add performance indexes
CREATE INDEX IF NOT EXISTS idx_surveys_type_active ON surveys(survey_type, is_active);
CREATE INDEX IF NOT EXISTS idx_survey_questions_survey_order ON survey_questions(survey_id, sort_order);
CREATE INDEX IF NOT EXISTS idx_survey_responses_user_survey ON survey_responses(user_id, survey_id);
CREATE INDEX IF NOT EXISTS idx_survey_responses_completed ON survey_responses(survey_id, is_completed);
CREATE INDEX IF NOT EXISTS idx_survey_answers_response ON survey_answers(response_id);

-- Add constraints
ALTER TABLE survey_questions ADD CONSTRAINT survey_questions_sort_order_check CHECK (sort_order >= 0);
ALTER TABLE survey_questions ADD CONSTRAINT survey_questions_type_check CHECK (question_type IN ('single_choice', 'multiple_choice', 'text'));

-- Add unique constraint to prevent duplicate responses per user per survey
ALTER TABLE survey_responses ADD CONSTRAINT unique_user_survey_response UNIQUE (user_id, survey_id);

-- Add unique constraint to prevent duplicate answers per question per response
ALTER TABLE survey_answers ADD CONSTRAINT unique_response_question_answer UNIQUE (response_id, question_id);

-- Insert the default account setup survey
INSERT INTO surveys (name, description, survey_type, is_active) VALUES
('Account Setup Survey', 'Initial questionnaire during account setup to understand user needs', 'account_setup', true)
ON CONFLICT DO NOTHING;

-- Get the survey ID for inserting questions
DO $$
DECLARE
survey_uuid UUID;
BEGIN
SELECT id INTO survey_uuid FROM surveys WHERE survey_type = 'account_setup' AND name = 'Account Setup Survey' LIMIT 1;

-- Insert survey questions
INSERT INTO survey_questions (survey_id, question_key, question_type, is_required, sort_order, options) VALUES
(survey_uuid, 'organization_type', 'single_choice', true, 1, '["freelancer", "startup", "small_medium_business", "agency", "enterprise", "other"]'),
(survey_uuid, 'user_role', 'single_choice', true, 2, '["founder_ceo", "project_manager", "software_developer", "designer", "operations", "other"]'),
(survey_uuid, 'main_use_cases', 'multiple_choice', true, 3, '["task_management", "team_collaboration", "resource_planning", "client_communication", "time_tracking", "other"]'),
(survey_uuid, 'previous_tools', 'text', false, 4, null),
(survey_uuid, 'how_heard_about', 'single_choice', false, 5, '["google_search", "twitter", "linkedin", "friend_colleague", "blog_article", "other"]')
ON CONFLICT DO NOTHING;
END $$;

COMMIT;
29 changes: 29 additions & 0 deletions worklenz-backend/database/migrations/user_deletion_logs.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-- Create table for tracking user deletion requests
CREATE TABLE IF NOT EXISTS user_deletion_logs (
id UUID DEFAULT uuid_generate_v4() NOT NULL,
user_id UUID NOT NULL,
email TEXT NOT NULL,
name TEXT NOT NULL,
requested_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
scheduled_deletion_date TIMESTAMP WITH TIME ZONE NOT NULL,
deleted_at TIMESTAMP WITH TIME ZONE,
deletion_completed BOOLEAN DEFAULT FALSE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL
);

ALTER TABLE user_deletion_logs
ADD CONSTRAINT user_deletion_logs_pk
PRIMARY KEY (id);

ALTER TABLE user_deletion_logs
ADD CONSTRAINT user_deletion_logs_user_id_fk
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;

-- Create index for faster queries
CREATE INDEX IF NOT EXISTS idx_user_deletion_logs_user_id ON user_deletion_logs(user_id);
CREATE INDEX IF NOT EXISTS idx_user_deletion_logs_scheduled_deletion ON user_deletion_logs(scheduled_deletion_date) WHERE NOT deletion_completed;

-- Add comment for documentation
COMMENT ON TABLE user_deletion_logs IS 'Tracks user account deletion requests and their scheduled deletion dates';
COMMENT ON COLUMN user_deletion_logs.scheduled_deletion_date IS 'Date when the user data should be permanently deleted (30 days after request)';
COMMENT ON COLUMN user_deletion_logs.deletion_completed IS 'Flag to indicate if the deletion process has been completed';
57 changes: 57 additions & 0 deletions worklenz-backend/database/sql/1_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2297,3 +2297,60 @@ ALTER TABLE organization_working_days
ALTER TABLE organization_working_days
ADD CONSTRAINT org_organization_id_fk
FOREIGN KEY (organization_id) REFERENCES organizations;

-- Survey tables for account setup questionnaire
CREATE TABLE IF NOT EXISTS surveys (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
description TEXT,
survey_type VARCHAR(50) DEFAULT 'account_setup' NOT NULL,
is_active BOOLEAN DEFAULT TRUE NOT NULL,
created_at TIMESTAMP DEFAULT now() NOT NULL,
updated_at TIMESTAMP DEFAULT now() NOT NULL
);

CREATE TABLE IF NOT EXISTS survey_questions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
survey_id UUID REFERENCES surveys(id) ON DELETE CASCADE NOT NULL,
question_key VARCHAR(100) NOT NULL,
question_type VARCHAR(50) NOT NULL,
is_required BOOLEAN DEFAULT FALSE NOT NULL,
sort_order INTEGER DEFAULT 0 NOT NULL,
options JSONB,
created_at TIMESTAMP DEFAULT now() NOT NULL,
updated_at TIMESTAMP DEFAULT now() NOT NULL
);

CREATE TABLE IF NOT EXISTS survey_responses (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
survey_id UUID REFERENCES surveys(id) ON DELETE CASCADE NOT NULL,
user_id UUID REFERENCES users(id) ON DELETE CASCADE NOT NULL,
is_completed BOOLEAN DEFAULT FALSE NOT NULL,
started_at TIMESTAMP DEFAULT now() NOT NULL,
completed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT now() NOT NULL,
updated_at TIMESTAMP DEFAULT now() NOT NULL
);

CREATE TABLE IF NOT EXISTS survey_answers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
response_id UUID REFERENCES survey_responses(id) ON DELETE CASCADE NOT NULL,
question_id UUID REFERENCES survey_questions(id) ON DELETE CASCADE NOT NULL,
answer_text TEXT,
answer_json JSONB,
created_at TIMESTAMP DEFAULT now() NOT NULL,
updated_at TIMESTAMP DEFAULT now() NOT NULL
);

-- Survey table indexes
CREATE INDEX IF NOT EXISTS idx_surveys_type_active ON surveys(survey_type, is_active);
CREATE INDEX IF NOT EXISTS idx_survey_questions_survey_order ON survey_questions(survey_id, sort_order);
CREATE INDEX IF NOT EXISTS idx_survey_responses_user_survey ON survey_responses(user_id, survey_id);
CREATE INDEX IF NOT EXISTS idx_survey_responses_completed ON survey_responses(survey_id, is_completed);
CREATE INDEX IF NOT EXISTS idx_survey_answers_response ON survey_answers(response_id);

-- Survey table constraints
ALTER TABLE survey_questions ADD CONSTRAINT survey_questions_sort_order_check CHECK (sort_order >= 0);
ALTER TABLE survey_questions ADD CONSTRAINT survey_questions_type_check CHECK (question_type IN ('single_choice', 'multiple_choice', 'text'));
ALTER TABLE survey_responses ADD CONSTRAINT unique_user_survey_response UNIQUE (user_id, survey_id);
ALTER TABLE survey_answers ADD CONSTRAINT unique_response_question_answer UNIQUE (response_id, question_id);
22 changes: 22 additions & 0 deletions worklenz-backend/database/sql/2_dml.sql
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,25 @@ DROP FUNCTION sys_insert_license_types();
INSERT INTO timezones (name, abbrev, utc_offset)
SELECT name, abbrev, utc_offset
FROM pg_timezone_names;

-- Insert default account setup survey
INSERT INTO surveys (name, description, survey_type, is_active) VALUES
('Account Setup Survey', 'Initial questionnaire during account setup to understand user needs', 'account_setup', true)
ON CONFLICT DO NOTHING;

-- Insert survey questions for account setup survey
DO $$
DECLARE
survey_uuid UUID;
BEGIN
SELECT id INTO survey_uuid FROM surveys WHERE survey_type = 'account_setup' AND name = 'Account Setup Survey' LIMIT 1;

-- Insert survey questions
INSERT INTO survey_questions (survey_id, question_key, question_type, is_required, sort_order, options) VALUES
(survey_uuid, 'organization_type', 'single_choice', true, 1, '["freelancer", "startup", "small_medium_business", "agency", "enterprise", "other"]'),
(survey_uuid, 'user_role', 'single_choice', true, 2, '["founder_ceo", "project_manager", "software_developer", "designer", "operations", "other"]'),
(survey_uuid, 'main_use_cases', 'multiple_choice', true, 3, '["task_management", "team_collaboration", "resource_planning", "client_communication", "time_tracking", "other"]'),
(survey_uuid, 'previous_tools', 'text', false, 4, null),
(survey_uuid, 'how_heard_about', 'single_choice', false, 5, '["google_search", "twitter", "linkedin", "friend_colleague", "blog_article", "other"]')
ON CONFLICT DO NOTHING;
END $$;
Loading