diff --git a/ddl/Tables/ddl_meeting_participants.sql b/ddl/Tables/ddl_meeting_participants.sql new file mode 100644 index 0000000..8972d3c --- /dev/null +++ b/ddl/Tables/ddl_meeting_participants.sql @@ -0,0 +1,26 @@ +CREATE TABLE virginia_dev_saayam_rdbms.meeting_participants( + meeting_id VARCHAR(255) NOT NULL, + participant_id VARCHAR(255) NOT NULL, + + --Unique identifer for table + CONSTRAINT meeting_participant_pk + PRIMARY KEY (meeting_id, participant_id), + + -- Foreign key constraint for meeting_id + CONSTRAINT meeting_participant_meetingid_fk + FOREIGN KEY (meeting_id) + REFERENCES meetings(meeting_id), + + -- Foreign key constraint for participant_id + CONSTRAINT meeting_participant_participant_fk + FOREIGN KEY (participant_id) + REFERENCES users(user_id) + +); + +-- INDEXING + +-- Index to pull participants for a particular meeting +CREATE INDEX IF NOT EXISTS mp_meeting_id_idx +ON meeting_participants(meeting_id); + diff --git a/ddl/Tables/ddl_meetings.sql b/ddl/Tables/ddl_meetings.sql new file mode 100644 index 0000000..dd9c29e --- /dev/null +++ b/ddl/Tables/ddl_meetings.sql @@ -0,0 +1,29 @@ +-- Meetings table +-- Timezone is WITHOUT TIMEZONE (UTC default) + +SET TIME ZONE 'UTC'; + +CREATE TABLE virginia_dev_saayam_rdbms.meetings ( +meeting_id VARCHAR(255) NOT NULL, +meeting_date DATE NOT NULL, +start_time TIME WITHOUT TIME ZONE NOT NULL, +end_time TIME WITHOUT TIME ZONE NOT NULL, +cohost_id VARCHAR(255) NOT NULL, + +-- Primary key constraint +CONSTRAINT meetings_pk +PRIMARY KEY(meeting_id, cohost_id), + +--Unique idenitifer for table +CONSTRAINT meetings_meeting_id_unique +UNIQUE(meeting_id), + +-- Foreign key constraint +CONSTRAINT meetings_fk +FOREIGN KEY (cohost_id) +REFERENCES users(user_id), + +-- Time check constraint +CONSTRAINT meetings_time_chk +CHECK (end_time>start_time) + ); \ No newline at end of file diff --git a/ddl/Tables/ddl_user_skills.sql b/ddl/Tables/ddl_user_skills.sql index 2dc1bce..8690a90 100644 --- a/ddl/Tables/ddl_user_skills.sql +++ b/ddl/Tables/ddl_user_skills.sql @@ -1,14 +1,18 @@ -CREATE TYPE skill_levels AS ENUM('BEGINNER', 'INTERMEDIATE', 'ADVANCED', 'EXPERT'); +DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.user_skills CASCADE; --- 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) -); \ No newline at end of file +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) +); + +CREATE TRIGGER trg_user_skills_updated_at +BEFORE UPDATE ON virginia_dev_saayam_rdbms.user_skills +FOR EACH ROW +EXECUTE FUNCTION set_updated_at(); + +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 new file mode 100644 index 0000000..655f346 --- /dev/null +++ b/ddl/Tables/ddl_volunteer_applications.sql @@ -0,0 +1,108 @@ +-- 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 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; + + -- 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; + + -- 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; + + -- 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; + + -- 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; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION virginia_dev_saayam_rdbms.handle_volunteer_application() +RETURNS TRIGGER AS $$ +BEGIN + 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_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 + ); + + -- 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, last_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; + END IF; + + 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(); + +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; diff --git a/ddl/Tables/ddl_volunteer_details.sql b/ddl/Tables/ddl_volunteer_details.sql index b533b59..f84918a 100644 --- a/ddl/Tables/ddl_volunteer_details.sql +++ b/ddl/Tables/ddl_volunteer_details.sql @@ -1,43 +1,28 @@ --- 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; +-- DROP TABLE IF EXISTS virginia_dev_saayam_rdbms.volunteer_details CASCADE; --- -- 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 +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'), + 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) +); --- To ensure each volunteer is unique by user_id as we don’t plan to allow multiple volunteer rows per use +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(); -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; -$$; +-- 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); diff --git a/dml/Populating Data Files/help_categories.csv b/dml/Populating Data Files/help_categories.csv index b14160c..275210d 100644 --- a/dml/Populating Data Files/help_categories.csv +++ b/dml/Populating Data Files/help_categories.csv @@ -1,4 +1,4 @@ -cat_id,cat_name,cat_desc +cat_id,cat_name,cat_desc 0.0.0.0.0,GENERAL_CATEGORY,GENERAL_CATEGORY_DESC 1,FOOD_AND_ESSENTIALS,FOOD_AND_ESSENTIALS_DESC 1.1,FOOD_ASSISTANCE,FOOD_ASSISTANCE_DESC @@ -16,9 +16,14 @@ 2.4,TAILORING,TAILORING_DESC 3,HOUSING_ASSISTANCE,HOUSING_ASSISTANCE_DESC 3.1,LEASE_SUPPORT,LEASE_SUPPORT_DESC +3.10,SELL_THINGS,SELL_THINGS_DESC 3.2,TENANT_RENT_SUPPORT,TENANT_RENT_SUPPORT_DESC 3.3,REPAIR_MAINTENANCE_SUPPORT,REPAIR_MAINTENANCE_SUPPORT_DESC 3.3.1,PLUMBING,PLUMBING_DESC +3.3.10,MASONRY_OR_CONCRETE,MASONRY_OR_CONCRETE_DESC +3.3.11,METALWORK_OR_WELDING,METALWORK_OR_WELDING_DESC +3.3.12,POOL_AND_SPA_MAINTENANCE,POOL_AND_SPA_MAINTENANCE_DESC +3.3.13,OTHER_RAPAIR_MAINTENANCE_SUPPORT,OTHER_RAPAIR_MAINTENANCE_SUPPORT_DESC 3.3.2,HANDYMAN,HANDYMAN_DESC 3.3.3,ELECTRICIAN,ELECTRICIAN_DESC 3.3.4,CARPENTRY,CARPENTRY_DESC @@ -27,17 +32,12 @@ 3.3.7,ROOFING,ROOFING_DESC 3.3.8,LOCKSMITH,LOCKSMITH_DESC 3.3.9,PAINTING,PAINTING_DESC -3.3.10,MASONRY_OR_CONCRETE,MASONRY_OR_CONCRETE_DESC -3.3.11,METALWORK_OR_WELDING,METALWORK_OR_WELDING_DESC -3.3.12,POOL_AND_SPA_MAINTENANCE,POOL_AND_SPA_MAINTENANCE_DESC -3.3.13,OTHER_RAPAIR_MAINTENANCE_SUPPORT,OTHER_RAPAIR_MAINTENANCE_SUPPORT_DESC 3.4,UTILITIES_SETUP_SUPPORT,UTILITIES_SETUP_SUPPORT_DESC 3.5,LOOKING_FOR_RENTAL,LOOKING_FOR_RENTAL_DESC 3.6,FIND_ROOMATE,FIND_ROOMATE_DESC 3.7,MOVE_IN_HELP,MOVE_IN_HELP_DESC 3.8,BOOKING_PACKERS_MOVERS_SUPPORT,BOOKING_PACKERS_MOVERS_SUPPORT_DESC 3.9,BUY_THINGS,BUY_THINGS_DESC -3.10,SELL_THINGS,SELL_THINGS_DESC 4,EDUCATION_CAREER_SUPPORT,EDUCATION_CAREER_SUPPORT_DESC 4.1,COLLEGE_APPLICATION_HELP,COLLEGE_APPLICATION_HELP_DESC 4.2,SOP_ESSAY_REVIEW,SOP_ESSAY_REVIEW_DESC @@ -55,6 +55,8 @@ 5,HEALTHCARE_AND_WELLNESS,HEALTHCARE_AND_WELLNESS_DESC 5.1,MEDICAL_CONSULTATION,MEDICAL_CONSULTATION_DESC 5.1.1,GENERAL_CONSULTATION,GENERAL_CONSULTATION_DESC +5.1.10,PEDIATRICS_OR_CHILD_HEALTH,PEDIATRICS_OR_CHILD_HEALTH_DESC +5.1.11,OTHER_MEDICAL_CONCERN,OTHER_MEDICAL_CONCERN_DESC 5.1.2,ENT(EAR_NOSE_AND_THROAT),ENT(EAR_NOSE_AND_THROAT)_DESC 5.1.3,DENTAL_OR_ORAL_HEALTH,DENTAL_OR_ORAL_HEALTH_DESC 5.1.4,EYE_OR_VISION_CARE,EYE_OR_VISION_CARE_DESC @@ -63,8 +65,6 @@ 5.1.7,SKIN_OR_DERMATOLOGY,SKIN_OR_DERMATOLOGY_DESC 5.1.8,WOMENS_OR_REPRODUCTIVE_HEALTH,WOMENS_OR_REPRODUCTIVE_HEALTH_DESC 5.1.9,VACCINATIONS_AND_PREVENTIVE_SCREENINGS,VACCINATIONS_AND_PREVENTIVE_SCREENINGS_DESC -5.1.10,PEDIATRICS_OR_CHILD_HEALTH,PEDIATRICS_OR_CHILD_HEALTH_DESC -5.1.11,OTHER_MEDICAL_CONCERN,OTHER_MEDICAL_CONCERN_DESC 5.2,MEDICINE_DELIVERY,MEDICINE_DELIVERY_DESC 5.3,MENTAL_WELLBEING_SUPPORT,MENTAL_WELLBEING_SUPPORT_DESC 5.4,MEDICATION_REMINDERS,MEDICATION_REMINDERS_DESC diff --git a/dml/Populating Data Files/list_item_metadata.csv b/dml/Populating Data Files/list_item_metadata.csv index b451d0b..23dc676 100644 --- a/dml/Populating Data Files/list_item_metadata.csv +++ b/dml/Populating Data Files/list_item_metadata.csv @@ -1,4 +1,4 @@ -item_id,field_id,item_value,item_type +item_id,field_id,item_value,item_type 1.1.A.1,1.1.A,VEGETARIAN,radiobutton 1.1.A.2,1.1.A,VEGAN,radiobutton 1.1.A.3,1.1.A,NON_VEGETARIAN,radiobutton @@ -116,6 +116,26 @@ 2.4.C.7,2.4.C,SAREE_TRADITIONAL_WEAR,checkbox 2.4.C.8,2.4.C,ACCESSORIES,checkbox 2.4.C.9,2.4.C,OTHER,checkbox +2.4.D.1,2.4.D,DROP_OFF,radiobutton +2.4.D.2,2.4.D,PICK_UP,radiobutton +2.4.D.3,2.4.D,MAIL_IN,radiobutton +3.10.A.1,3.10.A,FURNITURE,checkbox +3.10.A.2,3.10.A,MAJOR_APPLIANCES,checkbox +3.10.A.3,3.10.A,SMALL_ELECTRONICS,checkbox +3.10.A.4,3.10.A,KITCHENWARE_COOKWARE,checkbox +3.10.A.5,3.10.A,GARDENING_OUTDOOR_EQUIPMENT,checkbox +3.10.A.6,3.10.A,OTHER,checkbox +3.10.B.1,3.10.B,PRICING_VALUATION_GUIDANCE,checkbox +3.10.B.2,3.10.B,BEST_SELLING_PLATFORM,checkbox +3.10.B.3,3.10.B,LISTING_CREATION_PHOTO_TAKING,checkbox +3.10.B.4,3.10.B,BUYER_COMMUNICATION_SAFETY,checkbox +3.10.C.1,3.10.C,NEW_WITH_TAGS,checkbox +3.10.C.2,3.10.C,GENTLY_USED_GOOD_CONDITION,checkbox +3.10.C.3,3.10.C,USED_WEAR_AND_TEAR,checkbox +3.10.C.4,3.10.C,NEEDS_REPAIR,checkbox +3.10.D.1,3.10.D,MUST_GO_IMMEDIATELY,textbox +3.10.D.2,3.10.D,WITHIN_1_MONTH,textbox +3.10.D.3,3.10.D,FLEXIBLE,textbox 3.1.A.1,3.1.A,LEASE_REVIEW_PRE_SIGNING,radiobutton 3.1.A.2,3.1.A,LEASE_INTERPRETATION_POST_SIGNING,radiobutton 3.1.A.3,3.1.A,LEASE_TERMINATION_BREAK_CLAUSE_REVIEW,radiobutton @@ -145,17 +165,21 @@ 3.2.C.3,3.2.C,COMMUNICATION_LOGS,checkbox 3.2.C.4,3.2.C,PHOTOS_VIDEOS_OF_ISSUE,checkbox 3.2.C.5,3.2.C,NO_DOCUMENTS_AVAILABLE,checkbox +3.2.E.1,3.2.E,IMMEDIATE_NEXT_24_TO_48_HOURS,radiobutton +3.2.E.2,3.2.E,WITHIN_1_WEEK,radiobutton +3.2.E.3,3.2.E,WITHIN_1_MONTH,radiobutton +3.2.E.4,3.2.E,FLEXIBLE,radiobutton 3.3.A.1,3.3.A,EMERGENCY_LESS_THAN_4_HOURS,radiobutton 3.3.A.2,3.3.A,URGENT_IN_24_HOURS,radiobutton 3.3.A.3,3.3.A,STANDARD_WITHIN_1_WEEK,radiobutton 3.3.A.4,3.3.A,FLEXIBLE,radiobutton -3.3.B.1,3.3.B,RENTED_LEASED_PROPERTY,radiobutton -3.3.B.2,3.3.B,PERSONAL_ITEM_OWNER_RESPONSIBILITY,radiobutton -3.3.C.1,3.3.C,WEEKDAY_MORNINGS,checkbox -3.3.C.2,3.3.C,WEEKDAY_AFTERNOONS,checkbox -3.3.C.3,3.3.C,EVENINGS,checkbox -3.3.C.4,3.3.C,WEEKENDS,checkbox +3.3.B.1,3.3.B,WEEKDAY_MORNINGS,checkbox +3.3.B.2,3.3.B,WEEKDAY_AFTERNOONS,checkbox +3.3.B.3,3.3.B,EVENINGS,checkbox +3.3.B.4,3.3.B,WEEKENDS,checkbox 3.4.A.1,3.4.A,UTILITY_CONNECTION,checkbox +3.4.A.10,3.4.A,GARDEN_CARE,checkbox +3.4.A.11,3.4.A,OTHER,checkbox 3.4.A.2,3.4.A,INTERNET_SETUP,checkbox 3.4.A.3,3.4.A,CABLE_SETUP,checkbox 3.4.A.4,3.4.A,PHONE_SETUP,checkbox @@ -164,8 +188,6 @@ 3.4.A.7,3.4.A,FURNITURE_ASSEMBLY_SETUP,checkbox 3.4.A.8,3.4.A,HOUSEHOLD_GOODS,checkbox 3.4.A.9,3.4.A,GENERAL_OUTDOOR_MAINTENANCE,checkbox -3.4.A.10,3.4.A,GARDEN_CARE,checkbox -3.4.A.11,3.4.A,OTHER,checkbox 3.4.B.1,3.4.B,AVAILABLE_AT_LOCATION,radiobutton 3.4.B.2,3.4.B,BEFORE_MOVE_IN,radiobutton 3.4.B.3,3.4.B,POST_MOVE_IN,radiobutton @@ -215,6 +237,8 @@ 3.6.I.1,3.6.I,MEN,radiobutton 3.6.I.2,3.6.I,WOMEN,radiobutton 3.6.I.3,3.6.I,UNISEX,radiobutton +3.6.J.1,3.6.J,MIN_AGE,integer +3.6.J.2,3.6.J,MAX_AGE,integer 3.6.K.1,3.6.K,PET_FRIENDLY,checkbox 3.6.K.2,3.6.K,NON_SMOKING,checkbox 3.7.A.1,3.7.A,PACKING_UNPACKING,checkbox @@ -238,39 +262,28 @@ 3.8.C.2,3.8.C,SMALL_STUDIO_ROOM,textbox 3.8.C.3,3.8.C,MEDIUM_1_BEDROOM,textbox 3.8.C.4,3.8.C,LARGE_2_MORE_BEDROOM,textbox +3.8.D.1,3.8.D,MINIMUM_BUDGET,currency +3.8.D.2,3.8.D,MAXIMUM_BUDGET,currency 3.9.A.1,3.9.A,FURNITURE,checkbox 3.9.A.2,3.9.A,MAJOR_APPLIANCES,checkbox 3.9.A.3,3.9.A,SMALL_ELECTRONICS,checkbox 3.9.A.4,3.9.A,KITCHENWARE_COOKWARE,checkbox 3.9.A.5,3.9.A,GARDENING_OUTDOOR_EQUIPMENT,checkbox 3.9.A.6,3.9.A,OTHER,checkbox -3.9.B.1,3.9.B,NEW_ITEMS_ONLY,checkbox -3.9.B.2,3.9.B,USED_SECOND_HAND,checkbox -3.9.B.3,3.9.B,REPAIR_REFURBISHING_GUIDANCE,checkbox -3.9.B.4,3.9.B,BUDGET_FRIENDLY_OPTIONS,checkbox +3.9.B.1,3.9.B,VALUATION_GUIDANCE,checkbox +3.9.B.2,3.9.B,CHOOSE_BEST_SELL_PLATFORM,checkbox +3.9.B.3,3.9.B,CREATE_LISTING,checkbox +3.9.B.4,3.9.B,BUYER_COMMUNICATION,checkbox 3.9.C.1,3.9.C,MINIMUM_BUDGET,currency 3.9.C.2,3.9.C,MAXIMUM_BUDGET,currency 3.9.E.1,3.9.E,IMMEDIATE_NEXT_48_HOURS,radiobutton 3.9.E.2,3.9.E,WITHIN_1_WEEK,radiobutton 3.9.E.3,3.9.E,WITHIN_1_MONTH,radiobutton 3.9.E.4,3.9.E,FLEXIBLE,radiobutton -3.10.A.1,3.10.A,FURNITURE,checkbox -3.10.A.2,3.10.A,MAJOR_APPLIANCES,checkbox -3.10.A.3,3.10.A,SMALL_ELECTRONICS,checkbox -3.10.A.4,3.10.A,KITCHENWARE_COOKWARE,checkbox -3.10.A.5,3.10.A,GARDENING_OUTDOOR_EQUIPMENT,checkbox -3.10.A.6,3.10.A,OTHER,checkbox -3.10.B.1,3.10.B,PRICING_VALUATION_GUIDANCE,checkbox -3.10.B.2,3.10.B,BEST_SELLING_PLATFORM,checkbox -3.10.B.3,3.10.B,LISTING_CREATION_PHOTO_TAKING,checkbox -3.10.B.4,3.10.B,BUYER_COMMUNICATION_SAFETY,checkbox -3.10.C.1,3.10.C,NEW_WITH_TAGS,checkbox -3.10.C.2,3.10.C,GENTLY_USED_GOOD_CONDITION,checkbox -3.10.C.3,3.10.C,USED_WEAR_AND_TEAR,checkbox -3.10.C.4,3.10.C,NEEDS_REPAIR,checkbox -3.10.D.1,3.10.D,MUST_GO_IMMEDIATELY,textbox -3.10.D.2,3.10.D,WITHIN_1_MONTH,textbox -3.10.D.3,3.10.D,FLEXIBLE,textbox +3.9.F.1,3.9.F,NEW_ITEMS_ONLY,radiobutton +3.9.F.2,3.9.F,USED,radiobutton +3.9.F.3,3.9.F,REPAIR_OR_REFURBISING,radiobutton +3.9.F.4,3.9.F,BUDGET_FRIENDLY_OPTIONS,radiobutton 4.1.A.1,4.1.A,APPLICATION_FORM_GUIDANCE,checkbox 4.1.A.2,4.1.A,COMMON_APP_OR_COALITION APP_HELP,checkbox 4.1.A.3,4.1.A,RESUME_BUILDING,checkbox @@ -345,6 +358,7 @@ 5.2.B.1,5.2.B,PRESCRIBED,radiobutton 5.2.B.2,5.2.B,NON_PRESCRIBED,radiobutton 5.2.C.1,5.2.C,PAIN_RELIEF,checkbox +5.2.C.10,5.2.C,OTHER,checkbox 5.2.C.2,5.2.C,COLD_FLU_CARE,checkbox 5.2.C.3,5.2.C,ALLERGY_RELIEF,checkbox 5.2.C.4,5.2.C,DIGESTIVE_HEALTH,checkbox @@ -353,7 +367,6 @@ 5.2.C.7,5.2.C,SKIN_CARE_TOPICALS,checkbox 5.2.C.8,5.2.C,WOMEN_MEN_HEALTH,checkbox 5.2.C.9,5.2.C,CHILDREN_HEALTH,checkbox -5.2.C.10,5.2.C,OTHER,checkbox 5.2.D.1,5.2.D,SAME_NEXT_DAY,radiobutton 5.2.D.2,5.2.D,3 _4_DAYS,radiobutton 5.2.D.3,5.2.D,WITHIN_A_WEEK,radiobutton @@ -417,7 +430,6 @@ 6.2.A.1,6.2.A,APP_NAME,textbox 6.2.A.2,6.2.A,TYPE_OF_DEVICE,textbox 6.2.A.3,6.2.A,OPERATING_SYSTEM,textbox -6.2.A.4,6.2.A,DESCRIPTION_OF_ISSUE,textbox 6.3.A.1,6.3.A,NUMBER_OF_MEDICATIONS,integer 6.3.A.2,6.3.A,TIMING_PER_DAY,integer 6.3.C.1,6.3.C,PHONE_CALL,radiobutton @@ -474,3 +486,5 @@ 6.9.D.1,6.9.D,ONE_TIME,radiobutton 6.9.D.2,6.9.D,WEEKLY_MONTHLY,radiobutton 6.9.D.3,6.9.D,SPECIFIC_DATES,radiobutton + + diff --git a/dml/Populating Data Files/req_add_info_metadata.csv b/dml/Populating Data Files/req_add_info_metadata.csv index f40b538..a1e2b56 100644 --- a/dml/Populating Data Files/req_add_info_metadata.csv +++ b/dml/Populating Data Files/req_add_info_metadata.csv @@ -1,4 +1,4 @@ -field_id,field_name_key,field_type,status,cat_id +field_id,field_name_key,field_type,status,cat_id 1.1.A,PREFERRED_MEAL_TYPE,list,active,1.1 1.1.B,DIETARY_RESTRICTIONS,list,active,1.1 1.1.C,HOUSEHOLD_SIZE,int,active,1.1 @@ -6,10 +6,10 @@ 1.2.B,DELIVERY_TIME,list,active,1.2 1.2.C,PAYMENT_METHOD,list,active,1.2 1.2.D,URGENCY_TIMELINE,list,active,1.2 -1.2.E,SPECIAL_NOTES,textbox,active,1.2 1.3.A,RECIPE_PREFERENCE,list,active,1.3 1.3.B,KITCHEN_EQUIPMENT,list,active,1.3 1.3.C,URGENCY_TIMELINE,list,active,1.3 +1.3.D,PREFERRED_LANGUGAE,textbox,active,1.3 2.1.A,GENDER_CATEGORY,list,active,2.1 2.1.B,TYPE_OF_CLOTHING,list,active,2.1 2.1.C,SIZE,list,active,2.1 @@ -32,15 +32,21 @@ 2.4.A,GENDER_CATEGORY,list,active,2.4 2.4.B,TYPE_OF_CLOTHING,list,active,2.4 2.4.C,GARMENT_TYPE,list,active,2.4 +2.4.D,PREFERRED_METHOD,list,active,2.4 +3.10.A,ITEM_CATEGORY,list,active,3.10 +3.10.B,AREA_OF_SUPPORT,list,active,3.10 +3.10.C,ITEM_CONDITION,list,active,3.10 +3.10.D,SALE_TIMELINE,list,active,3.10 3.1.A,AREA_OF_HELP,list,active,3.1 3.1.B,LANGUAGE_DOC_TO_REVIEW,list,active,3.1 3.1.C,URGENCY_TIMELINE,list,active,3.1 3.2.A,AREA_OF_DISPUTE,list,active,3.2 3.2.B,STATUS_OF_DISPUTE,list,active,3.2 3.2.C,DOCUMENTS_AVAILABLE,list,active,3.2 +3.2.D,LANGUAGE_OF_SUPPORT,textbox,active,3.2 +3.2.E,URGENCY_TIMELINE,list,active,3.2 3.3.A,URGENCY_TIMELINE,list,active,3.3 -3.3.B,OWNERSHIP_STATUS,list,active,3.3 -3.3.C,PREFERRED_TIMELINE,list,active,3.3 +3.3.B,PREFERRED_TIMELINE,list,active,3.3 3.4.A,AREA_OF_SUPPORT,list,active,3.4 3.4.B,TIMELINE_FOR_SUPPORT,list,active,3.4 3.5.A,PROPERTY_TYPE,list,active,3.5 @@ -60,7 +66,7 @@ 3.6.G,NUMBER_OF_PEOPLE_SHARING,integer,active,3.6 3.6.H,ADDITIONAL_ROOM_CRITERIA,list,active,3.6 3.6.I,PREFERRED_GENDER,list,active,3.6 -3.6.J,PREFERRED_AGE,integer,active,3.6 +3.6.J,PREFERRED_AGE,list,active,3.6 3.6.K,PROPERTY_RULES,list,active,3.6 3.7.A,TYPE_OF_ASSISTANCE_NEEDED,list,active,3.7 3.7.B,ESTIMATED_MOVING_DATE,date&time,active,3.7 @@ -70,17 +76,14 @@ 3.8.A,SERVICE_TYPE,list,active,3.8 3.8.B,ESTIMATED_MOVING_DATE,date&time,active,3.8 3.8.C,VOLUME_OF_ITEMS_TO_MOVE,list,active,3.8 -3.8.D,BUDGET_FOR_MOVERS,currency,active,3.8 +3.8.D,BUDGET_FOR_MOVERS,list,active,3.8 3.8.E,NEED_FOR_INSURANCE_LIABILITY,checkbox,active,3.8 3.9.A,ITEM_CATEGORY,list,active,3.9 -3.9.B,PREFERENCE,list,active,3.9 +3.9.B,AREA_OF_SUPPORT,list,active,3.9 3.9.C,BUDGET_RANGE,list,active,3.9 3.9.D,NEED_FOR_LOGISTICS_TRANSPORT,checkbox,active,3.9 3.9.E,SUPPORT_TIMELINE,list,active,3.9 -3.10.A,ITEM_CATEGORY,list,active,3.10 -3.10.B,AREA_OF_SUPPORT,list,active,3.10 -3.10.C,ITEM_CONDITION,list,active,3.10 -3.10.D,SALE_TIMELINE,list,active,3.10 +3.9.F,ITEM_CONDITION,list,active,3.9 4.1.A,AREA_OF_HELP,list,active,4.1 4.2.A,DOCUMENT_TYPE,list,active,4.2 4.2.B,FEEDBACK_TYPE,list,active,4.2 @@ -91,6 +94,7 @@ 4.4.B,FIELD_OF_STUDY,textbox,active,4.4 4.4.C,FINANCIAL_NEED,checkbox,active,4.4 4.4.D,DOCUMENT_TYPE,list,active,4.4 +4.4.E,IS_SPECIAL_CATEGORY,checkbox,active,4.4 4.5.A,GROUP_TYPE,list,active,4.5 4.5.B,SUBJECT_OR_TOPIC,textbox,active,4.5 4.5.C,GROUP_SIZE,list,active,4.5 @@ -109,7 +113,7 @@ 5.3.B,PROVIDER_TYPE,list,active,5.3 5.3.C,TIMEFRAME_TIMEZONE,list,active,5.3 5.4.A,REMINDER_TYPE,list,active,5.4 -5.4.B,REMINDER_TIMES,date&time,active,5.4 +5.4.B,REMINDER_TIMES,time,active,5.4 5.4.C,REPETITION_SCHEDULE,list,active,5.4 5.4.D,DURATION,list,active,5.4 5.4.E,REMINDER_METHOD,list,active,5.4 @@ -127,6 +131,7 @@ 6.4.A,DEVICE_TYPE,list,active,6.4 6.4.B,SETUP_MODE,list,active,6.4 6.4.C,PREFERRED_TIME_SLOTS,date&time,active,6.4 +6.4.D,DEVICE_BRAND,textbox,active,6.4 6.5.A,ERRAND_TYPE,list,active,6.5 6.5.B,FREQUENCY,list,active,6.5 6.5.C,PREFERRED_TIME_SLOTS,time,active,6.5 @@ -146,4 +151,4 @@ 6.9.B,PREFERRED_LOCATION,textbox,active,6.9 6.9.C,DIETARY_PREFERENCES,list,active,6.9 6.9.D,FREQUENCY,list,active,6.9 -6.9.E,PREFERRED_TIME,date&time,active,6.9 +6.9.E,PREFERRED_TIME,time,active,6.9 diff --git a/script-library/tests/volunteer_onboarding.sql b/script-library/tests/volunteer_onboarding.sql new file mode 100644 index 0000000..a235df4 --- /dev/null +++ b/script-library/tests/volunteer_onboarding.sql @@ -0,0 +1,63 @@ +-- WRITE YOUR OWN TEST CASES AS WE HAVE THE FOREIGN KEY IMPLEMENTED +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 = 'SID-00-000-000-001'; + +-- Update the govt_id_path specifically +-- Check if path_updated_at refreshes while others remain distinct +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) +UPDATE public.volunteer_applications +SET application_status = 'IN_REVIEW', + skill_codes = '["2", "5"]', + availability = '{"days": ["Monday", "Wednesday"], "time": ["2025-12-24 23:17:20.929643"]}'::JSONB, + terms_and_conditions = TRUE +WHERE user_id = 'SID-00-000-000-001'; + +-- This executes your 'handle_volunteer_application' function +UPDATE public.volunteer_applications +SET application_status = 'ACCEPTED' +WHERE user_id = 'SID-00-000-000-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'; + +-- Use EXPLAIN to confirm the index idx_user_skills_cat_id is being used +EXPLAIN ANALYZE +SELECT user_id +FROM public.user_skills +WHERE cat_id = '5'; + +-- Search for volunteers available on Monday +SELECT user_id +FROM virginia_dev_saayam_rdbms.volunteer_details +WHERE availability_days ? 'Monday'; + +SELECT user_id +FROM public.volunteer_details +WHERE availability_times ? '2025-12-24 23:17:20.929643'; + + + diff --git a/script-library/tests/zoom_tables_test_cases.sql b/script-library/tests/zoom_tables_test_cases.sql new file mode 100644 index 0000000..7026240 --- /dev/null +++ b/script-library/tests/zoom_tables_test_cases.sql @@ -0,0 +1,106 @@ +--TEST CASE 1 +-- attempt to insert duplicate meetings +INSERT INTO meetings (meeting_id, meeting_date, start_time, end_time, cohost_id) VALUES +('MIT-00-000-000-0011', '2026-02-09', '2026-02-09 09:00:00', '2026-02-09 10:00:00', 'SID-00-000-000-001'), +('MIT-00-000-000-0011', '2026-02-07', '2026-02-07 09:00:00', '2026-02-07 10:00:00', 'SID-00-000-000-001'); + +/*ERROR: duplicate key value violates unique constraint "meetings_pk" +Key (meeting_id)=(MIT-00-000-000-0011) already exists. + +SQL state: 23505 +Detail: Key (meeting_id)=(MIT-00-000-000-0011) already exists.*/ + +-- TEST CASE 2 +-- attempt to insert cohost id that does not exist +INSERT INTO meetings (meeting_id, meeting_date, start_time, end_time, cohost_id) VALUES +('MIT-00-000-000-0013', '2026-02-09', '2026-02-09 09:00:00', '2026-02-09 10:00:00', 'SID-00-000-000-019'); + +/* OUTPUT : ERROR: insert or update on table "meetings" violates foreign key constraint "meetings_fk" +Key (cohost_id)=(SID-00-000-000-019) is not present in table "users". + +SQL state: 23503 +Detail: Key (cohost_id)=(SID-00-000-000-019) is not present in table "users". */ + +--TEST CASE 3 +-- attempt to insert a participant that does not exist in users table +INSERT INTO meeting_participants(meeting_id, participant_id) +VALUES +('MIT-00-000-000-001', 'SID-00-000-000-019'); + +/* OUTPUT :ERROR: insert or update on table "meeting_participants" violates foreign key constraint "meeting_participants_fk_two" +Key (participant_id)=(SID-00-000-000-019) is not present in table "users". + +SQL state: 23503 +Detail: Key (participant_id)=(SID-00-000-000-019) is not present in table "users". */ + +--TEST CASE 4 +-- Fetch all participants for a specific meeting_id using a JOIN. + +--BEFORE INDEX +explain analyze +SELECT mp.participant_id +FROM meeting_participants mp +JOIN meetings m +ON mp.meeting_id = m.meeting_id +WHERE mp.meeting_id = 'MIT-00-000-000-009'; +SET enable_seqscan = on; + +/*"Nested Loop (cost=0.29..16.34 rows=1 width=19) (actual time=0.057..0.059 rows=1.00 loops=1)" +" Buffers: shared hit=4" +" -> Index Scan using meeting_id_idx on meeting_participants mp (cost=0.15..8.17 rows=1 width=38) (actual time=0.044..0.044 rows=1.00 loops=1)" +" Index Cond: ((meeting_id)::text = 'MIT-00-000-000-009'::text)" +" Index Searches: 1" +" Buffers: shared hit=2" +" -> Index Only Scan using meetings_pk on meetings m (cost=0.14..8.16 rows=1 width=516) (actual time=0.011..0.012 rows=1.00 loops=1)" +" Index Cond: (meeting_id = 'MIT-00-000-000-009'::text)" +" Heap Fetches: 1" +" Index Searches: 1" +" Buffers: shared hit=2" +"Planning Time: 0.294 ms" +"Execution Time: 0.092 ms" */ + +--AFTER INDEX +explain analyze +SELECT mp.participant_id +FROM meeting_participants mp +JOIN meetings m +ON mp.meeting_id = m.meeting_id +WHERE mp.meeting_id = 'MIT-00-000-000-009'; +SET enable_seqscan = off; + +/* "Nested Loop (cost=0.29..16.34 rows=1 width=19) (actual time=0.030..0.032 rows=1.00 loops=1)" +" Buffers: shared hit=4" +" -> Index Scan using meeting_id_idx on meeting_participants mp (cost=0.15..8.17 rows=1 width=38) (actual time=0.018..0.019 rows=1.00 loops=1)" +" Index Cond: ((meeting_id)::text = 'MIT-00-000-000-009'::text)" +" Index Searches: 1" +" Buffers: shared hit=2" +" -> Index Only Scan using meetings_pk on meetings m (cost=0.14..8.16 rows=1 width=516) (actual time=0.009..0.009 rows=1.00 loops=1)" +" Index Cond: (meeting_id = 'MIT-00-000-000-009'::text)" +" Heap Fetches: 1" +" Index Searches: 1" +" Buffers: shared hit=2" +"Planning:" +" Buffers: shared hit=28" +"Planning Time: 0.668 ms" +"Execution Time: 0.055 ms"*/ + +-- TEST CASE 5 +-- Check rejection when end time is less than start time. +INSERT INTO meetings (meeting_id, meeting_date, start_time, end_time, cohost_id) VALUES +('MIT-00-000-000-0014', '2026-02-09', '2026-02-09 11:00:00', '2026-02-09 10:00:00', 'SID-00-000-000-019'); + +/* ERROR: new row for relation "meetings" violates check constraint "chk_meeting_duration" +Failing row contains (MIT-00-000-000-0014, 2026-02-09, 2026-02-09 11:00:00, 2026-02-09 10:00:00, SID-00-000-000-019). + +SQL state: 23514 +Detail: Failing row contains (MIT-00-000-000-0014, 2026-02-09, 2026-02-09 11:00:00, 2026-02-09 10:00:00, SID-00-000-000-019).*/ + +-- TEST CASE 6 +-- attempt to insert meeting_id in meeting_participants when it doesn't exist in meetings +INSERT INTO meeting_participants(meeting_id,participant_id) +VALUES('MIT-00-000-000-014', 'SID-00-000-000-520'); + +/* OUTPUT : Result: ERROR: insert or update on table "meeting_participants" violates foreign key constraint "meeting_participants_fk_one" +Key (meeting_id)=(MIT-00-000-000-014) is not present in table "meetings". +SQL state: 23503 +Detail: Key (meeting_id)=(MIT-00-000-000-014) is not present in table "meetings".*/ ALTER \ No newline at end of file