From 0f181734c4f729a40aff724fa061b3ef5a696dce Mon Sep 17 00:00:00 2001 From: Joshitha Sai Uppalapati Date: Thu, 4 Dec 2025 22:04:18 -0500 Subject: [PATCH 01/19] Updated volunteer_details and user_skills DDL; removed deprecated tables --- ddl/Tables/ddl_user_skills.sql | 14 +------ ddl/Tables/ddl_volunteer_details.sql | 59 ++++++++-------------------- 2 files changed, 19 insertions(+), 54 deletions(-) diff --git a/ddl/Tables/ddl_user_skills.sql b/ddl/Tables/ddl_user_skills.sql index 2dc1bce..9aaaf92 100644 --- a/ddl/Tables/ddl_user_skills.sql +++ b/ddl/Tables/ddl_user_skills.sql @@ -1,14 +1,4 @@ -CREATE TYPE skill_levels AS ENUM('BEGINNER', 'INTERMEDIATE', 'ADVANCED', 'EXPERT'); - --- Table: user_skills CREATE TABLE IF NOT EXISTS virginia_dev_saayam_rdbms.user_skills ( - user_skills_id SERIAL PRIMARY KEY, - user_id VARCHAR(255) NOT NULL, - skill_id INT NOT NULL, - skill_level skill_levels, - last_used_date TIMESTAMP, - created_date TIMESTAMP, - last_update_date TIMESTAMP, - FOREIGN KEY (skill_id) REFERENCES virginia_dev_saayam_rdbms.skill_list (skill_list_id), - FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users (user_id) + user_id uuid PRIMARY KEY, + skills jsonb ); \ No newline at end of file diff --git a/ddl/Tables/ddl_volunteer_details.sql b/ddl/Tables/ddl_volunteer_details.sql index b533b59..91e0683 100644 --- a/ddl/Tables/ddl_volunteer_details.sql +++ b/ddl/Tables/ddl_volunteer_details.sql @@ -1,43 +1,18 @@ --- Table: volunteer_details (Volunteer-specific details) -DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; CREATE TABLE IF NOT EXISTS virginia_dev_saayam_rdbms.volunteer_details ( - user_id VARCHAR(255) PRIMARY KEY, - terms_and_conditions BOOL NULL, - terms_and_conditions_update_date TIMESTAMP NULL, - govt_id_path VARCHAR(255) NULL, -- stored in S3, this attribute stores the S3 link - govt_id_update_date TIMESTAMP NULL, - skills JSONB NULL, -- to store unstructured data - notification BOOL NULL, - iscomplete BOOL NULL, - completed_date TIMESTAMP NULL, - location geography(Point,4326), - CONSTRAINT volunteer_details_user_fk - FOREIGN KEY (user_id) - REFERENCES virginia_dev_saayam_rdbms.users (user_id) - ON DELETE CASCADE -); - --- --IF you have already table exists and trying to change the column name and type from Pii varchar(255) to skills jsonb --- -- Change the column type from varchar to json --- ALTER TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details ALTER COLUMN pii TYPE jsonb USING pii::jsonb; - --- -- Rename the column from pii to skills --- ALTER TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details RENAME COLUMN pii TO skills; - --- used to store unstructured data - --- To ensure each volunteer is unique by user_id as we don’t plan to allow multiple volunteer rows per use - -DO $$ -BEGIN - IF NOT EXISTS ( - SELECT 1 FROM pg_constraint - WHERE conname = 'volunteer_details_user_uk' - AND conrelid = 'virginia_dev_saayam_rdbms.volunteer_details'::regclass -) THEN - ALTER TABLE virginia_dev_saayam_rdbms.volunteer_details - ADD CONSTRAINT volunteer_details_user_uk UNIQUE (user_id); -END IF; -END; -$$; - + user_id uuid PRIMARY KEY, + terms_and_conditions boolean, + terms_and_conditions_update_date timestamp without time zone, + govt_id_path text, + govt_id_update_date timestamp without time zone, + skills jsonb, + notification boolean, + iscomplete boolean, + completed_date timestamp without time zone, + location text, + full_name text, + email text, + phone text, + availability_days text[], + availability_time text, + gov_id_content_type text +); \ No newline at end of file From c1448c08259d7984d05b1b27f73d523f06e7de8e Mon Sep 17 00:00:00 2001 From: Joshitha Sai Uppalapati Date: Sun, 14 Dec 2025 19:34:05 -0500 Subject: [PATCH 02/19] Normalize user_skills and update volunteer_details schema --- ddl/Tables/ddl_user_skills.sql | 14 ++++++++++---- ddl/Tables/ddl_volunteer_details.sql | 24 +++++++++++++++++------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/ddl/Tables/ddl_user_skills.sql b/ddl/Tables/ddl_user_skills.sql index 9aaaf92..7398c49 100644 --- a/ddl/Tables/ddl_user_skills.sql +++ b/ddl/Tables/ddl_user_skills.sql @@ -1,4 +1,10 @@ -CREATE TABLE IF NOT EXISTS virginia_dev_saayam_rdbms.user_skills ( - user_id uuid PRIMARY KEY, - skills jsonb -); \ No newline at end of file +DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.user_skills CASCADE; + +CREATE TABLE virginia_dev_saayam_rdbms.user_skills ( + user_id VARCHAR(255) NOT NULL, + cat_id INT NOT NULL, + created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), + + CONSTRAINT user_skills_pkey PRIMARY KEY (user_id, cat_id) +); + diff --git a/ddl/Tables/ddl_volunteer_details.sql b/ddl/Tables/ddl_volunteer_details.sql index 91e0683..92b6a6e 100644 --- a/ddl/Tables/ddl_volunteer_details.sql +++ b/ddl/Tables/ddl_volunteer_details.sql @@ -1,18 +1,28 @@ -CREATE TABLE IF NOT EXISTS virginia_dev_saayam_rdbms.volunteer_details ( +DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; + +CREATE TABLE virginia_dev_saayam_rdbms.volunteer_details ( user_id uuid PRIMARY KEY, + terms_and_conditions boolean, terms_and_conditions_update_date timestamp without time zone, + govt_id_path text, govt_id_update_date timestamp without time zone, - skills jsonb, + gov_id_content_type text, + notification boolean, iscomplete boolean, completed_date timestamp without time zone, - location text, - full_name text, - email text, - phone text, + availability_days text[], availability_time text, - gov_id_content_type text + + location text, + + created_at timestamp without time zone DEFAULT now(), + + CONSTRAINT volunteer_details_user_fk + FOREIGN KEY (user_id) + REFERENCES virginia_dev_saayam_rdbms.users(user_id) + ON DELETE CASCADE ); \ No newline at end of file From fa087a9b2ee9e2a0ffd86e75b1c5f0acdb69f251 Mon Sep 17 00:00:00 2001 From: Joshitha Uppalpati Date: Mon, 15 Dec 2025 17:00:37 -0500 Subject: [PATCH 03/19] Change user_id type from uuid to VARCHAR(255) --- ddl/Tables/ddl_volunteer_details.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ddl/Tables/ddl_volunteer_details.sql b/ddl/Tables/ddl_volunteer_details.sql index 92b6a6e..b4dfa64 100644 --- a/ddl/Tables/ddl_volunteer_details.sql +++ b/ddl/Tables/ddl_volunteer_details.sql @@ -1,7 +1,7 @@ DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; CREATE TABLE virginia_dev_saayam_rdbms.volunteer_details ( - user_id uuid PRIMARY KEY, + user_id VARCHAR(255) PRIMARY KEY, terms_and_conditions boolean, terms_and_conditions_update_date timestamp without time zone, @@ -25,4 +25,4 @@ CREATE TABLE virginia_dev_saayam_rdbms.volunteer_details ( FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users(user_id) ON DELETE CASCADE -); \ No newline at end of file +); From 2b76a7625d9a284330803d9ae30a0e6a0190d864 Mon Sep 17 00:00:00 2001 From: Joshitha Sai Uppalapati Date: Wed, 17 Dec 2025 13:13:35 -0500 Subject: [PATCH 04/19] Add volunteer_applications DDL with acceptance trigger --- ddl/Tables/ddl_volunteer_applications.sql | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ddl/Tables/ddl_volunteer_applications.sql diff --git a/ddl/Tables/ddl_volunteer_applications.sql b/ddl/Tables/ddl_volunteer_applications.sql new file mode 100644 index 0000000..47fb07b --- /dev/null +++ b/ddl/Tables/ddl_volunteer_applications.sql @@ -0,0 +1,66 @@ +DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_applications CASCADE; + +CREATE TABLE virginia_dev_saayam_rdbms.volunteer_applications ( + user_id VARCHAR(255) NOT NULL, + application_status VARCHAR(50) NOT NULL, + selected_skill_codes INT[], + govt_id_storage_path VARCHAR(255), + created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), + updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), + + CONSTRAINT volunteer_applications_pkey PRIMARY KEY (user_id), + CONSTRAINT volunteer_applications_user_fk + FOREIGN KEY (user_id) + REFERENCES virginia_dev_saayam_rdbms.users(user_id) + ON DELETE CASCADE +); + +CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance() +RETURNS TRIGGER +LANGUAGE plpgsql +AS $$ +BEGIN + IF NEW.application_status = 'accepted' + AND OLD.application_status IS DISTINCT FROM NEW.application_status + THEN + INSERT INTO virginia_dev_saayam_rdbms.volunteer_details ( + user_id, + govt_id_path, + govt_id_path2, + iscomplete, + completed_date + ) + VALUES ( + NEW.user_id, + NEW.govt_id_storage_path, + NULL, + TRUE, + now() + ); + + IF NEW.selected_skill_codes IS NOT NULL THEN + INSERT INTO virginia_dev_saayam_rdbms.user_skills (user_id, cat_id) + SELECT + NEW.user_id, + unnest(NEW.selected_skill_codes); + END IF; + + DELETE FROM virginia_dev_saayam_rdbms.volunteer_applications + WHERE user_id = NEW.user_id; + END IF; + + RETURN NULL; +END; +$$; + +DROP TRIGGER IF EXISTS trg_handle_application_acceptance +ON virginia_dev_saayam_rdbms.volunteer_applications; + +CREATE TRIGGER trg_handle_application_acceptance +AFTER UPDATE OF application_status +ON virginia_dev_saayam_rdbms.volunteer_applications +FOR EACH ROW +EXECUTE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance(); + +CREATE INDEX IF NOT EXISTS idx_volunteer_applications_status +ON virginia_dev_saayam_rdbms.volunteer_applications (application_status); From f97b9d38f40774058ed51f99a82622d235938117 Mon Sep 17 00:00:00 2001 From: Joshitha Sai Uppalapati Date: Wed, 17 Dec 2025 17:04:02 -0500 Subject: [PATCH 05/19] Update volunteer tables: VARCHAR user_id, govt_id_path2, cleanup fields --- ddl/Tables/ddl_user_skills.sql | 9 +++++++++ ddl/Tables/ddl_volunteer_details.sql | 13 +++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ddl/Tables/ddl_user_skills.sql b/ddl/Tables/ddl_user_skills.sql index 7398c49..3ddde6b 100644 --- a/ddl/Tables/ddl_user_skills.sql +++ b/ddl/Tables/ddl_user_skills.sql @@ -6,5 +6,14 @@ CREATE TABLE virginia_dev_saayam_rdbms.user_skills ( created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), CONSTRAINT user_skills_pkey PRIMARY KEY (user_id, cat_id) + +-- CONSTRAINT user_skills_user_fk +-- FOREIGN KEY (user_id) +-- REFERENCES virginia_dev_saayam_rdbms.users(user_id) +-- ON DELETE CASCADE + +-- CONSTRAINT user_skills_cat_fk +-- FOREIGN KEY (cat_id) +-- REFERENCES virginia_dev_saayam_rdbms.help_categories(cat_id) ); diff --git a/ddl/Tables/ddl_volunteer_details.sql b/ddl/Tables/ddl_volunteer_details.sql index b4dfa64..136bdc1 100644 --- a/ddl/Tables/ddl_volunteer_details.sql +++ b/ddl/Tables/ddl_volunteer_details.sql @@ -7,8 +7,9 @@ CREATE TABLE virginia_dev_saayam_rdbms.volunteer_details ( terms_and_conditions_update_date timestamp without time zone, govt_id_path text, + govt_id_path2 text, govt_id_update_date timestamp without time zone, - gov_id_content_type text, + notification boolean, iscomplete boolean, @@ -19,10 +20,10 @@ CREATE TABLE virginia_dev_saayam_rdbms.volunteer_details ( location text, - created_at timestamp without time zone DEFAULT now(), + created_at timestamp without time zone DEFAULT now() - CONSTRAINT volunteer_details_user_fk - FOREIGN KEY (user_id) - REFERENCES virginia_dev_saayam_rdbms.users(user_id) - ON DELETE CASCADE +-- CONSTRAINT volunteer_details_user_fk +-- FOREIGN KEY (user_id) +-- REFERENCES virginia_dev_saayam_rdbms.users(user_id) +-- ON DELETE CASCADE ); From 82872238b40da8b3d6887a4a8baa1c599f082156 Mon Sep 17 00:00:00 2001 From: Joshitha Sai Uppalapati Date: Wed, 17 Dec 2025 17:18:09 -0500 Subject: [PATCH 06/19] Fix acceptance trigger to avoid duplicate volunteer_details insert --- ddl/Tables/ddl_volunteer_applications.sql | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/ddl/Tables/ddl_volunteer_applications.sql b/ddl/Tables/ddl_volunteer_applications.sql index 47fb07b..9816014 100644 --- a/ddl/Tables/ddl_volunteer_applications.sql +++ b/ddl/Tables/ddl_volunteer_applications.sql @@ -15,14 +15,17 @@ CREATE TABLE virginia_dev_saayam_rdbms.volunteer_applications ( ON DELETE CASCADE ); +-- Trigger function: handle application acceptance CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN + -- Only act when status changes to 'accepted' IF NEW.application_status = 'accepted' AND OLD.application_status IS DISTINCT FROM NEW.application_status THEN + -- Upsert into volunteer_details INSERT INTO virginia_dev_saayam_rdbms.volunteer_details ( user_id, govt_id_path, @@ -36,15 +39,23 @@ BEGIN NULL, TRUE, now() - ); + ) + ON CONFLICT (user_id) + DO UPDATE SET + govt_id_path = EXCLUDED.govt_id_path, + iscomplete = TRUE, + completed_date = now(); + -- Insert user skills IF NEW.selected_skill_codes IS NOT NULL THEN INSERT INTO virginia_dev_saayam_rdbms.user_skills (user_id, cat_id) SELECT NEW.user_id, - unnest(NEW.selected_skill_codes); + unnest(NEW.selected_skill_codes) + ON CONFLICT DO NOTHING; END IF; + -- Remove the application after acceptance DELETE FROM virginia_dev_saayam_rdbms.volunteer_applications WHERE user_id = NEW.user_id; END IF; @@ -53,6 +64,7 @@ BEGIN END; $$; +-- Trigger DROP TRIGGER IF EXISTS trg_handle_application_acceptance ON virginia_dev_saayam_rdbms.volunteer_applications; @@ -62,5 +74,3 @@ ON virginia_dev_saayam_rdbms.volunteer_applications FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance(); -CREATE INDEX IF NOT EXISTS idx_volunteer_applications_status -ON virginia_dev_saayam_rdbms.volunteer_applications (application_status); From 1097086043990f33da42332b812772e66ee960fa Mon Sep 17 00:00:00 2001 From: Joshitha Sai Uppalapati Date: Wed, 17 Dec 2025 19:05:52 -0500 Subject: [PATCH 07/19] Add test case script for volunteer onboarding trigger --- .../volunteer_onboarding_trigger_test.sql | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 script-library/tests/volunteer_onboarding_trigger_test.sql diff --git a/script-library/tests/volunteer_onboarding_trigger_test.sql b/script-library/tests/volunteer_onboarding_trigger_test.sql new file mode 100644 index 0000000..c2d749a --- /dev/null +++ b/script-library/tests/volunteer_onboarding_trigger_test.sql @@ -0,0 +1,63 @@ +-- Test Case: Volunteer onboarding trigger +-- Validates trigger behavior on volunteer_applications acceptance + +SET search_path TO virginia_dev_saayam_rdbms; + +-- Cleanup existing test data +DELETE FROM user_skills WHERE user_id = 'SID-TEST-PR-01'; +DELETE FROM volunteer_details WHERE user_id = 'SID-TEST-PR-01'; +DELETE FROM volunteer_applications WHERE user_id = 'SID-TEST-PR-01'; + +-- Step 1: Insert volunteer application +INSERT INTO volunteer_applications ( + user_id, + application_status, + availability, + selected_skill_codes, + govt_id_storage_path +) VALUES ( + 'SID-TEST-PR-01', + 'submitted', + '{"days":["Monday","Wednesday"],"time":["Morning","Evening"]}'::jsonb, + ARRAY[101,102], + 's3://fake-bucket/govt-id-1.png' +); + +-- Verify application insert +SELECT user_id, application_status +FROM volunteer_applications +WHERE user_id = 'SID-TEST-PR-01'; + +-- Step 2: Accept the application (trigger fires) +UPDATE volunteer_applications +SET application_status = 'accepted' +WHERE user_id = 'SID-TEST-PR-01'; + +-- Step 3: Application should be removed +SELECT * +FROM volunteer_applications +WHERE user_id = 'SID-TEST-PR-01'; + +-- Step 4: Volunteer details auto-created +SELECT + user_id, + govt_id_path, + govt_id_path2, + iscomplete, + completed_date +FROM volunteer_details +WHERE user_id = 'SID-TEST-PR-01'; + +-- Step 5: Skills expanded into user_skills +SELECT + user_id, + cat_id, + created_at +FROM user_skills +WHERE user_id = 'SID-TEST-PR-01' +ORDER BY cat_id; + +-- Step 6: Count validation +SELECT count(*) FROM volunteer_details WHERE user_id = 'SID-TEST-PR-01'; +SELECT count(*) FROM user_skills WHERE user_id = 'SID-TEST-PR-01'; + From 1399c672c5322e1386237ca0230cbe1c2ac74e35 Mon Sep 17 00:00:00 2001 From: Joshitha Uppalpati Date: Sat, 20 Dec 2025 00:32:06 -0500 Subject: [PATCH 08/19] volunteer_applications table and triggers --- ddl/Tables/ddl_volunteer_applications.sql | 107 +++++++++++++--------- 1 file changed, 66 insertions(+), 41 deletions(-) diff --git a/ddl/Tables/ddl_volunteer_applications.sql b/ddl/Tables/ddl_volunteer_applications.sql index 9816014..e4e7bc3 100644 --- a/ddl/Tables/ddl_volunteer_applications.sql +++ b/ddl/Tables/ddl_volunteer_applications.sql @@ -1,70 +1,96 @@ DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_applications CASCADE; CREATE TABLE virginia_dev_saayam_rdbms.volunteer_applications ( - user_id VARCHAR(255) NOT NULL, - application_status VARCHAR(50) NOT NULL, - selected_skill_codes INT[], - govt_id_storage_path VARCHAR(255), - created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), - updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), + user_id VARCHAR(255) PRIMARY KEY, + + terms_and_conditions BOOLEAN, + terms_and_conditions_accepted_at TIMESTAMP WITHOUT TIME ZONE, + + skill_codes JSON, + availability JSONB, - CONSTRAINT volunteer_applications_pkey PRIMARY KEY (user_id), - CONSTRAINT volunteer_applications_user_fk - FOREIGN KEY (user_id) - REFERENCES virginia_dev_saayam_rdbms.users(user_id) - ON DELETE CASCADE + application_status TEXT, + is_completed BOOLEAN, + current_page TEXT, + + govt_id_storage_path TEXT, + path_updated_at TIMESTAMP WITHOUT TIME ZONE, + + created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), + updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() ); --- Trigger function: handle application acceptance +CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.set_application_updated_at() +RETURNS TRIGGER +LANGUAGE plpgsql +AS $$ +BEGIN + NEW.updated_at = now(); + RETURN NEW; +END; +$$; + +DROP TRIGGER IF EXISTS trg_set_application_updated_at +ON virginia_dev_saayam_rdbms.volunteer_applications; + +CREATE TRIGGER trg_set_application_updated_at +BEFORE UPDATE +ON virginia_dev_saayam_rdbms.volunteer_applications +FOR EACH ROW +EXECUTE FUNCTION virginia_dev_saayam_rdbms.set_application_updated_at(); + CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN - -- Only act when status changes to 'accepted' - IF NEW.application_status = 'accepted' - AND OLD.application_status IS DISTINCT FROM NEW.application_status + IF OLD.application_status = 'submitted' + AND NEW.application_status = 'accepted' THEN - -- Upsert into volunteer_details INSERT INTO virginia_dev_saayam_rdbms.volunteer_details ( user_id, - govt_id_path, - govt_id_path2, - iscomplete, - completed_date + terms_and_conditions, + terms_and_conditions_update_date, + govt_id_path1, + availability_days, + availability_times, + created_at, + updated_at ) VALUES ( NEW.user_id, + NEW.terms_and_conditions, + NEW.terms_and_conditions_accepted_at, NEW.govt_id_storage_path, - NULL, - TRUE, - now() - ) - ON CONFLICT (user_id) - DO UPDATE SET - govt_id_path = EXCLUDED.govt_id_path, - iscomplete = TRUE, - completed_date = now(); + NEW.availability -> 'days', + NEW.availability -> 'time', + NEW.updated_at, + NEW.updated_at + ); - -- Insert user skills - IF NEW.selected_skill_codes IS NOT NULL THEN - INSERT INTO virginia_dev_saayam_rdbms.user_skills (user_id, cat_id) + IF NEW.skill_codes IS NOT NULL THEN + INSERT INTO virginia_dev_saayam_rdbms.user_skills ( + user_id, + cat_id, + created_at, + updated_at + ) SELECT - NEW.user_id, - unnest(NEW.selected_skill_codes) - ON CONFLICT DO NOTHING; + NEW.user_id, + value::INT, + NEW.updated_at, + NEW.updated_at + FROM json_array_elements_text(NEW.skill_codes); END IF; - - -- Remove the application after acceptance + DELETE FROM virginia_dev_saayam_rdbms.volunteer_applications WHERE user_id = NEW.user_id; END IF; - + RETURN NULL; END; $$; - --- Trigger + DROP TRIGGER IF EXISTS trg_handle_application_acceptance ON virginia_dev_saayam_rdbms.volunteer_applications; @@ -73,4 +99,3 @@ AFTER UPDATE OF application_status ON virginia_dev_saayam_rdbms.volunteer_applications FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance(); - From f1111963ee436594110ffb151e46c093d28ff188 Mon Sep 17 00:00:00 2001 From: Joshitha Uppalpati Date: Sat, 20 Dec 2025 00:33:20 -0500 Subject: [PATCH 09/19] volunteer_details table schema --- ddl/Tables/ddl_volunteer_details.sql | 30 ++++++++++------------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/ddl/Tables/ddl_volunteer_details.sql b/ddl/Tables/ddl_volunteer_details.sql index 136bdc1..aeba081 100644 --- a/ddl/Tables/ddl_volunteer_details.sql +++ b/ddl/Tables/ddl_volunteer_details.sql @@ -3,27 +3,17 @@ DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; CREATE TABLE virginia_dev_saayam_rdbms.volunteer_details ( user_id VARCHAR(255) PRIMARY KEY, - terms_and_conditions boolean, - terms_and_conditions_update_date timestamp without time zone, + terms_and_conditions BOOLEAN, + terms_and_conditions_update_date TIMESTAMP WITHOUT TIME ZONE, - govt_id_path text, - govt_id_path2 text, - govt_id_update_date timestamp without time zone, - + govt_id_path1 TEXT, + govt_id_path2 TEXT, + path1_updated_at TIMESTAMP WITHOUT TIME ZONE, + path2_updated_at TIMESTAMP WITHOUT TIME ZONE, - notification boolean, - iscomplete boolean, - completed_date timestamp without time zone, + availability_days JSON, + availability_times JSON, - availability_days text[], - availability_time text, - - location text, - - created_at timestamp without time zone DEFAULT now() - --- CONSTRAINT volunteer_details_user_fk --- FOREIGN KEY (user_id) --- REFERENCES virginia_dev_saayam_rdbms.users(user_id) --- ON DELETE CASCADE + created_at TIMESTAMP WITHOUT TIME ZONE, + updated_at TIMESTAMP WITHOUT TIME ZONE ); From 034852a27bf06331420d230e96d73d4723241414 Mon Sep 17 00:00:00 2001 From: Joshitha Uppalpati Date: Sat, 20 Dec 2025 00:33:53 -0500 Subject: [PATCH 10/19] user_skills table schema Removed foreign key constraints and added updated_at column. --- ddl/Tables/ddl_user_skills.sql | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/ddl/Tables/ddl_user_skills.sql b/ddl/Tables/ddl_user_skills.sql index 3ddde6b..cb3bc1f 100644 --- a/ddl/Tables/ddl_user_skills.sql +++ b/ddl/Tables/ddl_user_skills.sql @@ -3,17 +3,9 @@ DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.user_skills CASCADE; CREATE TABLE virginia_dev_saayam_rdbms.user_skills ( user_id VARCHAR(255) NOT NULL, cat_id INT NOT NULL, - created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), - CONSTRAINT user_skills_pkey PRIMARY KEY (user_id, cat_id) - --- CONSTRAINT user_skills_user_fk --- FOREIGN KEY (user_id) --- REFERENCES virginia_dev_saayam_rdbms.users(user_id) --- ON DELETE CASCADE + created_at TIMESTAMP WITHOUT TIME ZONE, + updated_at TIMESTAMP WITHOUT TIME ZONE, --- CONSTRAINT user_skills_cat_fk --- FOREIGN KEY (cat_id) --- REFERENCES virginia_dev_saayam_rdbms.help_categories(cat_id) + CONSTRAINT user_skills_pkey PRIMARY KEY (user_id, cat_id) ); - From 5d95302c8dcacfe0e6c273df6684d945e91e0b68 Mon Sep 17 00:00:00 2001 From: PallaviChitrada Date: Wed, 24 Dec 2025 17:36:31 -0500 Subject: [PATCH 11/19] Refactor volunteer_applications table and add triggers Added application status enum and updated volunteer_applications table structure with new fields and defaults. Created triggers for handling updates and application acceptance. --- ddl/Tables/ddl_volunteer_applications.sql | 161 +++++++++++----------- 1 file changed, 82 insertions(+), 79 deletions(-) diff --git a/ddl/Tables/ddl_volunteer_applications.sql b/ddl/Tables/ddl_volunteer_applications.sql index e4e7bc3..24573a6 100644 --- a/ddl/Tables/ddl_volunteer_applications.sql +++ b/ddl/Tables/ddl_volunteer_applications.sql @@ -1,101 +1,104 @@ -DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_applications CASCADE; +-- ENUM for application status +CREATE TYPE virginia_dev_saayam_rdbms.app_status_type AS ENUM ('STARTED', 'IN_REVIEW', 'ACCEPTED', 'REJECTED'); +-- Create the volunteer_applications table CREATE TABLE virginia_dev_saayam_rdbms.volunteer_applications ( user_id VARCHAR(255) PRIMARY KEY, - - terms_and_conditions BOOLEAN, - terms_and_conditions_accepted_at TIMESTAMP WITHOUT TIME ZONE, - + terms_and_conditions BOOLEAN DEFAULT FALSE, + terms_accepted_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + govt_id_path TEXT, + path_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), skill_codes JSON, availability JSONB, + current_page INT DEFAULT 1, -- Changed from TEXT to INT for numerical tracking + application_status virginia_dev_saayam_rdbms.app_status_type DEFAULT 'STARTED', + is_completed BOOLEAN DEFAULT FALSE, --extra precaution + created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + last_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users(user_id) +); - application_status TEXT, - is_completed BOOLEAN, - current_page TEXT, +CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.updated_at_handler() +RETURNS TRIGGER AS $$ +BEGIN + -- handle application table + IF (TG_TABLE_NAME = 'volunteer_applications') THEN + + NEW.last_updated_at = COALESCE(NEW.last_updated_at, (now() AT TIME ZONE 'UTC')); -- for any attribute + + -- Update path timestamp if path changed + IF (NEW.govt_id_path IS DISTINCT FROM OLD.govt_id_path) THEN + NEW.path_updated_at = COALESCE(NEW.path_updated_at, (now() AT TIME ZONE 'UTC')); + END IF; - govt_id_storage_path TEXT, - path_updated_at TIMESTAMP WITHOUT TIME ZONE, + -- Update terms timestamp if accepted + IF (NEW.terms_and_conditions IS TRUE AND (OLD.terms_and_conditions IS FALSE OR OLD.terms_and_conditions IS NULL)) THEN + NEW.terms_accepted_at = COALESCE(NEW.terms_accepted_at, (now() AT TIME ZONE 'UTC')); + END IF; - created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), - updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() -); + -- handle details table + ELSIF (TG_TABLE_NAME = 'volunteer_details') THEN + + NEW.last_updated_at = COALESCE(NEW.last_updated_at, (now() AT TIME ZONE 'UTC')); -- for any attribute + + -- update path1 timestamp if changed + IF (NEW.govt_id_path1 IS DISTINCT FROM OLD.govt_id_path1) THEN + NEW.path1_updated_at = COALESCE(NEW.path1_updated_at, (now() AT TIME ZONE 'UTC')); + END IF; + + -- update path2 timestamp if changed + IF (NEW.govt_id_path2 IS DISTINCT FROM OLD.govt_id_path2) THEN + NEW.path2_updated_at = COALESCE(NEW.path2_updated_at, (now() AT TIME ZONE 'UTC')); + END IF; + + -- update terms timestamp if accepted + IF (NEW.terms_and_conditions IS TRUE AND (OLD.terms_and_conditions IS FALSE OR OLD.terms_and_conditions IS NULL)) THEN + NEW.terms_accepted_at = COALESCE(NEW.terms_accepted_at, (now() AT TIME ZONE 'UTC')); + END IF; + END IF; -CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.set_application_updated_at() -RETURNS TRIGGER -LANGUAGE plpgsql -AS $$ -BEGIN - NEW.updated_at = now(); RETURN NEW; END; -$$; +$$ LANGUAGE plpgsql; -DROP TRIGGER IF EXISTS trg_set_application_updated_at -ON virginia_dev_saayam_rdbms.volunteer_applications; - -CREATE TRIGGER trg_set_application_updated_at -BEFORE UPDATE -ON virginia_dev_saayam_rdbms.volunteer_applications -FOR EACH ROW -EXECUTE FUNCTION virginia_dev_saayam_rdbms.set_application_updated_at(); - -CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance() -RETURNS TRIGGER -LANGUAGE plpgsql -AS $$ +CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.handle_volunteer_application() +RETURNS TRIGGER AS $$ BEGIN - IF OLD.application_status = 'submitted' - AND NEW.application_status = 'accepted' - THEN + IF (NEW.application_status = 'ACCEPTED' AND OLD.application_status != 'ACCEPTED') THEN + + -- Migrate to volunteer_details INSERT INTO virginia_dev_saayam_rdbms.volunteer_details ( - user_id, - terms_and_conditions, - terms_and_conditions_update_date, - govt_id_path1, - availability_days, - availability_times, - created_at, - updated_at - ) - VALUES ( - NEW.user_id, - NEW.terms_and_conditions, - NEW.terms_and_conditions_accepted_at, - NEW.govt_id_storage_path, - NEW.availability -> 'days', - NEW.availability -> 'time', - NEW.updated_at, - NEW.updated_at + user_id, terms_and_conditions, terms_accepted_at, + govt_id_path1, availability_days, availability_times, + created_at, last_updated_at + ) VALUES ( + NEW.user_id, NEW.terms_and_conditions, NEW.terms_accepted_at, + NEW.govt_id_path, (NEW.availability -> 'days')::JSONB, (NEW.availability -> 'time')::JSONB, + NEW.last_updated_at, NEW.last_updated_at ); - IF NEW.skill_codes IS NOT NULL THEN + -- Migrate to user_skills (unrolling the JSON array) + IF (NEW.skill_codes IS NOT NULL) THEN INSERT INTO virginia_dev_saayam_rdbms.user_skills ( - user_id, - cat_id, - created_at, - updated_at + user_id, cat_id, created_at, last_updated_at ) - SELECT - NEW.user_id, - value::INT, - NEW.updated_at, - NEW.updated_at - FROM json_array_elements_text(NEW.skill_codes); + SELECT + NEW.user_id, + skill_id, + NEW.last_updated_at, + NEW.last_updated_at + FROM json_array_elements_text(NEW.skill_codes) AS skill_id; END IF; - - DELETE FROM virginia_dev_saayam_rdbms.volunteer_applications - WHERE user_id = NEW.user_id; END IF; - - RETURN NULL; + + RETURN NEW; END; -$$; - -DROP TRIGGER IF EXISTS trg_handle_application_acceptance -ON virginia_dev_saayam_rdbms.volunteer_applications; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER trg_volunteer_app_updated_at + BEFORE UPDATE ON virginia_dev_saayam_rdbms.volunteer_applications + FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.updated_at_handler(); -CREATE TRIGGER trg_handle_application_acceptance -AFTER UPDATE OF application_status -ON virginia_dev_saayam_rdbms.volunteer_applications -FOR EACH ROW -EXECUTE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance(); +CREATE TRIGGER trg_handle_volunteer_application + AFTER UPDATE ON virginia_dev_saayam_rdbms.volunteer_applications + FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.handle_volunteer_application(); From 00d178c4c3eee3361cca1779c1eb73011ba2ed07 Mon Sep 17 00:00:00 2001 From: PallaviChitrada Date: Wed, 24 Dec 2025 17:36:38 -0500 Subject: [PATCH 12/19] Update volunteer_details table structure and indexes Added default values for timestamps and created indexes for availability days and times. --- ddl/Tables/ddl_volunteer_details.sql | 31 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/ddl/Tables/ddl_volunteer_details.sql b/ddl/Tables/ddl_volunteer_details.sql index aeba081..f84918a 100644 --- a/ddl/Tables/ddl_volunteer_details.sql +++ b/ddl/Tables/ddl_volunteer_details.sql @@ -1,19 +1,28 @@ -DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; +-- DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; CREATE TABLE virginia_dev_saayam_rdbms.volunteer_details ( user_id VARCHAR(255) PRIMARY KEY, - terms_and_conditions BOOLEAN, - terms_and_conditions_update_date TIMESTAMP WITHOUT TIME ZONE, - + terms_accepted_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), govt_id_path1 TEXT, govt_id_path2 TEXT, - path1_updated_at TIMESTAMP WITHOUT TIME ZONE, - path2_updated_at TIMESTAMP WITHOUT TIME ZONE, + path1_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + path2_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + availability_days JSONB, + availability_times JSONB, + created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + last_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users(user_id) +); - availability_days JSON, - availability_times JSON, +CREATE TRIGGER trg_volunteer_details_updated_at + BEFORE UPDATE ON virginia_dev_saayam_rdbms.volunteer_details + FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.updated_at_handler(); - created_at TIMESTAMP WITHOUT TIME ZONE, - updated_at TIMESTAMP WITHOUT TIME ZONE -); +-- Index for searching specific days (e.g., 'Monday') +CREATE INDEX idx_volunteer_availability_days +ON virginia_dev_saayam_rdbms.volunteer_details USING GIN (availability_days); + +-- Index for searching specific time slots +CREATE INDEX idx_volunteer_availability_times +ON virginia_dev_saayam_rdbms.volunteer_details USING GIN (availability_times); From ef4586534d7a9c405aa644c22db7de68b7c2ab9f Mon Sep 17 00:00:00 2001 From: PallaviChitrada Date: Wed, 24 Dec 2025 17:36:42 -0500 Subject: [PATCH 13/19] Modify user_skills table structure and add triggers --- ddl/Tables/ddl_user_skills.sql | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/ddl/Tables/ddl_user_skills.sql b/ddl/Tables/ddl_user_skills.sql index cb3bc1f..8690a90 100644 --- a/ddl/Tables/ddl_user_skills.sql +++ b/ddl/Tables/ddl_user_skills.sql @@ -1,11 +1,18 @@ DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.user_skills CASCADE; CREATE TABLE virginia_dev_saayam_rdbms.user_skills ( - user_id VARCHAR(255) NOT NULL, - cat_id INT NOT NULL, + user_id VARCHAR(255), + cat_id VARCHAR(50) NOT NULL, + created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + last_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + PRIMARY KEY (user_id, cat_id), + FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users(user_id), + FOREIGN KEY (cat_id) REFERENCES virginia_dev_saayam_rdbms.help_categories(cat_id) +); - created_at TIMESTAMP WITHOUT TIME ZONE, - updated_at TIMESTAMP WITHOUT TIME ZONE, +CREATE TRIGGER trg_user_skills_updated_at +BEFORE UPDATE ON virginia_dev_saayam_rdbms.user_skills +FOR EACH ROW +EXECUTE FUNCTION set_updated_at(); - CONSTRAINT user_skills_pkey PRIMARY KEY (user_id, cat_id) -); +CREATE INDEX idx_user_skills_cat_id ON virginia_dev_saayam_rdbms.user_skills (cat_id); From 02876256c361cc78efa6fd628710a847432363eb Mon Sep 17 00:00:00 2001 From: PallaviChitrada Date: Wed, 24 Dec 2025 17:41:10 -0500 Subject: [PATCH 14/19] Add SQL test cases for volunteer onboarding process This SQL script contains test cases for verifying the functionality of the volunteer onboarding process, including audit timestamps, volunteer acceptance, skill search performance, and availability search. --- script-library/tests/volunteer_onboarding.sql | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 script-library/tests/volunteer_onboarding.sql diff --git a/script-library/tests/volunteer_onboarding.sql b/script-library/tests/volunteer_onboarding.sql new file mode 100644 index 0000000..8889c43 --- /dev/null +++ b/script-library/tests/volunteer_onboarding.sql @@ -0,0 +1,60 @@ +-- WRITE YOUR OWN TEST CASES AS WE HAVE THE FOREIGN KEY IMPLEMENTED + +-- Test Audit Timestamps +-- This test verifies that the updated_at_handler trigger correctly updates timestamps when you make changes, prioritizing the database's UTC time if the API provides none. + +-- Step 1: Insert a test application +INSERT INTO virginia_dev_saayam_rdbms.volunteer_applications (user_id, application_status) +VALUES ('test_user_001', 'STARTED'); + +-- Step 2: Update a field (like current_page) and check if updated_at changes +UPDATE virginia_dev_saayam_rdbms.volunteer_applications +SET current_page = 2 +WHERE user_id = 'test_user_001'; + +-- Step 3: Update the govt_id_path specifically +-- Check if path_updated_at refreshes while others remain distinct +UPDATE virginia_dev_saayam_rdbms.volunteer_applications +SET govt_id_path = 'https://storage.com/id1.jpg' +WHERE user_id = 'test_user_001'; + +SELECT user_id, updated_at, path_updated_at FROM virginia_dev_saayam_rdbms.volunteer_applications; + +-- Test Volunteer Acceptance (Migration Trigger) +-- Step 1: Prepare the application with skills and availability +UPDATE virginia_dev_saayam_rdbms.volunteer_applications +SET application_status = 'IN_REVIEW', + skill_codes = '["SKILL_01", "SKILL_02"]', + availability = '{"days": ["Monday", "Wednesday"], "time": ["Morning"]}'::JSONB, + terms_and_conditions = TRUE +WHERE user_id = 'test_user_001'; + +-- Step 2: Trigger the migration by accepting the volunteer +UPDATE virginia_dev_saayam_rdbms.volunteer_applications +SET application_status = 'ACCEPTED' +WHERE user_id = 'test_user_001'; + +-- Step 3: Verify migration to volunteer_details +SELECT * FROM virginia_dev_saayam_rdbms.volunteer_details WHERE user_id = 'test_user_001'; + +-- Step 4: Verify migration to user_skills (should have 2 rows for the 2 skill_codes) +SELECT * FROM virginia_dev_saayam_rdbms.user_skills WHERE user_id = 'test_user_001'; + +-- Test Skill Search Performance +-- Search for all volunteers who have "SKILL_01" +-- Use EXPLAIN to confirm the index idx_user_skills_cat_id is being used +EXPLAIN ANALYZE +SELECT user_id +FROM virginia_dev_saayam_rdbms.user_skills +WHERE cat_id = 'SKILL_01'; + +-- Test Availability Search +-- Search for volunteers available on Monday +SELECT user_id +FROM virginia_dev_saayam_rdbms.volunteer_details +WHERE availability_days ? 'Monday'; + +-- Search for volunteers available in the Morning +SELECT user_id +FROM virginia_dev_saayam_rdbms.volunteer_details +WHERE availability_times ? 'Morning'; From ff3934aa21aa76131064584ca2db4c4ce0de5af4 Mon Sep 17 00:00:00 2001 From: PallaviChitrada Date: Wed, 24 Dec 2025 18:54:43 -0500 Subject: [PATCH 15/19] Refactor SQL test cases for volunteer onboarding --- script-library/tests/volunteer_onboarding.sql | 75 ++++++++++--------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/script-library/tests/volunteer_onboarding.sql b/script-library/tests/volunteer_onboarding.sql index 8889c43..a235df4 100644 --- a/script-library/tests/volunteer_onboarding.sql +++ b/script-library/tests/volunteer_onboarding.sql @@ -1,60 +1,63 @@ -- WRITE YOUR OWN TEST CASES AS WE HAVE THE FOREIGN KEY IMPLEMENTED - --- Test Audit Timestamps --- This test verifies that the updated_at_handler trigger correctly updates timestamps when you make changes, prioritizing the database's UTC time if the API provides none. - --- Step 1: Insert a test application -INSERT INTO virginia_dev_saayam_rdbms.volunteer_applications (user_id, application_status) -VALUES ('test_user_001', 'STARTED'); - --- Step 2: Update a field (like current_page) and check if updated_at changes -UPDATE virginia_dev_saayam_rdbms.volunteer_applications +INSERT INTO public.help_categories (cat_id, cat_name) VALUES +('1', 'Education & Tutoring'), +('2', 'Medical Assistance'), +('3', 'Logistics & Transport'), +('2.1', 'Child Care'), +('5', 'Administrative Support'); + +INSERT INTO public.users (full_name) VALUES +('Alice Johnson'), +('Bob Smith'); + +-- Insert a test application +INSERT INTO public.volunteer_applications (user_id, application_status) +VALUES ('SID-00-000-000-001', 'STARTED'); + +-- Update a field (like current_page) and check if updated_at changes +UPDATE public.volunteer_applications SET current_page = 2 -WHERE user_id = 'test_user_001'; +WHERE user_id = 'SID-00-000-000-001'; --- Step 3: Update the govt_id_path specifically +-- Update the govt_id_path specifically -- Check if path_updated_at refreshes while others remain distinct -UPDATE virginia_dev_saayam_rdbms.volunteer_applications -SET govt_id_path = 'https://storage.com/id1.jpg' -WHERE user_id = 'test_user_001'; +UPDATE public.volunteer_applications +SET govt_id_path = 'https://storage.com/alice_id.jpg' +WHERE user_id = 'SID-00-000-000-001'; SELECT user_id, updated_at, path_updated_at FROM virginia_dev_saayam_rdbms.volunteer_applications; -- Test Volunteer Acceptance (Migration Trigger) --- Step 1: Prepare the application with skills and availability -UPDATE virginia_dev_saayam_rdbms.volunteer_applications +UPDATE public.volunteer_applications SET application_status = 'IN_REVIEW', - skill_codes = '["SKILL_01", "SKILL_02"]', - availability = '{"days": ["Monday", "Wednesday"], "time": ["Morning"]}'::JSONB, + skill_codes = '["2", "5"]', + availability = '{"days": ["Monday", "Wednesday"], "time": ["2025-12-24 23:17:20.929643"]}'::JSONB, terms_and_conditions = TRUE -WHERE user_id = 'test_user_001'; +WHERE user_id = 'SID-00-000-000-001'; --- Step 2: Trigger the migration by accepting the volunteer -UPDATE virginia_dev_saayam_rdbms.volunteer_applications +-- This executes your 'handle_volunteer_application' function +UPDATE public.volunteer_applications SET application_status = 'ACCEPTED' -WHERE user_id = 'test_user_001'; - --- Step 3: Verify migration to volunteer_details -SELECT * FROM virginia_dev_saayam_rdbms.volunteer_details WHERE user_id = 'test_user_001'; +WHERE user_id = 'SID-00-000-000-001'; --- Step 4: Verify migration to user_skills (should have 2 rows for the 2 skill_codes) -SELECT * FROM virginia_dev_saayam_rdbms.user_skills WHERE user_id = 'test_user_001'; +SELECT * FROM public.volunteer_details WHERE user_id = 'SID-00-000-000-001'; +SELECT * FROM public.user_skills WHERE user_id = 'SID-00-000-000-001'; +SELECT * FROM public.volunteer_applications WHERE user_id = 'SID-00-000-000-001'; --- Test Skill Search Performance --- Search for all volunteers who have "SKILL_01" -- Use EXPLAIN to confirm the index idx_user_skills_cat_id is being used EXPLAIN ANALYZE SELECT user_id -FROM virginia_dev_saayam_rdbms.user_skills -WHERE cat_id = 'SKILL_01'; +FROM public.user_skills +WHERE cat_id = '5'; --- Test Availability Search -- Search for volunteers available on Monday SELECT user_id FROM virginia_dev_saayam_rdbms.volunteer_details WHERE availability_days ? 'Monday'; --- Search for volunteers available in the Morning SELECT user_id -FROM virginia_dev_saayam_rdbms.volunteer_details -WHERE availability_times ? 'Morning'; +FROM public.volunteer_details +WHERE availability_times ? '2025-12-24 23:17:20.929643'; + + + From 92a567205b5a16fed6047d63540826aff817887b Mon Sep 17 00:00:00 2001 From: PallaviChitrada Date: Wed, 24 Dec 2025 19:10:23 -0500 Subject: [PATCH 16/19] Refactor updated_at_handler for volunteer applications --- ddl/Tables/ddl_volunteer_applications.sql | 30 +++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/ddl/Tables/ddl_volunteer_applications.sql b/ddl/Tables/ddl_volunteer_applications.sql index 24573a6..655f346 100644 --- a/ddl/Tables/ddl_volunteer_applications.sql +++ b/ddl/Tables/ddl_volunteer_applications.sql @@ -21,39 +21,39 @@ CREATE TABLE virginia_dev_saayam_rdbms.volunteer_applications ( CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.updated_at_handler() RETURNS TRIGGER AS $$ BEGIN + -- check if the last_updated_at was explicitly changed in the UPDATE statement. + -- if it WASN'T changed by the API, we force it to the current UTC. + IF (NEW.last_updated_at IS NOT DISTINCT FROM OLD.last_updated_at) THEN + NEW.last_updated_at = (now() AT TIME ZONE 'UTC'); + END IF; + -- handle application table IF (TG_TABLE_NAME = 'volunteer_applications') THEN - - NEW.last_updated_at = COALESCE(NEW.last_updated_at, (now() AT TIME ZONE 'UTC')); -- for any attribute - -- Update path timestamp if path changed IF (NEW.govt_id_path IS DISTINCT FROM OLD.govt_id_path) THEN - NEW.path_updated_at = COALESCE(NEW.path_updated_at, (now() AT TIME ZONE 'UTC')); + NEW.path_updated_at = (now() AT TIME ZONE 'UTC'); END IF; -- Update terms timestamp if accepted IF (NEW.terms_and_conditions IS TRUE AND (OLD.terms_and_conditions IS FALSE OR OLD.terms_and_conditions IS NULL)) THEN - NEW.terms_accepted_at = COALESCE(NEW.terms_accepted_at, (now() AT TIME ZONE 'UTC')); + NEW.terms_accepted_at = (now() AT TIME ZONE 'UTC'); END IF; -- handle details table ELSIF (TG_TABLE_NAME = 'volunteer_details') THEN - - NEW.last_updated_at = COALESCE(NEW.last_updated_at, (now() AT TIME ZONE 'UTC')); -- for any attribute - -- update path1 timestamp if changed IF (NEW.govt_id_path1 IS DISTINCT FROM OLD.govt_id_path1) THEN - NEW.path1_updated_at = COALESCE(NEW.path1_updated_at, (now() AT TIME ZONE 'UTC')); + NEW.path1_updated_at = (now() AT TIME ZONE 'UTC'); END IF; -- update path2 timestamp if changed IF (NEW.govt_id_path2 IS DISTINCT FROM OLD.govt_id_path2) THEN - NEW.path2_updated_at = COALESCE(NEW.path2_updated_at, (now() AT TIME ZONE 'UTC')); + NEW.path2_updated_at = (now() AT TIME ZONE 'UTC'); END IF; -- update terms timestamp if accepted IF (NEW.terms_and_conditions IS TRUE AND (OLD.terms_and_conditions IS FALSE OR OLD.terms_and_conditions IS NULL)) THEN - NEW.terms_accepted_at = COALESCE(NEW.terms_accepted_at, (now() AT TIME ZONE 'UTC')); + NEW.terms_accepted_at = (now() AT TIME ZONE 'UTC'); END IF; END IF; @@ -69,11 +69,11 @@ BEGIN -- Migrate to volunteer_details INSERT INTO virginia_dev_saayam_rdbms.volunteer_details ( user_id, terms_and_conditions, terms_accepted_at, - govt_id_path1, availability_days, availability_times, + govt_id_path1, path1_updated_at, path2_updated_at, availability_days, availability_times, created_at, last_updated_at ) VALUES ( NEW.user_id, NEW.terms_and_conditions, NEW.terms_accepted_at, - NEW.govt_id_path, (NEW.availability -> 'days')::JSONB, (NEW.availability -> 'time')::JSONB, + NEW.govt_id_path, NEW.path_updated_at, NULL, (NEW.availability -> 'days')::JSONB, (NEW.availability -> 'time')::JSONB, NEW.last_updated_at, NEW.last_updated_at ); @@ -89,6 +89,8 @@ BEGIN NEW.last_updated_at FROM json_array_elements_text(NEW.skill_codes) AS skill_id; END IF; + + DELETE FROM virginia_dev_saayam_rdbms.volunteer_applications WHERE user_id = NEW.user_id; END IF; RETURN NEW; @@ -102,3 +104,5 @@ CREATE TRIGGER trg_volunteer_app_updated_at CREATE TRIGGER trg_handle_volunteer_application AFTER UPDATE ON virginia_dev_saayam_rdbms.volunteer_applications FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.handle_volunteer_application(); + +ALTER TABLE virginia_dev_saayam_rdbms.volunteer_applications ENABLE TRIGGER trg_volunteer_app_updated_at; From 0289cf0924bd29d436ca669ceefc9f136953d8f6 Mon Sep 17 00:00:00 2001 From: Joshitha Sai Uppalapati Date: Fri, 19 Dec 2025 19:01:50 -0500 Subject: [PATCH 17/19] Resolve conflicts and finalize volunteer onboarding schema, triggers, and test --- ddl/Tables/ddl_user_skills.sql | 20 +-- ddl/Tables/ddl_volunteer_applications.sql | 161 +++++++++--------- ddl/Tables/ddl_volunteer_details.sql | 31 ++-- .../volunteer_onboarding_trigger_test.sql | 74 +++----- 4 files changed, 120 insertions(+), 166 deletions(-) diff --git a/ddl/Tables/ddl_user_skills.sql b/ddl/Tables/ddl_user_skills.sql index 8690a90..5ce39a1 100644 --- a/ddl/Tables/ddl_user_skills.sql +++ b/ddl/Tables/ddl_user_skills.sql @@ -1,18 +1,12 @@ DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.user_skills CASCADE; CREATE TABLE virginia_dev_saayam_rdbms.user_skills ( - user_id VARCHAR(255), - cat_id VARCHAR(50) NOT NULL, - created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - last_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - PRIMARY KEY (user_id, cat_id), - FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users(user_id), - FOREIGN KEY (cat_id) REFERENCES virginia_dev_saayam_rdbms.help_categories(cat_id) -); + user_id VARCHAR(255) NOT NULL, + cat_id INT NOT NULL, + + created_at TIMESTAMP WITHOUT TIME ZONE, + updated_at TIMESTAMP WITHOUT TIME ZONE, -CREATE TRIGGER trg_user_skills_updated_at -BEFORE UPDATE ON virginia_dev_saayam_rdbms.user_skills -FOR EACH ROW -EXECUTE FUNCTION set_updated_at(); + CONSTRAINT user_skills_pkey PRIMARY KEY (user_id, cat_id) +); -CREATE INDEX idx_user_skills_cat_id ON virginia_dev_saayam_rdbms.user_skills (cat_id); diff --git a/ddl/Tables/ddl_volunteer_applications.sql b/ddl/Tables/ddl_volunteer_applications.sql index 655f346..ab44ab7 100644 --- a/ddl/Tables/ddl_volunteer_applications.sql +++ b/ddl/Tables/ddl_volunteer_applications.sql @@ -1,108 +1,101 @@ --- ENUM for application status -CREATE TYPE virginia_dev_saayam_rdbms.app_status_type AS ENUM ('STARTED', 'IN_REVIEW', 'ACCEPTED', 'REJECTED'); +DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_applications CASCADE; --- Create the volunteer_applications table CREATE TABLE virginia_dev_saayam_rdbms.volunteer_applications ( user_id VARCHAR(255) PRIMARY KEY, - terms_and_conditions BOOLEAN DEFAULT FALSE, - terms_accepted_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - govt_id_path TEXT, - path_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - skill_codes JSON, - availability JSONB, - current_page INT DEFAULT 1, -- Changed from TEXT to INT for numerical tracking - application_status virginia_dev_saayam_rdbms.app_status_type DEFAULT 'STARTED', - is_completed BOOLEAN DEFAULT FALSE, --extra precaution - created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - last_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users(user_id) -); -CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.updated_at_handler() -RETURNS TRIGGER AS $$ -BEGIN - -- check if the last_updated_at was explicitly changed in the UPDATE statement. - -- if it WASN'T changed by the API, we force it to the current UTC. - IF (NEW.last_updated_at IS NOT DISTINCT FROM OLD.last_updated_at) THEN - NEW.last_updated_at = (now() AT TIME ZONE 'UTC'); - END IF; + terms_and_conditions BOOLEAN, + terms_and_conditions_accepted_at TIMESTAMP WITHOUT TIME ZONE, - -- handle application table - IF (TG_TABLE_NAME = 'volunteer_applications') THEN - -- Update path timestamp if path changed - IF (NEW.govt_id_path IS DISTINCT FROM OLD.govt_id_path) THEN - NEW.path_updated_at = (now() AT TIME ZONE 'UTC'); - END IF; + skill_codes JSON, + availability JSONB, - -- Update terms timestamp if accepted - IF (NEW.terms_and_conditions IS TRUE AND (OLD.terms_and_conditions IS FALSE OR OLD.terms_and_conditions IS NULL)) THEN - NEW.terms_accepted_at = (now() AT TIME ZONE 'UTC'); - END IF; + application_status TEXT, + is_completed BOOLEAN, + current_page TEXT, - -- handle details table - ELSIF (TG_TABLE_NAME = 'volunteer_details') THEN - -- update path1 timestamp if changed - IF (NEW.govt_id_path1 IS DISTINCT FROM OLD.govt_id_path1) THEN - NEW.path1_updated_at = (now() AT TIME ZONE 'UTC'); - END IF; - - -- update path2 timestamp if changed - IF (NEW.govt_id_path2 IS DISTINCT FROM OLD.govt_id_path2) THEN - NEW.path2_updated_at = (now() AT TIME ZONE 'UTC'); - END IF; + govt_id_storage_path TEXT, + path_updated_at TIMESTAMP WITHOUT TIME ZONE, - -- update terms timestamp if accepted - IF (NEW.terms_and_conditions IS TRUE AND (OLD.terms_and_conditions IS FALSE OR OLD.terms_and_conditions IS NULL)) THEN - NEW.terms_accepted_at = (now() AT TIME ZONE 'UTC'); - END IF; - END IF; + created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(), + updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() +); +CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.set_application_updated_at() +RETURNS TRIGGER +LANGUAGE plpgsql +AS $$ +BEGIN + NEW.updated_at = now(); RETURN NEW; END; -$$ LANGUAGE plpgsql; +$$; -CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.handle_volunteer_application() -RETURNS TRIGGER AS $$ +DROP TRIGGER IF EXISTS trg_set_application_updated_at +ON virginia_dev_saayam_rdbms.volunteer_applications; + +CREATE TRIGGER trg_set_application_updated_at +BEFORE UPDATE +ON virginia_dev_saayam_rdbms.volunteer_applications +FOR EACH ROW +EXECUTE FUNCTION virginia_dev_saayam_rdbms.set_application_updated_at(); + +CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance() +RETURNS TRIGGER +LANGUAGE plpgsql +AS $$ BEGIN - IF (NEW.application_status = 'ACCEPTED' AND OLD.application_status != 'ACCEPTED') THEN - - -- Migrate to volunteer_details + IF OLD.application_status = 'submitted' + AND NEW.application_status = 'accepted' + THEN INSERT INTO virginia_dev_saayam_rdbms.volunteer_details ( - user_id, terms_and_conditions, terms_accepted_at, - govt_id_path1, path1_updated_at, path2_updated_at, availability_days, availability_times, - created_at, last_updated_at - ) VALUES ( - NEW.user_id, NEW.terms_and_conditions, NEW.terms_accepted_at, - NEW.govt_id_path, NEW.path_updated_at, NULL, (NEW.availability -> 'days')::JSONB, (NEW.availability -> 'time')::JSONB, - NEW.last_updated_at, NEW.last_updated_at + user_id, + terms_and_conditions, + terms_and_conditions_update_date, + govt_id_path1, + availability_days, + availability_times, + created_at, + updated_at + ) + VALUES ( + NEW.user_id, + NEW.terms_and_conditions, + NEW.terms_and_conditions_accepted_at, + NEW.govt_id_storage_path, + NEW.availability -> 'days', + NEW.availability -> 'time', + NEW.updated_at, + NEW.updated_at ); - -- Migrate to user_skills (unrolling the JSON array) - IF (NEW.skill_codes IS NOT NULL) THEN + IF NEW.skill_codes IS NOT NULL THEN INSERT INTO virginia_dev_saayam_rdbms.user_skills ( - user_id, cat_id, created_at, last_updated_at + user_id, + cat_id, + created_at, + updated_at ) - SELECT - NEW.user_id, - skill_id, - NEW.last_updated_at, - NEW.last_updated_at - FROM json_array_elements_text(NEW.skill_codes) AS skill_id; + SELECT + NEW.user_id, + value::INT, + NEW.updated_at, + NEW.updated_at + FROM json_array_elements_text(NEW.skill_codes); END IF; - DELETE FROM virginia_dev_saayam_rdbms.volunteer_applications WHERE user_id = NEW.user_id; + DELETE FROM virginia_dev_saayam_rdbms.volunteer_applications + WHERE user_id = NEW.user_id; END IF; - - RETURN NEW; -END; -$$ LANGUAGE plpgsql; -CREATE TRIGGER trg_volunteer_app_updated_at - BEFORE UPDATE ON virginia_dev_saayam_rdbms.volunteer_applications - FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.updated_at_handler(); + RETURN NULL; +END; +$$; -CREATE TRIGGER trg_handle_volunteer_application - AFTER UPDATE ON virginia_dev_saayam_rdbms.volunteer_applications - FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.handle_volunteer_application(); +DROP TRIGGER IF EXISTS trg_handle_application_acceptance +ON virginia_dev_saayam_rdbms.volunteer_applications; -ALTER TABLE virginia_dev_saayam_rdbms.volunteer_applications ENABLE TRIGGER trg_volunteer_app_updated_at; +CREATE TRIGGER trg_handle_application_acceptance +AFTER UPDATE OF application_status +ON virginia_dev_saayam_rdbms.volunteer_applications +FOR EACH ROW +EXECUTE FUNCTION virginia_dev_saayam_rdbms.handle_application_acceptance(); diff --git a/ddl/Tables/ddl_volunteer_details.sql b/ddl/Tables/ddl_volunteer_details.sql index f84918a..aeba081 100644 --- a/ddl/Tables/ddl_volunteer_details.sql +++ b/ddl/Tables/ddl_volunteer_details.sql @@ -1,28 +1,19 @@ --- DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; +DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; CREATE TABLE virginia_dev_saayam_rdbms.volunteer_details ( user_id VARCHAR(255) PRIMARY KEY, + terms_and_conditions BOOLEAN, - terms_accepted_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), + terms_and_conditions_update_date TIMESTAMP WITHOUT TIME ZONE, + govt_id_path1 TEXT, govt_id_path2 TEXT, - path1_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - path2_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - availability_days JSONB, - availability_times JSONB, - created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - last_updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'UTC'), - FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users(user_id) -); + path1_updated_at TIMESTAMP WITHOUT TIME ZONE, + path2_updated_at TIMESTAMP WITHOUT TIME ZONE, -CREATE TRIGGER trg_volunteer_details_updated_at - BEFORE UPDATE ON virginia_dev_saayam_rdbms.volunteer_details - FOR EACH ROW EXECUTE FUNCTION virginia_dev_saayam_rdbms.updated_at_handler(); + availability_days JSON, + availability_times JSON, --- Index for searching specific days (e.g., 'Monday') -CREATE INDEX idx_volunteer_availability_days -ON virginia_dev_saayam_rdbms.volunteer_details USING GIN (availability_days); - --- Index for searching specific time slots -CREATE INDEX idx_volunteer_availability_times -ON virginia_dev_saayam_rdbms.volunteer_details USING GIN (availability_times); + created_at TIMESTAMP WITHOUT TIME ZONE, + updated_at TIMESTAMP WITHOUT TIME ZONE +); diff --git a/script-library/tests/volunteer_onboarding_trigger_test.sql b/script-library/tests/volunteer_onboarding_trigger_test.sql index c2d749a..a830665 100644 --- a/script-library/tests/volunteer_onboarding_trigger_test.sql +++ b/script-library/tests/volunteer_onboarding_trigger_test.sql @@ -1,63 +1,39 @@ --- Test Case: Volunteer onboarding trigger --- Validates trigger behavior on volunteer_applications acceptance +BEGIN; -SET search_path TO virginia_dev_saayam_rdbms; - --- Cleanup existing test data -DELETE FROM user_skills WHERE user_id = 'SID-TEST-PR-01'; -DELETE FROM volunteer_details WHERE user_id = 'SID-TEST-PR-01'; -DELETE FROM volunteer_applications WHERE user_id = 'SID-TEST-PR-01'; - --- Step 1: Insert volunteer application -INSERT INTO volunteer_applications ( +INSERT INTO virginia_dev_saayam_rdbms.volunteer_applications ( user_id, - application_status, + terms_and_conditions, + terms_and_conditions_accepted_at, + skill_codes, availability, - selected_skill_codes, + application_status, govt_id_storage_path -) VALUES ( - 'SID-TEST-PR-01', - 'submitted', +) +VALUES ( + 'SID-TEST-TRG-01', + TRUE, + now(), + '[101,102]', '{"days":["Monday","Wednesday"],"time":["Morning","Evening"]}'::jsonb, - ARRAY[101,102], + 'submitted', 's3://fake-bucket/govt-id-1.png' ); --- Verify application insert -SELECT user_id, application_status -FROM volunteer_applications -WHERE user_id = 'SID-TEST-PR-01'; - --- Step 2: Accept the application (trigger fires) -UPDATE volunteer_applications +UPDATE virginia_dev_saayam_rdbms.volunteer_applications SET application_status = 'accepted' -WHERE user_id = 'SID-TEST-PR-01'; +WHERE user_id = 'SID-TEST-TRG-01'; --- Step 3: Application should be removed -SELECT * -FROM volunteer_applications -WHERE user_id = 'SID-TEST-PR-01'; +SELECT * +FROM virginia_dev_saayam_rdbms.volunteer_details +WHERE user_id = 'SID-TEST-TRG-01'; --- Step 4: Volunteer details auto-created -SELECT - user_id, - govt_id_path, - govt_id_path2, - iscomplete, - completed_date -FROM volunteer_details -WHERE user_id = 'SID-TEST-PR-01'; +SELECT * +FROM virginia_dev_saayam_rdbms.user_skills +WHERE user_id = 'SID-TEST-TRG-01'; --- Step 5: Skills expanded into user_skills -SELECT - user_id, - cat_id, - created_at -FROM user_skills -WHERE user_id = 'SID-TEST-PR-01' -ORDER BY cat_id; +SELECT * +FROM virginia_dev_saayam_rdbms.volunteer_applications +WHERE user_id = 'SID-TEST-TRG-01'; --- Step 6: Count validation -SELECT count(*) FROM volunteer_details WHERE user_id = 'SID-TEST-PR-01'; -SELECT count(*) FROM user_skills WHERE user_id = 'SID-TEST-PR-01'; +ROLLBACK; From dfa7bb09fc7d9a27312f63b55e9a38fea0f53af2 Mon Sep 17 00:00:00 2001 From: PallaviChitrada Date: Thu, 25 Dec 2025 13:49:57 -0500 Subject: [PATCH 18/19] Delete script-library/tests/volunteer_onboarding_trigger_test.sql --- .../volunteer_onboarding_trigger_test.sql | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 script-library/tests/volunteer_onboarding_trigger_test.sql diff --git a/script-library/tests/volunteer_onboarding_trigger_test.sql b/script-library/tests/volunteer_onboarding_trigger_test.sql deleted file mode 100644 index c2d749a..0000000 --- a/script-library/tests/volunteer_onboarding_trigger_test.sql +++ /dev/null @@ -1,63 +0,0 @@ --- Test Case: Volunteer onboarding trigger --- Validates trigger behavior on volunteer_applications acceptance - -SET search_path TO virginia_dev_saayam_rdbms; - --- Cleanup existing test data -DELETE FROM user_skills WHERE user_id = 'SID-TEST-PR-01'; -DELETE FROM volunteer_details WHERE user_id = 'SID-TEST-PR-01'; -DELETE FROM volunteer_applications WHERE user_id = 'SID-TEST-PR-01'; - --- Step 1: Insert volunteer application -INSERT INTO volunteer_applications ( - user_id, - application_status, - availability, - selected_skill_codes, - govt_id_storage_path -) VALUES ( - 'SID-TEST-PR-01', - 'submitted', - '{"days":["Monday","Wednesday"],"time":["Morning","Evening"]}'::jsonb, - ARRAY[101,102], - 's3://fake-bucket/govt-id-1.png' -); - --- Verify application insert -SELECT user_id, application_status -FROM volunteer_applications -WHERE user_id = 'SID-TEST-PR-01'; - --- Step 2: Accept the application (trigger fires) -UPDATE volunteer_applications -SET application_status = 'accepted' -WHERE user_id = 'SID-TEST-PR-01'; - --- Step 3: Application should be removed -SELECT * -FROM volunteer_applications -WHERE user_id = 'SID-TEST-PR-01'; - --- Step 4: Volunteer details auto-created -SELECT - user_id, - govt_id_path, - govt_id_path2, - iscomplete, - completed_date -FROM volunteer_details -WHERE user_id = 'SID-TEST-PR-01'; - --- Step 5: Skills expanded into user_skills -SELECT - user_id, - cat_id, - created_at -FROM user_skills -WHERE user_id = 'SID-TEST-PR-01' -ORDER BY cat_id; - --- Step 6: Count validation -SELECT count(*) FROM volunteer_details WHERE user_id = 'SID-TEST-PR-01'; -SELECT count(*) FROM user_skills WHERE user_id = 'SID-TEST-PR-01'; - From 0fae3a8eb692b389fd20fb01c8f3f5738a39be59 Mon Sep 17 00:00:00 2001 From: Joshitha Sai Uppalapati Date: Mon, 16 Mar 2026 12:34:23 -0400 Subject: [PATCH 19/19] Fix availability schema and add emergency flag --- ddl/Tables/ddl_user_availability.sql | 7 ++++--- ddl/Tables/ddl_users.sql | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ddl/Tables/ddl_user_availability.sql b/ddl/Tables/ddl_user_availability.sql index 1b9ace3..5f0a323 100644 --- a/ddl/Tables/ddl_user_availability.sql +++ b/ddl/Tables/ddl_user_availability.sql @@ -2,9 +2,10 @@ CREATE TABLE IF NOT EXISTS virginia_dev_saayam_rdbms.user_availability ( user_availability_id SERIAL PRIMARY KEY, user_id VARCHAR(255) NOT NULL, - day_of_week VARCHAR(10) CHECK (day_of_week IN ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')), - start_time TIMESTAMP NOT NULL, - end_time TIMESTAMP NOT NULL, + day_of_week VARCHAR(10) NOT NULL CHECK (day_of_week IN ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')), + CHECK (end_time > start_time), + start_time TIME NOT NULL, + end_time TIME NOT NULL, last_update_date TIMESTAMP, FOREIGN KEY (user_id) REFERENCES virginia_dev_saayam_rdbms.users (user_id) ); diff --git a/ddl/Tables/ddl_users.sql b/ddl/Tables/ddl_users.sql index 1d0d03b..a34a853 100644 --- a/ddl/Tables/ddl_users.sql +++ b/ddl/Tables/ddl_users.sql @@ -19,6 +19,7 @@ CREATE TABLE IF NOT EXISTS virginia_dev_saayam_rdbms.users ( last_location point, last_update_date TIMESTAMP, time_zone VARCHAR(255) NULL, + is_emergency_available BOOLEAN DEFAULT FALSE, profile_picture_path VARCHAR(255) NULL, gender VARCHAR(255) NULL, language_1 VARCHAR(255) NULL,