nxtgauge-backend-rust/scripts/seed.sql

1031 lines
68 KiB
SQL

-- Nxtgauge Seed Script
-- Run: psql $DATABASE_URL -f scripts/seed.sql
-- Safe to re-run (uses INSERT ... ON CONFLICT DO UPDATE for configs)
-- ── 1. Roles ─────────────────────────────────────────────────────────────────
-- Internal roles
INSERT INTO roles (key, name, audience) VALUES
('SUPER_ADMIN', 'Super Admin', 'INTERNAL'),
('ADMIN', 'Admin', 'INTERNAL'),
('SUPPORT', 'Support Agent', 'INTERNAL')
ON CONFLICT (key) DO NOTHING;
-- Internal role extensions
INSERT INTO internal_roles (role_id, description)
SELECT id, 'Full system administrator with all permissions' FROM roles WHERE key = 'SUPER_ADMIN'
ON CONFLICT (role_id) DO NOTHING;
INSERT INTO internal_roles (role_id, description, can_approve_requests, can_manage_system_settings)
SELECT id, 'Standard administrator', true, true FROM roles WHERE key = 'ADMIN'
ON CONFLICT (role_id) DO NOTHING;
INSERT INTO internal_roles (role_id, description)
SELECT id, 'Customer support agent' FROM roles WHERE key = 'SUPPORT'
ON CONFLICT (role_id) DO NOTHING;
-- External roles
INSERT INTO roles (key, name, audience) VALUES
('COMPANY', 'Company', 'EXTERNAL'),
('JOB_SEEKER', 'Job Seeker', 'EXTERNAL'),
('CUSTOMER', 'Customer', 'EXTERNAL'),
('PHOTOGRAPHER', 'Photographer', 'EXTERNAL'),
('MAKEUP_ARTIST', 'Makeup Artist', 'EXTERNAL'),
('TUTOR', 'Tutor', 'EXTERNAL'),
('DEVELOPER', 'Developer', 'EXTERNAL'),
('VIDEO_EDITOR', 'Video Editor', 'EXTERNAL'),
('GRAPHIC_DESIGNER', 'Graphic Designer', 'EXTERNAL'),
('SOCIAL_MEDIA_MANAGER', 'Social Media Manager', 'EXTERNAL'),
('FITNESS_TRAINER', 'Fitness Trainer', 'EXTERNAL'),
('CATERING_SERVICES', 'Catering Services', 'EXTERNAL')
ON CONFLICT (key) DO NOTHING;
-- External role extensions
INSERT INTO external_roles (role_id)
SELECT id FROM roles WHERE audience = 'EXTERNAL'
ON CONFLICT (role_id) DO NOTHING;
-- ── 2. Super Admin User ──────────────────────────────────────────────────────
-- Default password: Admin@nxtgauge1 (bcrypt hash)
-- CHANGE THIS PASSWORD IMMEDIATELY AFTER FIRST LOGIN
DO $$
DECLARE
super_admin_role_id UUID;
admin_user_id UUID;
BEGIN
SELECT id INTO super_admin_role_id FROM roles WHERE key = 'SUPER_ADMIN';
INSERT INTO users (email, password_hash, status, role_id, first_name, last_name, email_verified)
VALUES (
'admin@nxtgauge.com',
'$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TiGniB9GSmJBGp0K7RqUi/4hY/Ii',
'ACTIVE',
super_admin_role_id,
'Super',
'Admin',
true
)
ON CONFLICT (email) DO NOTHING
RETURNING id INTO admin_user_id;
IF admin_user_id IS NOT NULL THEN
INSERT INTO user_roles (user_id, role_id, status, approved_at)
VALUES (admin_user_id, super_admin_role_id, 'APPROVED', NOW())
ON CONFLICT (user_id, role_id) DO NOTHING;
END IF;
END $$;
-- ── 3. Onboarding Configs ─────────────────────────────────────────────────────
-- Each role gets its own INSERT for clarity and maintainability.
-- Fields use "id" (not "key") to match the frontend field binding.
-- All document uploads accept PDF + images.
-- City fields are readOnly and default to "Chennai, India".
-- version = 2 to force updates on re-run.
-- CUSTOMER (14 steps: 1 service select + 9 profession-specific + 4 shared)
-- The frontend normalizeSchemaPayload() auto-adds visibleWhen to steps
-- matching /^customer_(requirements|budget)_([a-z_]+)$/.
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_service",
"title": "Select Service Category",
"fields": [
{
"id": "profession",
"label": "Service Category",
"type": "select",
"required": true,
"options": [
{"label": "Photographer", "value": "photographer"},
{"label": "Makeup Artist", "value": "makeup_artist"},
{"label": "Tutor", "value": "tutor"},
{"label": "Developer", "value": "developer"},
{"label": "Video Editor", "value": "video_editor"},
{"label": "Graphic Designer", "value": "graphic_designer"},
{"label": "Social Media Manager", "value": "social_media_manager"},
{"label": "Fitness Trainer", "value": "fitness_trainer"},
{"label": "Catering Services", "value": "catering_services"}
]
}
]
},
{
"id": "customer_requirements_photographer",
"title": "Photography Requirements",
"fields": [
{"id": "event_type", "label": "Event Type", "type": "select", "required": true,
"options": [{"label":"Wedding","value":"Wedding"},{"label":"Corporate Event","value":"Corporate Event"},{"label":"Birthday","value":"Birthday"},{"label":"Product Shoot","value":"Product Shoot"},{"label":"Portrait","value":"Portrait"}]},
{"id": "coverage_hours", "label": "Coverage Hours", "type": "number", "required": true, "placeholder": "e.g., 4", "validation": {"min": 1}},
{"id": "photo_style", "label": "Photo Style", "type": "select", "required": true,
"options": [{"label":"Traditional","value":"Traditional"},{"label":"Candid","value":"Candid"},{"label":"Cinematic","value":"Cinematic"},{"label":"Documentary","value":"Documentary"}]}
]
},
{
"id": "customer_requirements_makeup_artist",
"title": "Makeup Requirements",
"fields": [
{"id": "occasion_type", "label": "Occasion Type", "type": "select", "required": true,
"options": [{"label":"Bridal","value":"Bridal"},{"label":"Party/Guest","value":"Party/Guest"},{"label":"Photoshoot","value":"Photoshoot"},{"label":"Editorial","value":"Editorial"}]},
{"id": "people_count", "label": "Number of People", "type": "number", "required": true, "placeholder": "e.g., 2", "validation": {"min": 1}},
{"id": "skin_preferences", "label": "Skin Preferences", "type": "textarea", "placeholder": "Any allergies or specific product requests?"}
]
},
{
"id": "customer_requirements_tutor",
"title": "Tutoring Requirements",
"fields": [
{"id": "subject", "label": "Subject", "type": "text", "required": true, "placeholder": "e.g., Mathematics, Spoken English"},
{"id": "grade_level", "label": "Grade Level", "type": "select", "required": true,
"options": [{"label":"Primary","value":"Primary"},{"label":"Middle School","value":"Middle School"},{"label":"High School","value":"High School"},{"label":"College","value":"College"},{"label":"Professional","value":"Professional"}]},
{"id": "sessions_per_week", "label": "Sessions Per Week", "type": "number", "required": true, "placeholder": "e.g., 3", "validation": {"min": 1}}
]
},
{
"id": "customer_requirements_developer",
"title": "Development Requirements",
"fields": [
{"id": "project_type", "label": "Project Type", "type": "select", "required": true,
"options": [{"label":"Website","value":"Website"},{"label":"Mobile App","value":"Mobile App"},{"label":"E-commerce","value":"E-commerce"},{"label":"Custom Software","value":"Custom Software"}]},
{"id": "platform", "label": "Platform", "type": "select", "required": true,
"options": [{"label":"iOS","value":"iOS"},{"label":"Android","value":"Android"},{"label":"Web","value":"Web"},{"label":"Cross-platform","value":"Cross-platform"}]},
{"id": "feature_summary", "label": "Feature Summary", "type": "textarea", "required": true, "placeholder": "Briefly describe what the app/website should do"}
]
},
{
"id": "customer_requirements_video_editor",
"title": "Video Editing Requirements",
"fields": [
{"id": "video_type", "label": "Video Type", "type": "select", "required": true,
"options": [{"label":"YouTube Video","value":"YouTube Video"},{"label":"Instagram Reel/Shorts","value":"Instagram Reel/Shorts"},{"label":"Wedding Highlights","value":"Wedding Highlights"},{"label":"Corporate Promo","value":"Corporate Promo"}]},
{"id": "video_duration", "label": "Video Duration", "type": "select", "required": true,
"options": [{"label":"Under 1 min","value":"Under 1 min"},{"label":"1-5 mins","value":"1-5 mins"},{"label":"5-15 mins","value":"5-15 mins"},{"label":"Over 15 mins","value":"Over 15 mins"}]},
{"id": "editing_style", "label": "Editing Style", "type": "text", "required": true, "placeholder": "e.g., Fast-paced, Cinematic, Vlog style"}
]
},
{
"id": "customer_requirements_graphic_designer",
"title": "Design Requirements",
"fields": [
{"id": "design_type", "label": "Design Type", "type": "select", "required": true,
"options": [{"label":"Logo/Branding","value":"Logo/Branding"},{"label":"Social Media Posts","value":"Social Media Posts"},{"label":"UI/UX","value":"UI/UX"},{"label":"Print Media","value":"Print Media"}]},
{"id": "brand_guidelines", "label": "Brand Guidelines", "type": "select", "required": true,
"options": [{"label":"Yes - I have them","value":"Yes - I have them"},{"label":"No - Need to create them","value":"No - Need to create them"}]},
{"id": "asset_count", "label": "Asset Count", "type": "number", "required": true, "placeholder": "How many images/screens?", "validation": {"min": 1}}
]
},
{
"id": "customer_requirements_social_media_manager",
"title": "Social Media Requirements",
"fields": [
{"id": "platforms", "label": "Platforms", "type": "select", "required": true, "multiple": true,
"options": [{"label":"Instagram","value":"Instagram"},{"label":"LinkedIn","value":"LinkedIn"},{"label":"Facebook","value":"Facebook"},{"label":"X/Twitter","value":"X/Twitter"},{"label":"YouTube","value":"YouTube"}]},
{"id": "posting_frequency", "label": "Posting Frequency", "type": "select", "required": true,
"options": [{"label":"1-2 times/week","value":"1-2 times/week"},{"label":"3-4 times/week","value":"3-4 times/week"},{"label":"Daily","value":"Daily"}]},
{"id": "goal", "label": "Goal", "type": "select", "required": true,
"options": [{"label":"Brand Awareness","value":"Brand Awareness"},{"label":"Lead Generation","value":"Lead Generation"},{"label":"Sales/Conversions","value":"Sales/Conversions"},{"label":"Community Building","value":"Community Building"}]}
]
},
{
"id": "customer_requirements_fitness_trainer",
"title": "Fitness Training Requirements",
"fields": [
{"id": "fitness_goal", "label": "Fitness Goal", "type": "select", "required": true,
"options": [{"label":"Weight Loss","value":"Weight Loss"},{"label":"Muscle Gain","value":"Muscle Gain"},{"label":"Flexibility/Yoga","value":"Flexibility/Yoga"},{"label":"General Fitness","value":"General Fitness"}]},
{"id": "sessions_per_week", "label": "Sessions Per Week", "type": "number", "required": true, "placeholder": "e.g., 5", "validation": {"min": 1}},
{"id": "training_mode", "label": "Training Mode", "type": "select", "required": true,
"options": [{"label":"Online/Virtual","value":"Online/Virtual"},{"label":"In-person","value":"In-person"}]}
]
},
{
"id": "customer_requirements_catering_services",
"title": "Catering Requirements",
"fields": [
{"id": "event_size", "label": "Event Size (Guests)", "type": "number", "required": true, "placeholder": "Number of guests/plates", "validation": {"min": 1}},
{"id": "menu_preference", "label": "Menu Preference", "type": "select", "required": true,
"options": [{"label":"Pure Veg","value":"Pure Veg"},{"label":"Non-Veg","value":"Non-Veg"},{"label":"Mixed","value":"Mixed"}]},
{"id": "cuisine_type", "label": "Cuisine Type", "type": "text", "required": true, "placeholder": "e.g., South Indian, North Indian, Continental"}
]
},
{
"id": "step_3_budget_timeline",
"title": "Budget and Timeline",
"fields": [
{"id": "budget_range", "label": "Budget Range", "type": "select", "required": true,
"options": [{"label":"Under \u20b95,000","value":"Under \u20b95,000"},{"label":"\u20b95,000 - \u20b915,000","value":"\u20b95,000 - \u20b915,000"},{"label":"\u20b915,000 - \u20b950,000","value":"\u20b915,000 - \u20b950,000"},{"label":"\u20b950,000 - \u20b91,00,000","value":"\u20b950,000 - \u20b91,00,000"},{"label":"\u20b91,00,000+","value":"\u20b91,00,000+"}]},
{"id": "expected_start", "label": "Expected Start", "type": "date", "required": true},
{"id": "urgency", "label": "Urgency", "type": "select", "required": true,
"options": [{"label":"Relaxed (No strict deadline)","value":"Relaxed (No strict deadline)"},{"label":"Standard (Within a few weeks)","value":"Standard (Within a few weeks)"},{"label":"ASAP (Urgent)","value":"ASAP (Urgent)"}]}
]
},
{
"id": "step_4_location",
"title": "Location and Preference",
"fields": [
{"id": "service_mode", "label": "Service Mode", "type": "select", "required": true,
"options": [{"label":"Onsite (In-person)","value":"Onsite (In-person)"},{"label":"Remote (Online)","value":"Remote (Online)"},{"label":"Hybrid (Mix of both)","value":"Hybrid (Mix of both)"}]},
{"id": "address_line", "label": "Address Line", "type": "text", "required": true, "placeholder": "Street address, Landmark"},
{"id": "service_city", "label": "Service City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"},
{"id": "pin_code", "label": "PIN Code", "type": "text", "required": true, "placeholder": "e.g., 600001", "validation": {"pattern": "^[0-9]{6}$", "minLength": 6, "maxLength": 6}}
]
},
{
"id": "step_5_review",
"title": "Final Review",
"fields": [
{"id": "summary_note", "label": "Additional Instructions", "type": "textarea", "placeholder": "Any additional instructions or context?"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'CUSTOMER'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- COMPANY (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_identity",
"title": "Company Identity",
"fields": [
{"id": "company_name", "label": "Company Name", "type": "text", "required": true, "placeholder": "Your registered company name"},
{"id": "legal_name", "label": "Legal Name", "type": "text", "required": true, "placeholder": "As per registration documents"},
{"id": "industry", "label": "Industry", "type": "select", "required": true,
"options": [{"label":"IT/Software","value":"IT/Software"},{"label":"Marketing/Advertising","value":"Marketing/Advertising"},{"label":"EdTech","value":"EdTech"},{"label":"Media/Entertainment","value":"Media/Entertainment"},{"label":"Health/Wellness","value":"Health/Wellness"},{"label":"Food/Beverage","value":"Food/Beverage"},{"label":"Other","value":"Other"}]}
]
},
{
"id": "step_2_contact",
"title": "Contact Details",
"fields": [
{"id": "contact_name", "label": "Contact Person Name", "type": "text", "required": true, "placeholder": "HR Manager or Founder"},
{"id": "contact_email", "label": "Contact Email", "type": "email", "required": true, "placeholder": "hr@yourcompany.com"},
{"id": "contact_phone", "label": "Contact Phone", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}}
]
},
{
"id": "step_3_presence",
"title": "Company Presence",
"fields": [
{"id": "website", "label": "Website URL", "type": "url", "required": false, "placeholder": "https://yourcompany.com"},
{"id": "hq_city", "label": "HQ City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"},
{"id": "team_size", "label": "Team Size", "type": "select", "required": true,
"options": [{"label":"1-10","value":"1-10"},{"label":"11-50","value":"11-50"},{"label":"51-200","value":"51-200"},{"label":"200+","value":"200+"}]}
]
},
{
"id": "step_4_hiring",
"title": "Hiring Preferences",
"fields": [
{"id": "hiring_for", "label": "Currently Hiring For", "type": "text", "required": true, "placeholder": "e.g., Frontend Developer, Sales Executive"},
{"id": "work_mode", "label": "Work Mode", "type": "select", "required": true,
"options": [{"label":"Onsite (Work from office)","value":"Onsite"},{"label":"Remote (Work from home)","value":"Remote"},{"label":"Hybrid","value":"Hybrid"}]},
{"id": "monthly_openings", "label": "Monthly Openings", "type": "number", "required": true, "placeholder": "Expected number of hires/month", "validation": {"min": 1}}
]
},
{
"id": "step_5_compliance",
"title": "Verification and Compliance",
"fields": [
{"id": "registration_number", "label": "Company Registration Number", "type": "text", "required": true, "placeholder": "CIN / MSME / GST Number"},
{"id": "official_email", "label": "Official Email", "type": "email", "required": true, "placeholder": "official@yourcompany.com"}
]
},
{
"id": "step_6_business_verification",
"title": "Business Verification",
"fields": [
{"id": "company_doc_type", "label": "Document Type", "type": "select", "required": true,
"options": [{"label":"GST Certificate","value":"GST Certificate"},{"label":"Certificate of Incorporation","value":"Certificate of Incorporation"},{"label":"MSME/Udyam Registration","value":"MSME/Udyam Registration"},{"label":"Company PAN Card","value":"Company PAN Card"}]},
{"id": "company_doc_upload", "label": "Upload Company Document", "type": "file", "required": true, "multiple": false, "maxFiles": 1, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'COMPANY'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- JOB_SEEKER (5 steps — NO resume upload to prevent phone number exposure)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_basic",
"title": "Basic Profile",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"},
{"id": "skills", "label": "Key Skills", "type": "text", "required": true, "placeholder": "e.g., JavaScript, React, Node.js (comma-separated)"}
]
},
{
"id": "step_2_preferences",
"title": "Job Preferences",
"fields": [
{"id": "preferred_role", "label": "Preferred Role", "type": "text", "required": true, "placeholder": "e.g., Frontend Developer"},
{"id": "expected_salary", "label": "Expected Salary (LPA)", "type": "number", "required": true, "placeholder": "Annual salary in Lakhs", "validation": {"min": 0}},
{"id": "work_mode", "label": "Work Mode", "type": "select", "required": true,
"options": [{"label":"Onsite","value":"Onsite"},{"label":"Remote","value":"Remote"},{"label":"Hybrid","value":"Hybrid"}]}
]
},
{
"id": "step_3_experience",
"title": "Experience Details",
"fields": [
{"id": "experience_years", "label": "Years of Experience", "type": "number", "required": true, "placeholder": "0 for freshers", "validation": {"min": 0}},
{"id": "latest_company", "label": "Latest/Current Company", "type": "text", "required": false, "placeholder": "Company name or 'Fresher'"},
{"id": "notice_period", "label": "Notice Period", "type": "select", "required": true,
"options": [{"label":"Immediate","value":"Immediate"},{"label":"15 Days","value":"15 Days"},{"label":"30 Days","value":"30 Days"},{"label":"60 Days","value":"60 Days"},{"label":"90 Days","value":"90 Days"}]}
]
},
{
"id": "step_4_review",
"title": "About Me",
"fields": [
{"id": "about_me", "label": "About Me", "type": "textarea", "required": true, "placeholder": "Tell companies about yourself, your strengths, and career goals"},
{"id": "linkedin_url","label": "LinkedIn URL", "type": "url", "required": false, "placeholder": "https://linkedin.com/in/yourprofile"}
]
},
{
"id": "step_5_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'JOB_SEEKER'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- PHOTOGRAPHER (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "experience", "label": "Experience (Years)","type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Hi, I am a photographer specializing in..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Photography Specialization",
"fields": [
{"id": "specialty", "label": "Specialty", "type": "select", "required": true,
"options": [{"label":"Wedding","value":"Wedding"},{"label":"Portrait","value":"Portrait"},{"label":"Product/Commercial","value":"Product/Commercial"},{"label":"Events","value":"Events"},{"label":"Real Estate","value":"Real Estate"},{"label":"Fashion/Editorial","value":"Fashion/Editorial"}]},
{"id": "camera_equipment", "label": "Camera Equipment", "type": "text", "required": true, "placeholder": "e.g., Canon EOS R5, Sony A7 III"},
{"id": "editing_software", "label": "Editing Software", "type": "select", "required": true,
"options": [{"label":"Adobe Lightroom","value":"Adobe Lightroom"},{"label":"Adobe Photoshop","value":"Adobe Photoshop"},{"label":"Capture One","value":"Capture One"},{"label":"Other","value":"Other"}]}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Hourly","value":"Hourly"},{"label":"Per Session/Event","value":"Per Session/Event"},{"label":"Per Project","value":"Per Project"},{"label":"Custom Package","value":"Custom Package"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)","type": "number", "required": true, "placeholder": "Starting price in INR", "validation": {"min": 0}},
{"id": "availability", "label": "Availability", "type": "select", "required": true,
"options": [{"label":"Weekdays","value":"Weekdays"},{"label":"Weekends","value":"Weekends"},{"label":"All Days","value":"All Days"},{"label":"By Appointment","value":"By Appointment"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Portfolio",
"fields": [
{"id": "portfolio_images", "label": "Portfolio Images (up to 6)", "type": "file", "required": true, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload up to 6 images, max 2MB each. Displayed in 3\u00d72 grid."},
{"id": "portfolio_url", "label": "External Portfolio URL", "type": "url", "required": false, "placeholder": "Instagram, website, or Behance link"},
{"id": "portfolio_note", "label": "Portfolio Note", "type": "textarea", "placeholder": "Describe your style and best work"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'PHOTOGRAPHER'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- MAKEUP_ARTIST (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "experience", "label": "Experience (Years)", "type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Hi, I am a makeup artist specializing in..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Makeup Specialization",
"fields": [
{"id": "makeup_specialty", "label": "Makeup Specialty", "type": "select", "required": true,
"options": [{"label":"Bridal","value":"Bridal"},{"label":"Editorial/Fashion","value":"Editorial/Fashion"},{"label":"Film/TV","value":"Film/TV"},{"label":"Special Effects","value":"Special Effects"},{"label":"Party/Events","value":"Party/Events"}]},
{"id": "preferred_brands", "label": "Preferred Brands", "type": "text", "required": true, "placeholder": "e.g., MAC, Huda Beauty, Kryolan"},
{"id": "services_offered", "label": "Services Offered", "type": "select", "required": true, "multiple": true,
"options": [{"label":"Bridal Makeup","value":"Bridal Makeup"},{"label":"Party Makeup","value":"Party Makeup"},{"label":"Photoshoot Makeup","value":"Photoshoot Makeup"},{"label":"Grooming","value":"Grooming"},{"label":"Airbrush Makeup","value":"Airbrush Makeup"}]}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Per Session","value":"Per Session"},{"label":"Per Person","value":"Per Person"},{"label":"Package-based","value":"Package-based"},{"label":"Custom","value":"Custom"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)", "type": "number", "required": true, "placeholder": "Starting price in INR", "validation": {"min": 0}},
{"id": "availability", "label": "Availability", "type": "select", "required": true,
"options": [{"label":"Weekdays","value":"Weekdays"},{"label":"Weekends","value":"Weekends"},{"label":"All Days","value":"All Days"},{"label":"By Appointment","value":"By Appointment"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Portfolio",
"fields": [
{"id": "portfolio_images", "label": "Portfolio Images (up to 6)", "type": "file", "required": true, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload up to 6 images, max 2MB each. Displayed in 3\u00d72 grid."},
{"id": "portfolio_url", "label": "External Portfolio URL", "type": "url", "required": false, "placeholder": "Instagram or website link"},
{"id": "portfolio_note", "label": "Portfolio Note", "type": "textarea", "placeholder": "Describe your style and best work"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'MAKEUP_ARTIST'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- TUTOR (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "experience", "label": "Experience (Years)", "type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Hi, I am a tutor specializing in..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Teaching Specialization",
"fields": [
{"id": "subjects", "label": "Subjects", "type": "text", "required": true, "placeholder": "e.g., Mathematics, Physics, Spoken English"},
{"id": "grade_levels", "label": "Grade Levels", "type": "select", "required": true, "multiple": true,
"options": [{"label":"Primary (1-5)","value":"Primary"},{"label":"Middle School (6-8)","value":"Middle School"},{"label":"High School (9-12)","value":"High School"},{"label":"College","value":"College"},{"label":"Professional/Adult","value":"Professional"}]},
{"id": "teaching_mode", "label": "Teaching Mode", "type": "select", "required": true,
"options": [{"label":"Online","value":"Online"},{"label":"Offline (Home visits)","value":"Offline"},{"label":"Hybrid","value":"Hybrid"}]}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Per Hour","value":"Per Hour"},{"label":"Per Session","value":"Per Session"},{"label":"Monthly Package","value":"Monthly Package"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)", "type": "number", "required": true, "placeholder": "Starting price in INR", "validation": {"min": 0}},
{"id": "availability", "label": "Availability", "type": "select", "required": true,
"options": [{"label":"Weekdays","value":"Weekdays"},{"label":"Weekends","value":"Weekends"},{"label":"All Days","value":"All Days"},{"label":"By Appointment","value":"By Appointment"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Credentials and Work Samples",
"fields": [
{"id": "portfolio_images", "label": "Certificates / Work Samples (up to 6)", "type": "file", "required": false, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload certificates or student work samples, max 2MB each."},
{"id": "portfolio_url", "label": "Online Profile or Course Link", "type": "url", "required": false, "placeholder": "LinkedIn, Vedantu, or website link"},
{"id": "portfolio_note", "label": "Teaching Approach", "type": "textarea", "placeholder": "Describe your teaching style and methodology"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'TUTOR'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- DEVELOPER (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "experience", "label": "Experience (Years)", "type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Hi, I am a developer specializing in..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Development Specialization",
"fields": [
{"id": "developer_type", "label": "Developer Type", "type": "select", "required": true,
"options": [{"label":"Frontend","value":"Frontend"},{"label":"Backend","value":"Backend"},{"label":"Full-stack","value":"Full-stack"},{"label":"Mobile (iOS/Android)","value":"Mobile"},{"label":"DevOps/Cloud","value":"DevOps"}]},
{"id": "tech_stack", "label": "Tech Stack", "type": "text", "required": true, "placeholder": "e.g., React, Node.js, PostgreSQL, Docker"},
{"id": "open_source_profile", "label": "GitHub / Portfolio URL", "type": "url", "required": false, "placeholder": "https://github.com/yourusername"}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Hourly","value":"Hourly"},{"label":"Per Project","value":"Per Project"},{"label":"Monthly Retainer","value":"Monthly Retainer"},{"label":"Custom","value":"Custom"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)", "type": "number", "required": true, "placeholder": "Starting price in INR", "validation": {"min": 0}},
{"id": "availability", "label": "Availability", "type": "select", "required": true,
"options": [{"label":"Full-time","value":"Full-time"},{"label":"Part-time","value":"Part-time"},{"label":"Weekends Only","value":"Weekends Only"},{"label":"Flexible","value":"Flexible"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Portfolio",
"fields": [
{"id": "portfolio_images", "label": "Screenshots / Work Samples (up to 6)", "type": "file", "required": false, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload app/website screenshots, max 2MB each."},
{"id": "portfolio_url", "label": "Live Project / Portfolio URL", "type": "url", "required": false, "placeholder": "Deployed project, Behance, or GitHub Pages"},
{"id": "portfolio_note", "label": "Portfolio Note", "type": "textarea", "placeholder": "Describe your most impactful projects"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'DEVELOPER'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- VIDEO_EDITOR (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "experience", "label": "Experience (Years)", "type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Hi, I am a video editor specializing in..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Video Editing Specialization",
"fields": [
{"id": "editing_software", "label": "Primary Editing Software", "type": "select", "required": true,
"options": [{"label":"Adobe Premiere Pro","value":"Adobe Premiere Pro"},{"label":"Final Cut Pro","value":"Final Cut Pro"},{"label":"DaVinci Resolve","value":"DaVinci Resolve"},{"label":"After Effects","value":"After Effects"},{"label":"CapCut","value":"CapCut"}]},
{"id": "video_specialties", "label": "Video Specialties", "type": "select", "required": true, "multiple": true,
"options": [{"label":"YouTube Videos","value":"YouTube Videos"},{"label":"Instagram Reels/Shorts","value":"Reels/Shorts"},{"label":"Wedding Highlights","value":"Wedding Highlights"},{"label":"Corporate Promo","value":"Corporate Promo"},{"label":"Explainer/Animation","value":"Explainer"}]},
{"id": "turnaround_time", "label": "Typical Turnaround", "type": "select", "required": true,
"options": [{"label":"24-48 hours","value":"24-48 hours"},{"label":"3-5 days","value":"3-5 days"},{"label":"1-2 weeks","value":"1-2 weeks"},{"label":"Depends on project","value":"Depends"}]}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Per Video","value":"Per Video"},{"label":"Per Minute of Output","value":"Per Minute"},{"label":"Hourly","value":"Hourly"},{"label":"Monthly Retainer","value":"Monthly Retainer"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)", "type": "number", "required": true, "placeholder": "Starting price in INR", "validation": {"min": 0}},
{"id": "availability", "label": "Availability", "type": "select", "required": true,
"options": [{"label":"Full-time","value":"Full-time"},{"label":"Part-time","value":"Part-time"},{"label":"Weekends Only","value":"Weekends Only"},{"label":"Flexible","value":"Flexible"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Portfolio",
"fields": [
{"id": "portfolio_images", "label": "Work Thumbnails / Stills (up to 6)", "type": "file", "required": false, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload video thumbnails or stills, max 2MB each."},
{"id": "portfolio_url", "label": "YouTube / Vimeo Portfolio Link", "type": "url", "required": true, "placeholder": "Link to your best video work"},
{"id": "portfolio_note", "label": "Portfolio Note", "type": "textarea", "placeholder": "Describe your editing style and best projects"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'VIDEO_EDITOR'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- GRAPHIC_DESIGNER (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "experience", "label": "Experience (Years)", "type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Hi, I am a graphic designer specializing in..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Design Specialization",
"fields": [
{"id": "design_tools", "label": "Design Tools", "type": "select", "required": true, "multiple": true,
"options": [{"label":"Figma","value":"Figma"},{"label":"Adobe Illustrator","value":"Adobe Illustrator"},{"label":"Adobe Photoshop","value":"Adobe Photoshop"},{"label":"Canva Pro","value":"Canva Pro"},{"label":"Adobe InDesign","value":"Adobe InDesign"}]},
{"id": "design_specialties","label": "Design Specialties","type": "select", "required": true, "multiple": true,
"options": [{"label":"Branding/Logo","value":"Branding/Logo"},{"label":"UI/UX Design","value":"UI/UX"},{"label":"Print Media","value":"Print Media"},{"label":"Social Media Graphics","value":"Social Media"},{"label":"Motion Graphics","value":"Motion Graphics"}]},
{"id": "style_note", "label": "Design Style", "type": "text", "required": false, "placeholder": "e.g., Minimalist, Bold, Illustrative"}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Per Design/Asset","value":"Per Design"},{"label":"Per Project","value":"Per Project"},{"label":"Hourly","value":"Hourly"},{"label":"Monthly Retainer","value":"Monthly Retainer"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)", "type": "number", "required": true, "placeholder": "Starting price in INR", "validation": {"min": 0}},
{"id": "availability", "label": "Availability", "type": "select", "required": true,
"options": [{"label":"Full-time","value":"Full-time"},{"label":"Part-time","value":"Part-time"},{"label":"Weekends Only","value":"Weekends Only"},{"label":"Flexible","value":"Flexible"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Portfolio",
"fields": [
{"id": "portfolio_images", "label": "Design Samples (up to 6)", "type": "file", "required": true, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload your best design work, max 2MB each. Displayed in 3\u00d72 grid."},
{"id": "portfolio_url", "label": "Behance / Dribbble / Portfolio URL", "type": "url", "required": false, "placeholder": "https://behance.net/yourprofile"},
{"id": "portfolio_note", "label": "Portfolio Note", "type": "textarea", "placeholder": "Describe your design philosophy and best projects"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'GRAPHIC_DESIGNER'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- SOCIAL_MEDIA_MANAGER (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "experience", "label": "Experience (Years)", "type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Hi, I am a social media manager specializing in..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Social Media Specialization",
"fields": [
{"id": "platforms_managed", "label": "Platforms Managed", "type": "select", "required": true, "multiple": true,
"options": [{"label":"Instagram","value":"Instagram"},{"label":"LinkedIn","value":"LinkedIn"},{"label":"Facebook","value":"Facebook"},{"label":"X/Twitter","value":"X/Twitter"},{"label":"YouTube","value":"YouTube"},{"label":"Pinterest","value":"Pinterest"}]},
{"id": "content_types", "label": "Content Types", "type": "select", "required": true, "multiple": true,
"options": [{"label":"Graphics/Creatives","value":"Graphics"},{"label":"Reels/Short Videos","value":"Reels"},{"label":"Copywriting/Captions","value":"Copywriting"},{"label":"Stories","value":"Stories"},{"label":"Analytics & Reports","value":"Analytics"}]},
{"id": "tools_used", "label": "Tools Used", "type": "text", "required": true, "placeholder": "e.g., Canva, Hootsuite, Buffer, Meta Business Suite"}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Monthly Retainer","value":"Monthly Retainer"},{"label":"Per Platform","value":"Per Platform"},{"label":"Per Post","value":"Per Post"},{"label":"Custom Package","value":"Custom Package"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)", "type": "number", "required": true, "placeholder": "Starting price in INR", "validation": {"min": 0}},
{"id": "availability", "label": "Availability", "type": "select", "required": true,
"options": [{"label":"Full-time","value":"Full-time"},{"label":"Part-time","value":"Part-time"},{"label":"Flexible","value":"Flexible"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Portfolio",
"fields": [
{"id": "portfolio_images", "label": "Content Samples (up to 6)", "type": "file", "required": true, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload posts, stories, or analytics screenshots, max 2MB each."},
{"id": "portfolio_url", "label": "Sample Brand Account URL", "type": "url", "required": false, "placeholder": "Instagram/LinkedIn page you manage"},
{"id": "portfolio_note", "label": "Portfolio Note", "type": "textarea", "placeholder": "Describe brands you have worked with and results achieved"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'SOCIAL_MEDIA_MANAGER'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- FITNESS_TRAINER (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name", "type": "text", "required": true, "placeholder": "Your full name"},
{"id": "experience", "label": "Experience (Years)", "type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Hi, I am a fitness trainer specializing in..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Training Specialization",
"fields": [
{"id": "training_specialties", "label": "Training Specialties", "type": "select", "required": true, "multiple": true,
"options": [{"label":"Weight Loss","value":"Weight Loss"},{"label":"Muscle Gain","value":"Muscle Gain"},{"label":"HIIT","value":"HIIT"},{"label":"Yoga/Flexibility","value":"Yoga/Flexibility"},{"label":"CrossFit","value":"CrossFit"},{"label":"Sports-specific","value":"Sports-specific"},{"label":"Rehabilitation","value":"Rehabilitation"}]},
{"id": "certifications", "label": "Certifications", "type": "text", "required": false, "placeholder": "e.g., ACE CPT, NASM CPT, RYT-200"},
{"id": "training_mode", "label": "Training Mode", "type": "select", "required": true,
"options": [{"label":"Online/Virtual","value":"Online"},{"label":"In-person (Client's location)","value":"In-person"},{"label":"Both Online and In-person","value":"Both"}]}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Per Session","value":"Per Session"},{"label":"Monthly Package","value":"Monthly Package"},{"label":"Quarterly Package","value":"Quarterly Package"},{"label":"Custom","value":"Custom"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)", "type": "number", "required": true, "placeholder": "Starting price in INR", "validation": {"min": 0}},
{"id": "availability", "label": "Availability", "type": "select", "required": true,
"options": [{"label":"Early Morning (5-8 AM)","value":"Early Morning"},{"label":"Morning (8-12 PM)","value":"Morning"},{"label":"Evening (5-9 PM)","value":"Evening"},{"label":"Flexible","value":"Flexible"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Portfolio",
"fields": [
{"id": "portfolio_images", "label": "Transformation Photos / Certificates (up to 6)", "type": "file", "required": false, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload client transformation photos or certification images, max 2MB each."},
{"id": "portfolio_url", "label": "Instagram / YouTube Channel", "type": "url", "required": false, "placeholder": "Your fitness social media or YouTube link"},
{"id": "portfolio_note", "label": "Portfolio Note", "type": "textarea", "placeholder": "Describe your training philosophy and client success stories"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'FITNESS_TRAINER'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- CATERING_SERVICES (6 steps)
INSERT INTO onboarding_configs (role_id, schema_json, version, is_active)
SELECT id, $json${
"steps": [
{
"id": "step_1_profile",
"title": "Profile Details",
"fields": [
{"id": "full_name", "label": "Full Name / Business Name", "type": "text", "required": true, "placeholder": "Your name or catering business name"},
{"id": "experience", "label": "Experience (Years)", "type": "number", "required": true, "validation": {"min": 0}},
{"id": "bio", "label": "Bio", "type": "textarea", "required": true, "placeholder": "Tell us about your catering business and specialties..."}
]
},
{
"id": "step_2_contact",
"title": "Contact and Location",
"fields": [
{"id": "email", "label": "Email", "type": "email", "required": true},
{"id": "phone", "label": "Phone Number", "type": "tel", "required": true, "placeholder": "10-digit mobile number", "validation": {"pattern": "^[0-9]{10}$", "minLength": 10, "maxLength": 10}},
{"id": "city", "label": "City", "type": "text", "required": true, "readOnly": true, "defaultValue": "Chennai, India"}
]
},
{
"id": "step_3_specialization",
"title": "Catering Specialization",
"fields": [
{"id": "cuisine_types", "label": "Cuisine Types", "type": "select", "required": true, "multiple": true,
"options": [{"label":"South Indian","value":"South Indian"},{"label":"North Indian","value":"North Indian"},{"label":"Continental","value":"Continental"},{"label":"Chinese","value":"Chinese"},{"label":"Fusion","value":"Fusion"},{"label":"Biryani/Mughlai","value":"Biryani/Mughlai"}]},
{"id": "dietary_options", "label": "Dietary Options", "type": "select", "required": true, "multiple": true,
"options": [{"label":"Pure Veg","value":"Pure Veg"},{"label":"Non-Veg","value":"Non-Veg"},{"label":"Vegan","value":"Vegan"},{"label":"Jain","value":"Jain"}]},
{"id": "max_capacity", "label": "Max Capacity (Plates/Guests)", "type": "number", "required": true, "placeholder": "Maximum plates per event", "validation": {"min": 1}}
]
},
{
"id": "step_4_pricing",
"title": "Pricing and Availability",
"fields": [
{"id": "pricing_model", "label": "Pricing Model", "type": "select", "required": true,
"options": [{"label":"Per Plate","value":"Per Plate"},{"label":"Per Event","value":"Per Event"},{"label":"Package-based","value":"Package-based"},{"label":"Custom Quote","value":"Custom Quote"}]},
{"id": "base_rate", "label": "Base Rate (\u20b9)", "type": "number", "required": true, "placeholder": "Starting price (e.g., per plate or per event)", "validation": {"min": 0}},
{"id": "advance_notice","label": "Advance Notice Required", "type": "select", "required": true,
"options": [{"label":"24 hours","value":"24 hours"},{"label":"2-3 days","value":"2-3 days"},{"label":"1 week","value":"1 week"},{"label":"2+ weeks","value":"2+ weeks"}]}
]
},
{
"id": "step_5_portfolio",
"title": "Portfolio",
"fields": [
{"id": "portfolio_images", "label": "Food / Event Photos (up to 6)", "type": "file", "required": true, "multiple": true, "maxFiles": 6, "accept": "image/jpeg,image/jpg,image/png,image/webp", "maxSizeMB": 2, "helperText": "Upload your best food and event photos, max 2MB each. Displayed in 3\u00d72 grid."},
{"id": "portfolio_url", "label": "Instagram / Google Business URL", "type": "url", "required": false, "placeholder": "Your food page or Google Business listing"},
{"id": "portfolio_note", "label": "Portfolio Note", "type": "textarea", "placeholder": "Describe your specialty dishes and memorable events you have catered"}
]
},
{
"id": "step_6_verification",
"title": "Identity Verification",
"fields": [
{"id": "id_type", "label": "ID Type", "type": "select", "required": true,
"options": [{"label":"Aadhaar Card","value":"Aadhaar Card"},{"label":"PAN Card","value":"PAN Card"},{"label":"Driving License","value":"Driving License"},{"label":"Voter ID","value":"Voter ID"},{"label":"Passport","value":"Passport"}]},
{"id": "id_number", "label": "ID Number", "type": "text", "required": true, "placeholder": "Enter ID Number"},
{"id": "id_document_upload", "label": "Upload ID Document", "type": "file", "required": true, "multiple": true, "maxFiles": 2, "accept": "application/pdf,image/jpeg,image/jpg,image/png", "maxSizeMB": 2}
]
}
]
}$json$::jsonb, 2, true
FROM roles WHERE key = 'CATERING_SERVICES'
ON CONFLICT (role_id) WHERE is_active DO UPDATE SET schema_json = EXCLUDED.schema_json, version = EXCLUDED.version;
-- ── 4. Default Dashboard Configs ─────────────────────────────────────────────
INSERT INTO dashboard_configs (role_id, audience, config_json, version, is_active)
SELECT r.id,
'EXTERNAL',
jsonb_build_object(
'nav', CASE r.key
WHEN 'COMPANY' THEN '[
{"key": "jobs", "label": "My Jobs", "path": "/dashboard/jobs", "icon": "briefcase"},
{"key": "applications", "label": "Applications", "path": "/dashboard/applications", "icon": "users"},
{"key": "profile", "label": "Company Profile", "path": "/dashboard/profile", "icon": "building"}
]'::jsonb
WHEN 'JOB_SEEKER' THEN '[
{"key": "browse_jobs", "label": "Browse Jobs", "path": "/dashboard/jobs", "icon": "search"},
{"key": "my_applications", "label": "My Applications", "path": "/dashboard/applications", "icon": "file-text"},
{"key": "profile", "label": "My Profile", "path": "/dashboard/profile", "icon": "user"}
]'::jsonb
WHEN 'CUSTOMER' THEN '[
{"key": "requirements", "label": "My Requirements", "path": "/dashboard/requirements", "icon": "list"},
{"key": "profile", "label": "My Profile", "path": "/dashboard/profile", "icon": "user"}
]'::jsonb
ELSE '[
{"key": "marketplace", "label": "Marketplace", "path": "/dashboard/marketplace", "icon": "store"},
{"key": "leads", "label": "My Leads", "path": "/dashboard/leads", "icon": "zap"},
{"key": "portfolio", "label": "Portfolio", "path": "/dashboard/portfolio", "icon": "image"},
{"key": "services", "label": "Services", "path": "/dashboard/services", "icon": "list"},
{"key": "wallet", "label": "Wallet", "path": "/dashboard/wallet", "icon": "wallet"},
{"key": "profile", "label": "My Profile", "path": "/dashboard/profile", "icon": "user"}
]'::jsonb
END,
'enabled_modules', CASE r.key
WHEN 'COMPANY' THEN '["jobs", "applications", "profile"]'::jsonb
WHEN 'JOB_SEEKER' THEN '["browse_jobs", "my_applications", "profile"]'::jsonb
WHEN 'CUSTOMER' THEN '["requirements", "profile"]'::jsonb
ELSE '["marketplace", "leads", "portfolio", "services", "wallet", "profile"]'::jsonb
END
),
1,
true
FROM roles r
WHERE r.audience = 'EXTERNAL'
ON CONFLICT (role_id, audience) WHERE is_active DO NOTHING;
-- ── Done ──────────────────────────────────────────────────────────────────────
SELECT 'Seed completed successfully.' AS status;