-- Phase 1 Seed Data: Persona Types, External Roles, Modules -- Run: psql $DATABASE_URL -f scripts/seed_external_role_management.sql -- ============================================ -- Persona Types -- ============================================ INSERT INTO persona_types (code, name, description) VALUES ('PROFESSIONAL', 'Professional', 'Service providers like photographers, tutors, developers'), ('COMPANY', 'Company', 'Employer/corporate accounts'), ('JOB_SEEKER', 'Job Seeker', 'Individuals seeking employment'), ('CUSTOMER', 'Customer', 'Service seekers/customers') ON CONFLICT (code) DO NOTHING; -- ============================================ -- External Roles -- ============================================ INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'COMPANY', 'Company', id, 'Employer/corporate account for posting jobs', 1 FROM persona_types WHERE code = 'COMPANY' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'JOB_SEEKER', 'Job Seeker', id, 'Individual seeking employment opportunities', 2 FROM persona_types WHERE code = 'JOB_SEEKER' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'CUSTOMER', 'Customer', id, 'Service seeker/customer', 3 FROM persona_types WHERE code = 'CUSTOMER' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'PHOTOGRAPHER', 'Photographer', id, 'Professional photographer', 10 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'MAKEUP_ARTIST', 'Makeup Artist', id, 'Professional makeup artist', 11 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'TUTOR', 'Tutor', id, 'Professional tutor/teacher', 12 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'DEVELOPER', 'Developer', id, 'Software developer', 13 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'VIDEO_EDITOR', 'Video Editor', id, 'Professional video editor', 14 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'GRAPHIC_DESIGNER', 'Graphic Designer', id, 'Professional graphic designer', 15 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'SOCIAL_MEDIA_MANAGER', 'Social Media Manager', id, 'Social media management professional', 16 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'FITNESS_TRAINER', 'Fitness Trainer', id, 'Professional fitness trainer', 17 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; INSERT INTO external_roles (role_code, role_name, persona_type_id, description, sort_order) SELECT 'CATERING_SERVICES', 'Catering Services', id, 'Catering service provider', 18 FROM persona_types WHERE code = 'PROFESSIONAL' ON CONFLICT (role_code) DO NOTHING; -- ============================================ -- Modules (23 total) -- ============================================ -- Core Shared Modules (7) INSERT INTO modules (module_key, module_name, category, description, default_route, default_sidebar_label, icon_key, is_core) VALUES ('dashboard_home', 'Dashboard Home', 'core', 'Dashboard landing page with KPIs and widgets', '/dashboard', 'My Dashboard', 'dashboard', true), ('profile', 'Profile', 'core', 'User profile management', '/profile', 'My Profile', 'user', true), ('verification', 'Verification', 'core', 'Verification status and resubmission', '/verification', 'Verification', 'shield', true), ('help_center', 'Help Center', 'core', 'FAQs and support', '/help-center', 'Help Center', 'help-circle', true), ('settings', 'Settings', 'core', 'Account settings and preferences', '/settings', 'Settings', 'settings', true), ('switch_services', 'Switch Services', 'core', 'Switch between approved roles', '/switch-services', 'Switch Services', 'refresh-cw', true), ('explore_nxtgauge', 'Explore Nxtgauge', 'core', 'Register for additional roles', '/explore', 'Explore Nxtgauge', 'compass', true) ON CONFLICT (module_key) DO NOTHING; -- Content and Identity Modules (2) INSERT INTO modules (module_key, module_name, category, description, default_route, default_sidebar_label, icon_key) VALUES ('portfolio', 'Portfolio', 'content', 'Work samples and showcase', '/portfolio', 'My Portfolio', 'image'), ('services', 'Services', 'content', 'Service offerings and pricing', '/services', 'My Services', 'briefcase') ON CONFLICT (module_key) DO NOTHING; -- Marketplace and Discovery Modules (3) INSERT INTO modules (module_key, module_name, category, description, default_route, default_sidebar_label, icon_key) VALUES ('marketplace', 'Marketplace', 'marketplace', 'Discover opportunities', '/marketplace', 'Marketplace', 'store'), ('browse_jobs', 'Browse Jobs', 'marketplace', 'Search and browse jobs', '/browse-jobs', 'Jobs', 'search'), ('saved_jobs', 'Saved Jobs', 'marketplace', 'Saved job postings', '/saved-jobs', 'Saved Jobs', 'bookmark') ON CONFLICT (module_key) DO NOTHING; -- Work and Response Modules (8) INSERT INTO modules (module_key, module_name, category, description, default_route, default_sidebar_label, icon_key) VALUES ('jobs', 'Jobs', 'work', 'Job postings management', '/jobs', 'Jobs', 'briefcase'), ('applications', 'Applications', 'work', 'Application management', '/applications', 'Applications', 'file-text'), ('my_applications', 'My Applications', 'work', 'Track submitted applications', '/my-applications', 'My Applications', 'file-text'), ('requirements', 'Requirements', 'work', 'Customer requirements', '/requirements', 'My Requirements', 'list'), ('leads', 'Leads', 'work', 'Lead management', '/leads', 'Leads', 'users'), ('my_responses', 'My Responses', 'work', 'Track service responses', '/my-responses', 'My Responses', 'send'), ('received_responses', 'Received Responses', 'work', 'View received responses', '/received-responses', 'Received Responses', 'inbox'), ('shortlisted_candidates', 'Shortlisted Candidates', 'work', 'Manage shortlisted candidates', '/shortlisted-candidates', 'Shortlisted Candidates', 'star') ON CONFLICT (module_key) DO NOTHING; INSERT INTO modules (module_key, module_name, category, description, default_route, default_sidebar_label, icon_key) VALUES ('shortlisted_responses', 'Shortlisted Responses', 'work', 'Manage shortlisted responses', '/shortlisted-responses', 'Shortlisted Responses', 'star') ON CONFLICT (module_key) DO NOTHING; -- Financial Modules (2) INSERT INTO modules (module_key, module_name, category, description, default_route, default_sidebar_label, icon_key) VALUES ('wallet', 'Wallet', 'financial', 'Earnings and payouts', '/wallet', 'Wallet', 'credit-card'), ('credits', 'Credits', 'financial', 'Credit balance and purchases', '/credits', 'Credits', 'package') ON CONFLICT (module_key) DO NOTHING; -- ============================================ -- Module Actions (Generic) -- ============================================ -- Insert generic CRUD actions for each module DO $$ DECLARE m_record RECORD; generic_actions TEXT[] := ARRAY['view', 'list', 'create', 'update', 'delete']; action_name TEXT; action_key TEXT; BEGIN FOR m_record IN SELECT id, module_key FROM modules LOOP FOREACH action_key IN ARRAY generic_actions LOOP action_name := INITCAP(action_key); -- Custom names for some actions IF action_key = 'list' THEN action_name := 'List'; END IF; IF action_key = 'create' THEN action_name := 'Create'; END IF; IF action_key = 'update' THEN action_name := 'Update'; END IF; IF action_key = 'delete' THEN action_name := 'Delete'; END IF; IF action_key = 'view' THEN action_name := 'View'; END IF; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_record.id, action_key, action_name, action_name || ' ' || m_record.module_key) ON CONFLICT (module_id, action_key) DO NOTHING; END LOOP; END LOOP; END $$; -- ============================================ -- Module Actions (Domain-Specific) -- ============================================ -- Add domain-specific actions per module DO $$ DECLARE m_id UUID; BEGIN -- dashboard_home SELECT id INTO m_id FROM modules WHERE module_key = 'dashboard_home'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'customize', 'Customize', 'Customize dashboard widgets') ON CONFLICT (module_id, action_key) DO NOTHING; -- profile SELECT id INTO m_id FROM modules WHERE module_key = 'profile'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'upload_media', 'Upload Media', 'Upload profile photos/documents'), (m_id, 'preview_profile', 'Preview Profile', 'Preview public profile') ON CONFLICT (module_id, action_key) DO NOTHING; -- portfolio SELECT id INTO m_id FROM modules WHERE module_key = 'portfolio'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'publish_item', 'Publish Item', 'Publish portfolio item'), (m_id, 'unpublish_item', 'Unpublish Item', 'Unpublish portfolio item'), (m_id, 'feature_item', 'Feature Item', 'Feature portfolio item'), (m_id, 'reorder_items', 'Reorder Items', 'Reorder portfolio items') ON CONFLICT (module_id, action_key) DO NOTHING; -- services SELECT id INTO m_id FROM modules WHERE module_key = 'services'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'activate', 'Activate', 'Activate service'), (m_id, 'deactivate', 'Deactivate', 'Deactivate service') ON CONFLICT (module_id, action_key) DO NOTHING; -- jobs SELECT id INTO m_id FROM modules WHERE module_key = 'jobs'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'publish', 'Publish', 'Publish job posting'), (m_id, 'close', 'Close', 'Close job posting'), (m_id, 'archive', 'Archive', 'Archive job posting') ON CONFLICT (module_id, action_key) DO NOTHING; -- applications SELECT id INTO m_id FROM modules WHERE module_key = 'applications'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'shortlist', 'Shortlist', 'Shortlist candidate'), (m_id, 'reject', 'Reject', 'Reject candidate'), (m_id, 'review', 'Review', 'Review application') ON CONFLICT (module_id, action_key) DO NOTHING; -- leads SELECT id INTO m_id FROM modules WHERE module_key = 'leads'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'update_status', 'Update Status', 'Update lead status'), (m_id, 'unlock_contact', 'Unlock Contact', 'Unlock contact information') ON CONFLICT (module_id, action_key) DO NOTHING; -- my_responses SELECT id INTO m_id FROM modules WHERE module_key = 'my_responses'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'withdraw', 'Withdraw', 'Withdraw response') ON CONFLICT (module_id, action_key) DO NOTHING; -- requirements SELECT id INTO m_id FROM modules WHERE module_key = 'requirements'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'publish', 'Publish', 'Publish requirement'), (m_id, 'close', 'Close', 'Close requirement'), (m_id, 'reopen', 'Reopen', 'Reopen requirement'), (m_id, 'archive', 'Archive', 'Archive requirement') ON CONFLICT (module_id, action_key) DO NOTHING; -- received_responses SELECT id INTO m_id FROM modules WHERE module_key = 'received_responses'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'shortlist', 'Shortlist', 'Shortlist response'), (m_id, 'reject', 'Reject', 'Reject response'), (m_id, 'compare', 'Compare', 'Compare responses') ON CONFLICT (module_id, action_key) DO NOTHING; -- shortlisted_responses SELECT id INTO m_id FROM modules WHERE module_key = 'shortlisted_responses'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'compare', 'Compare', 'Compare shortlisted responses') ON CONFLICT (module_id, action_key) DO NOTHING; -- shortlisted_candidates SELECT id INTO m_id FROM modules WHERE module_key = 'shortlisted_candidates'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'compare', 'Compare', 'Compare candidates') ON CONFLICT (module_id, action_key) DO NOTHING; -- browse_jobs SELECT id INTO m_id FROM modules WHERE module_key = 'browse_jobs'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'save', 'Save', 'Save job'), (m_id, 'apply', 'Apply', 'Apply to job') ON CONFLICT (module_id, action_key) DO NOTHING; -- saved_jobs SELECT id INTO m_id FROM modules WHERE module_key = 'saved_jobs'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'apply', 'Apply', 'Apply from saved jobs') ON CONFLICT (module_id, action_key) DO NOTHING; -- my_applications SELECT id INTO m_id FROM modules WHERE module_key = 'my_applications'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'withdraw', 'Withdraw', 'Withdraw application') ON CONFLICT (module_id, action_key) DO NOTHING; -- marketplace SELECT id INTO m_id FROM modules WHERE module_key = 'marketplace'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'respond', 'Respond', 'Respond to opportunity') ON CONFLICT (module_id, action_key) DO NOTHING; -- wallet SELECT id INTO m_id FROM modules WHERE module_key = 'wallet'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'request_payout', 'Request Payout', 'Request wallet payout') ON CONFLICT (module_id, action_key) DO NOTHING; -- credits SELECT id INTO m_id FROM modules WHERE module_key = 'credits'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'buy_credits', 'Buy Credits', 'Purchase credits') ON CONFLICT (module_id, action_key) DO NOTHING; -- verification SELECT id INTO m_id FROM modules WHERE module_key = 'verification'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'resubmit', 'Resubmit', 'Resubmit verification'), (m_id, 'view_status', 'View Status', 'View verification status') ON CONFLICT (module_id, action_key) DO NOTHING; -- explore_nxtgauge SELECT id INTO m_id FROM modules WHERE module_key = 'explore_nxtgauge'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'start_onboarding', 'Start Onboarding', 'Start new role onboarding'), (m_id, 'resume_onboarding', 'Resume Onboarding', 'Resume incomplete onboarding'), (m_id, 'save_draft', 'Save Draft', 'Save onboarding draft'), (m_id, 'submit_for_verification', 'Submit for Verification', 'Submit application'), (m_id, 'view_progress', 'View Progress', 'View onboarding progress') ON CONFLICT (module_id, action_key) DO NOTHING; -- switch_services SELECT id INTO m_id FROM modules WHERE module_key = 'switch_services'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'switch', 'Switch', 'Switch to another role') ON CONFLICT (module_id, action_key) DO NOTHING; -- help_center SELECT id INTO m_id FROM modules WHERE module_key = 'help_center'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'search', 'Search', 'Search help articles'), (m_id, 'ask_help', 'Ask Help', 'Ask for help') ON CONFLICT (module_id, action_key) DO NOTHING; -- settings SELECT id INTO m_id FROM modules WHERE module_key = 'settings'; INSERT INTO module_actions (module_id, action_key, action_name, description) VALUES (m_id, 'manage_sessions', 'Manage Sessions', 'Manage active sessions') ON CONFLICT (module_id, action_key) DO NOTHING; END $$; -- ============================================ -- Default Role Module Access (by Persona) -- ============================================ -- Helper function to get module id by key DO $$ DECLARE pt_rec RECORD; mod_rec RECORD; role_id UUID; mod_id UUID; sort_int INTEGER := 0; BEGIN -- PROFESSIONAL default modules (all 23) FOR pt_rec IN SELECT id FROM persona_types WHERE code = 'PROFESSIONAL' LOOP sort_int := 0; FOR mod_rec IN SELECT id, module_key FROM modules ORDER BY is_core DESC, category, module_key LOOP SELECT id INTO role_id FROM external_roles WHERE persona_type_id = pt_rec.id LIMIT 1; IF role_id IS NOT NULL THEN INSERT INTO role_module_access (external_role_id, module_id, is_enabled, is_sidebar_visible, sort_order) VALUES (role_id, mod_rec.id, true, true, sort_int) ON CONFLICT (external_role_id, module_id) DO NOTHING; sort_int := sort_int + 1; END IF; END LOOP; END LOOP; -- COMPANY default modules FOR pt_rec IN SELECT id FROM persona_types WHERE code = 'COMPANY' LOOP SELECT id INTO role_id FROM external_roles WHERE persona_type_id = pt_rec.id LIMIT 1; IF role_id IS NOT NULL THEN -- dashboard_home, profile, jobs, applications, shortlisted_candidates, credits, verification, help_center, settings, switch_services, explore_nxtgauge FOREACH mod_rec IN ARRAY ( SELECT module_key FROM modules WHERE module_key IN ( 'dashboard_home', 'profile', 'jobs', 'applications', 'shortlisted_candidates', 'credits', 'verification', 'help_center', 'settings', 'switch_services', 'explore_nxtgauge' ) ) LOOP SELECT id INTO mod_id FROM modules WHERE module_key = mod_rec; INSERT INTO role_module_access (external_role_id, module_id, is_enabled, is_sidebar_visible, sort_order) VALUES (role_id, mod_id, true, true, sort_int) ON CONFLICT (external_role_id, module_id) DO NOTHING; sort_int := sort_int + 1; END LOOP; END IF; END LOOP; -- JOB_SEEKER default modules FOR pt_rec IN SELECT id FROM persona_types WHERE code = 'JOB_SEEKER' LOOP SELECT id INTO role_id FROM external_roles WHERE persona_type_id = pt_rec.id LIMIT 1; IF role_id IS NOT NULL THEN -- dashboard_home, profile, portfolio, browse_jobs, my_applications, saved_jobs, verification, help_center, settings, switch_services, explore_nxtgauge FOREACH mod_rec IN ARRAY ( SELECT module_key FROM modules WHERE module_key IN ( 'dashboard_home', 'profile', 'portfolio', 'browse_jobs', 'my_applications', 'saved_jobs', 'verification', 'help_center', 'settings', 'switch_services', 'explore_nxtgauge' ) ) LOOP SELECT id INTO mod_id FROM modules WHERE module_key = mod_rec; INSERT INTO role_module_access (external_role_id, module_id, is_enabled, is_sidebar_visible, sort_order) VALUES (role_id, mod_id, true, true, sort_int) ON CONFLICT (external_role_id, module_id) DO NOTHING; sort_int := sort_int + 1; END LOOP; END IF; END LOOP; -- CUSTOMER default modules FOR pt_rec IN SELECT id FROM persona_types WHERE code = 'CUSTOMER' LOOP SELECT id INTO role_id FROM external_roles WHERE persona_type_id = pt_rec.id LIMIT 1; IF role_id IS NOT NULL THEN -- dashboard_home, profile, requirements, received_responses, shortlisted_responses, credits, verification, help_center, settings, switch_services, explore_nxtgauge FOREACH mod_rec IN ARRAY ( SELECT module_key FROM modules WHERE module_key IN ( 'dashboard_home', 'profile', 'requirements', 'received_responses', 'shortlisted_responses', 'credits', 'verification', 'help_center', 'settings', 'switch_services', 'explore_nxtgauge' ) ) LOOP SELECT id INTO mod_id FROM modules WHERE module_key = mod_rec; INSERT INTO role_module_access (external_role_id, module_id, is_enabled, is_sidebar_visible, sort_order) VALUES (role_id, mod_id, true, true, sort_int) ON CONFLICT (external_role_id, module_id) DO NOTHING; sort_int := sort_int + 1; END LOOP; END IF; END LOOP; END $$; -- ============================================ -- Default Role Module Permissions -- ============================================ -- Set default CRUD permissions based on persona type DO $$ DECLARE role_rec RECORD; mod_rec RECORD; role_id UUID; mod_id UUID; can_v BOOLEAN; can_l BOOLEAN; can_c BOOLEAN; can_u BOOLEAN; can_d BOOLEAN; BEGIN -- All roles get view/list on all their enabled modules by default FOR role_rec IN SELECT id, persona_type_id FROM external_roles LOOP FOR mod_rec IN SELECT module_id FROM role_module_access WHERE external_role_id = role_rec.id AND is_enabled = true LOOP role_id := role_rec.id; mod_id := mod_rec.module_id; -- Default: all get view and list can_v := true; can_l := true; can_c := false; can_u := false; can_d := false; -- Customize defaults per module IF (SELECT module_key FROM modules WHERE id = mod_id) IN ('dashboard_home', 'profile', 'portfolio', 'services', 'jobs', 'applications', 'requirements', 'leads', 'my_responses', 'received_responses', 'shortlisted_candidates', 'shortlisted_responses', 'saved_jobs', 'browse_jobs', 'my_applications') THEN can_c := true; can_u := true; END IF; IF (SELECT module_key FROM modules WHERE id = mod_id) IN ('portfolio', 'services', 'jobs', 'requirements') THEN can_d := true; END IF; INSERT INTO role_module_permissions (external_role_id, module_id, can_view, can_list, can_create, can_update, can_delete) VALUES (role_id, mod_id, can_v, can_l, can_c, can_u, can_d) ON CONFLICT (external_role_id, module_id) DO NOTHING; END LOOP; END LOOP; END $$; -- ============================================ -- Update external_roles set switch_services_enabled for roles with multiple personas per user -- (Will be enabled after user_role_applications system is in place) -- For now, keep it false UPDATE external_roles SET switch_services_enabled = false WHERE switch_services_enabled IS NULL OR switch_services_enabled = true;