1923 lines
83 KiB
JavaScript
1923 lines
83 KiB
JavaScript
/**
|
||
* Demo dataset for the KROW Forge demo.
|
||
*
|
||
* Shapes follow the entity schemas the app was designed against, and the
|
||
* numbers are chosen so the derived dashboard figures come out to the
|
||
* reference values: 22 applicants, 5 open positions, 9 AI-scored candidates
|
||
* averaging 76, 3 hires at an average quality of 94, and a 41% standardized
|
||
* decision rate.
|
||
*/
|
||
|
||
const iso = (date) => new Date(`${date}T09:00:00.000Z`).toISOString();
|
||
|
||
/* ── Reference data ────────────────────────────────────────────────────── */
|
||
|
||
const ROLE_CATEGORIES = [
|
||
'Bartender', 'Server', 'Security', 'Chef', 'Picker', 'Host', 'Barback', 'Line Cook', 'Event Lead',
|
||
].map((name, i) => ({
|
||
id: `role_${i + 1}`,
|
||
name,
|
||
created_date: iso('2026-06-01'),
|
||
}));
|
||
|
||
const CERTIFICATIONS = [
|
||
'ServSafe', 'TIPS Certified', 'RBS Alcohol Server', 'Guard Card', 'CPR / First Aid',
|
||
'Food Handler Card', 'Forklift Operator', 'OSHA 10',
|
||
].map((name, i) => ({
|
||
id: `cert_${i + 1}`,
|
||
name,
|
||
created_date: iso('2026-06-01'),
|
||
}));
|
||
|
||
/* ── Positions ─────────────────────────────────────────────────────────── */
|
||
|
||
// created_date descending drives list order on Positions and Overview.
|
||
const JOB_POSTINGS = [
|
||
{
|
||
id: 'job_senior_server',
|
||
company: 'Fairmont San Jose',
|
||
custom_requirements: 'Fine dining or banquet service at senior level — recover a table before the client notices there was anything to recover.',
|
||
leadership_expectations: 'Set the pace for the servers on your floor',
|
||
attendance_expectations: 'Available evenings and weekends',
|
||
title: 'Senior Server – Fine Dining',
|
||
role_category: 'Server',
|
||
description:
|
||
'An advanced service role for seated fine dining events in San Jose. You carry the standard for your section, recover a table before a client notices there was anything to recover, and set the pace for the servers around you.',
|
||
responsibilities: [
|
||
'Run a section at fine dining standard without supervision',
|
||
'Recover service issues before they reach the client',
|
||
'Set timing and pace for the servers around you',
|
||
'Handle allergens and special requests accurately',
|
||
'Support the captain through arrivals, toasts and close',
|
||
],
|
||
qualifications: [
|
||
'4+ years of fine dining or banquet service',
|
||
'Verified advanced service capability',
|
||
'Comfortable as the senior server on a floor',
|
||
'Available evenings and weekends',
|
||
],
|
||
nice_to_haves: ['Wine service knowledge', 'Captain experience', 'Bilingual'],
|
||
min_experience_years: 4,
|
||
english_required: 'fluent',
|
||
certifications_required: ['Food Handler Card'],
|
||
/* What the work actually requires, in verified skill levels. This is what
|
||
the matching engine reads — see lib/skillGraph.js. Weights say which
|
||
requirement carries the role; they are normalised, so they need not total
|
||
100 to produce a meaningful percentage. */
|
||
skill_requirements: [
|
||
{ skill_id: 'server', level: 'advanced', weight: 40 },
|
||
{ skill_id: 'customer_service', level: 'intermediate', weight: 25 },
|
||
{ skill_id: 'food_safety', level: 'beginner', weight: 20 },
|
||
{ skill_id: 'leadership', level: 'beginner', weight: 15 },
|
||
],
|
||
pay_range_min: 24,
|
||
pay_range_max: 34,
|
||
location: 'San Jose, CA',
|
||
status: 'active',
|
||
ai_generated: false,
|
||
created_date: iso('2026-08-08'),
|
||
},
|
||
{
|
||
id: 'job_bartender',
|
||
company: 'Bay Event Staffing',
|
||
custom_requirements: 'Own your bar from setup to breakdown at high-volume private events.',
|
||
physical_requirements: 'Comfortable standing for a full shift',
|
||
title: 'Bartender',
|
||
role_category: 'Bartender',
|
||
skill_requirements: [
|
||
{ skill_id: 'bartending', level: 'intermediate', weight: 60 },
|
||
{ skill_id: 'customer_service', level: 'beginner', weight: 40 },
|
||
],
|
||
description:
|
||
'We are building a bench of dependable bartenders for high-volume private events across the region. You will own your bar from setup to breakdown, pour with speed and consistency, and keep guests feeling looked after even when the room is three deep.',
|
||
responsibilities: [
|
||
'Set up and break down a full service bar',
|
||
'Pour classic cocktails to spec at event pace',
|
||
'Verify guest age and refuse service responsibly',
|
||
'Track inventory and flag low stock before service',
|
||
'Keep the bar clean and compliant throughout the shift',
|
||
],
|
||
qualifications: [
|
||
'Prior bartending experience at events or in a busy venue',
|
||
'Working knowledge of classic cocktail specs',
|
||
'Comfortable standing for a full shift',
|
||
'Valid alcohol service certification',
|
||
],
|
||
nice_to_haves: ['Craft cocktail background', 'Bilingual', 'Own bar kit'],
|
||
min_experience_years: 2,
|
||
english_required: 'conversational',
|
||
certifications_required: ['TIPS Certified'],
|
||
pay_range_min: 0,
|
||
pay_range_max: 0,
|
||
location: '',
|
||
status: 'active',
|
||
ai_generated: true,
|
||
created_date: iso('2026-07-30'),
|
||
},
|
||
{
|
||
id: 'job_server_fine',
|
||
company: 'Valley Catering Co.',
|
||
custom_requirements: 'Tray service and synchronized coursing experience for seated events.',
|
||
attendance_expectations: 'Available evenings and weekends',
|
||
skill_requirements: [
|
||
{ skill_id: 'server', level: 'advanced', weight: 45 },
|
||
{ skill_id: 'customer_service', level: 'intermediate', weight: 30 },
|
||
{ skill_id: 'food_safety', level: 'beginner', weight: 25 },
|
||
],
|
||
title: 'Event Server – Fine Dining',
|
||
role_category: 'Server',
|
||
description:
|
||
'Fine dining service for seated corporate dinners and weddings in Silicon Valley. You will run synchronized courses, read a table without hovering, and hold a standard of polish that clients notice and rebook for.',
|
||
responsibilities: [
|
||
'Execute synchronized coursed service for seated events',
|
||
'Polish and set glassware, china, and flatware',
|
||
'Describe menus and handle allergen questions accurately',
|
||
'Clear and reset tables between courses discreetly',
|
||
'Support captains during guest arrivals and toasts',
|
||
],
|
||
qualifications: [
|
||
'2+ years of banquet or fine dining service',
|
||
'Tray service and synchronized coursing experience',
|
||
'Professional appearance and clear communication',
|
||
'Available evenings and weekends',
|
||
],
|
||
nice_to_haves: ['Wine service knowledge', 'Captain experience', 'Bilingual'],
|
||
min_experience_years: 2,
|
||
english_required: 'fluent',
|
||
certifications_required: ['Food Handler Card'],
|
||
pay_range_min: 18,
|
||
pay_range_max: 26,
|
||
location: 'Silicon Valley, CA',
|
||
status: 'active',
|
||
ai_generated: true,
|
||
created_date: iso('2026-07-29'),
|
||
},
|
||
{
|
||
id: 'job_security',
|
||
company: 'Legendary Event Staff',
|
||
custom_requirements: 'Valid California Guard Card on file before the first shift.',
|
||
physical_requirements: 'Able to stand and patrol for extended periods',
|
||
title: 'Event Security Officer',
|
||
role_category: 'Security',
|
||
description:
|
||
'Licensed event security for concerts, corporate activations, and private functions across Los Angeles. Presence over confrontation: you set the tone at the door and de-escalate long before anything becomes an incident.',
|
||
responsibilities: [
|
||
'Staff entry points and verify credentials',
|
||
'Conduct bag checks per venue policy',
|
||
'De-escalate guest conflicts calmly',
|
||
'Document incidents accurately and promptly',
|
||
'Coordinate with venue staff and local authorities',
|
||
],
|
||
qualifications: [
|
||
'Valid California Guard Card',
|
||
'3+ years of event or venue security experience',
|
||
'Clear incident reporting skills',
|
||
'Able to stand and patrol for extended periods',
|
||
],
|
||
nice_to_haves: ['Crowd management training', 'CPR certified', 'Bilingual'],
|
||
min_experience_years: 3,
|
||
english_required: 'conversational',
|
||
certifications_required: ['Guard Card', 'CPR / First Aid'],
|
||
pay_range_min: 20,
|
||
pay_range_max: 28,
|
||
location: 'Los Angeles, CA',
|
||
status: 'paused',
|
||
ai_generated: false,
|
||
created_date: iso('2026-07-28'),
|
||
},
|
||
{
|
||
id: 'job_chef',
|
||
company: 'Valley Catering Co.',
|
||
custom_requirements: 'Offsite and high-volume catering experience, with food cost ownership.',
|
||
leadership_expectations: 'Lead and schedule a rotating kitchen brigade',
|
||
skill_requirements: [
|
||
{ skill_id: 'food_safety', level: 'advanced', weight: 40 },
|
||
{ skill_id: 'leadership', level: 'advanced', weight: 35 },
|
||
{ skill_id: 'customer_service', level: 'beginner', weight: 25 },
|
||
],
|
||
title: 'Executive Chef – Catering',
|
||
role_category: 'Chef',
|
||
description:
|
||
'Lead the kitchen for a high-end catering operation running multiple events a week. You will design menus, cost them honestly, and run a brigade that holds quality at 400 covers the same way it does at 40.',
|
||
responsibilities: [
|
||
'Design and cost seasonal event menus',
|
||
'Lead and schedule a rotating kitchen brigade',
|
||
'Own food safety compliance across offsite kitchens',
|
||
'Manage vendor relationships and food cost targets',
|
||
'Execute tastings and client menu consultations',
|
||
],
|
||
qualifications: [
|
||
'8+ years of professional kitchen experience',
|
||
'3+ years leading a brigade at executive or sous level',
|
||
'ServSafe certification',
|
||
'Offsite and high-volume catering experience',
|
||
],
|
||
nice_to_haves: ['Culinary degree', 'Plated dinner specialization', 'Bilingual kitchen leadership'],
|
||
min_experience_years: 8,
|
||
english_required: 'fluent',
|
||
certifications_required: ['ServSafe'],
|
||
pay_range_min: 45,
|
||
pay_range_max: 70,
|
||
location: 'Bay Area, CA',
|
||
status: 'active',
|
||
ai_generated: true,
|
||
created_date: iso('2026-07-27'),
|
||
},
|
||
{
|
||
id: 'job_bartender_corp',
|
||
company: 'Bay Event Staffing',
|
||
custom_requirements: 'Corporate or executive event experience, with batched cocktail programs.',
|
||
leadership_expectations: 'Run a bar independently at corporate functions',
|
||
skill_requirements: [
|
||
{ skill_id: 'bartending', level: 'advanced', weight: 50 },
|
||
{ skill_id: 'customer_service', level: 'intermediate', weight: 30 },
|
||
{ skill_id: 'leadership', level: 'beginner', weight: 20 },
|
||
],
|
||
title: 'Experienced Bartender – Corporate Events',
|
||
role_category: 'Bartender',
|
||
description:
|
||
'Corporate hospitality bartending for tech campuses and executive functions in the Bay Area. Batch cocktails, clean presentation, and the judgment to run a bar unsupervised in front of an executive audience.',
|
||
responsibilities: [
|
||
'Build and execute batched cocktail programs',
|
||
'Run a bar independently at corporate functions',
|
||
'Maintain responsible service standards',
|
||
'Present a clean, branded bar throughout service',
|
||
'Reconcile consumption counts after service',
|
||
],
|
||
qualifications: [
|
||
'5+ years of bartending experience',
|
||
'Corporate or executive event experience',
|
||
'RBS or equivalent alcohol service certification',
|
||
'Reliable transportation across the Bay Area',
|
||
],
|
||
nice_to_haves: ['Zero-proof program experience', 'Barista skills', 'Own bar kit'],
|
||
min_experience_years: 5,
|
||
english_required: 'fluent',
|
||
certifications_required: ['RBS Alcohol Server'],
|
||
pay_range_min: 22,
|
||
pay_range_max: 32,
|
||
location: 'Bay Area, CA',
|
||
status: 'active',
|
||
ai_generated: true,
|
||
created_date: iso('2026-07-26'),
|
||
},
|
||
{
|
||
id: 'job_picker',
|
||
company: 'Oakland Event Logistics',
|
||
custom_requirements: 'Accuracy first — every mispick becomes a missing item at an event.',
|
||
physical_requirements: 'Able to lift 50 lbs repeatedly',
|
||
attendance_expectations: 'Reliable attendance for early shifts',
|
||
title: 'Picker',
|
||
role_category: 'Picker',
|
||
description:
|
||
'Warehouse order picking for an event logistics hub in Oakland. Accuracy first, speed second: every mispick becomes a missing item at someone else’s wedding.',
|
||
responsibilities: [
|
||
'Pick and stage orders against pick lists',
|
||
'Scan and verify SKUs for accuracy',
|
||
'Stage outbound pallets for event trucks',
|
||
'Report damaged inventory immediately',
|
||
'Keep aisles and staging lanes clear',
|
||
],
|
||
qualifications: [
|
||
'Warehouse or fulfillment experience',
|
||
'Able to lift 50 lbs repeatedly',
|
||
'Comfortable with handheld scanners',
|
||
'Reliable attendance for early shifts',
|
||
],
|
||
nice_to_haves: ['Forklift certified', 'Inventory system experience'],
|
||
min_experience_years: 1,
|
||
english_required: 'basic',
|
||
certifications_required: ['Forklift Operator'],
|
||
pay_range_min: 40,
|
||
pay_range_max: 45,
|
||
location: 'Oakland',
|
||
status: 'closed',
|
||
ai_generated: false,
|
||
created_date: iso('2026-07-20'),
|
||
},
|
||
{
|
||
id: 'job_banquet',
|
||
company: 'Fairmont San Jose',
|
||
custom_requirements: 'Hotel banquet background and BEO fluency.',
|
||
leadership_expectations: 'Direct a floor team you have often just met that afternoon',
|
||
attendance_expectations: 'Available for early mornings and late nights',
|
||
skill_requirements: [
|
||
{ skill_id: 'server', level: 'advanced', weight: 35 },
|
||
{ skill_id: 'leadership', level: 'intermediate', weight: 35 },
|
||
{ skill_id: 'customer_service', level: 'advanced', weight: 30 },
|
||
],
|
||
title: 'Banquet Captain – Hotel Events',
|
||
role_category: 'Server',
|
||
description:
|
||
'Captain banquet floors for hotel conferences and galas in San Jose. You are the bridge between the client, the kitchen, and a floor team you have often just met that afternoon.',
|
||
responsibilities: [
|
||
'Lead pre-shift briefings and assign sections',
|
||
'Coordinate timing between kitchen and floor',
|
||
'Be the client contact throughout the event',
|
||
'Resolve service issues without escalation',
|
||
'Close out the floor and complete event reports',
|
||
],
|
||
qualifications: [
|
||
'4+ years of banquet service, 1+ in a lead role',
|
||
'Proven ability to direct a floor team',
|
||
'Strong client-facing communication',
|
||
'Available for early mornings and late nights',
|
||
],
|
||
nice_to_haves: ['Hotel banquet background', 'BEO fluency', 'Bilingual'],
|
||
min_experience_years: 4,
|
||
english_required: 'fluent',
|
||
certifications_required: ['Food Handler Card'],
|
||
pay_range_min: 24,
|
||
pay_range_max: 34,
|
||
location: 'San Jose, CA',
|
||
status: 'active',
|
||
ai_generated: true,
|
||
created_date: iso('2026-07-18'),
|
||
},
|
||
|
||
/* ── The multi-company demand the allocation engine exists for ──────────
|
||
Three companies wanting the same skill at the same time, with different
|
||
urgency, start dates and run lengths. Total demand is 90 chefs against a
|
||
workforce that cannot cover it, which is the situation priority ordering
|
||
has to resolve — and the reason it is seeded rather than described. */
|
||
];
|
||
|
||
/* ── Applications ──────────────────────────────────────────────────────── */
|
||
|
||
const breakdown = (over) => ({
|
||
experience: 0, english: 0, reliability: 0, certifications: 0, availability: 0,
|
||
personality: 0, culture_fit: 0, communication_style: 0, attendance_expectations: 0,
|
||
physical_requirements: 0, leadership_expectations: 0, job_related_answers: 0,
|
||
verified_skills: 0, scenario_judgment: 0, employer_requirements: 0,
|
||
...over,
|
||
});
|
||
|
||
/** An applicant who has not been screened yet — every AI field stays empty. */
|
||
const unscreened = (over) => ({
|
||
status: 'applied',
|
||
ai_score: 0,
|
||
certifications: [],
|
||
availability: [],
|
||
skills: [],
|
||
companies_worked: [],
|
||
client_rating: 0,
|
||
created_date: iso('2026-08-04'),
|
||
updated_date: iso('2026-08-04'),
|
||
...over,
|
||
});
|
||
|
||
const JOB_APPLICATIONS = [
|
||
/* Senior Server – Fine Dining. Two applications with no AI screening on them
|
||
at all: what the recruiter sees for these is the skill match, computed from
|
||
verified training rather than from a model's reading of a résumé. */
|
||
{
|
||
id: 'app_arun',
|
||
applicant_name: 'Arun Kumar',
|
||
email: 'arun.kumar@example.com',
|
||
phone: '+1-408-555-0210',
|
||
years_experience: 4,
|
||
english_level: 'fluent',
|
||
certifications: ['Food Handler Card'],
|
||
availability: ['Weekdays', 'Weekends', 'Evenings'],
|
||
skills: ['Coursed service', 'Guest recovery', 'Allergen handling'],
|
||
companies_worked: ['Valley Catering Co.'],
|
||
client_rating: 4.7,
|
||
professional_summary:
|
||
'Four years of event service in San Jose, working towards the senior server role on a fine dining floor.',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=68',
|
||
job_posting_id: 'job_senior_server',
|
||
job_title: 'Senior Server – Fine Dining',
|
||
status: 'applied',
|
||
ai_score: 0,
|
||
created_date: iso('2026-08-13'),
|
||
updated_date: iso('2026-08-13'),
|
||
},
|
||
{
|
||
id: 'app_priya_nair',
|
||
applicant_name: 'Priya Nair',
|
||
email: 'priya.nair@example.com',
|
||
phone: '+1-408-555-0211',
|
||
years_experience: 2,
|
||
english_level: 'fluent',
|
||
certifications: ['Food Handler Card'],
|
||
availability: ['Weekends', 'Evenings'],
|
||
skills: ['Table service', 'Guest relations'],
|
||
companies_worked: ['Bay Event Staffing'],
|
||
client_rating: 4.5,
|
||
professional_summary: 'Two years of event service, moving towards fine dining sections.',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=47',
|
||
job_posting_id: 'job_senior_server',
|
||
job_title: 'Senior Server – Fine Dining',
|
||
status: 'applied',
|
||
ai_score: 0,
|
||
created_date: iso('2026-08-12'),
|
||
updated_date: iso('2026-08-12'),
|
||
},
|
||
|
||
/* Executive Chef – Catering: 2 applicants · 1 screened · 1 hired */
|
||
{
|
||
id: 'app_antoine',
|
||
applicant_name: 'Chef Antoine Dubois',
|
||
email: 'antoine.dubois@email.com',
|
||
phone: '+1-415-555-0101',
|
||
years_experience: 12,
|
||
english_level: 'fluent',
|
||
certifications: ['ServSafe', 'CPR / First Aid'],
|
||
availability: ['Weekdays', 'Weekends', 'Evenings'],
|
||
skills: ['Menu design', 'Brigade leadership', 'Food costing', 'Plated dinners', 'Offsite catering'],
|
||
companies_worked: [],
|
||
client_rating: 4.9,
|
||
professional_summary:
|
||
'Executive chef with 12 years across hotel banquets and high-end offsite catering. Has run brigades of 20+ and holds plate standards at 400 covers.',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=45',
|
||
job_posting_id: 'job_chef',
|
||
job_title: 'Executive Chef – Catering',
|
||
status: 'hired',
|
||
ai_score: 97,
|
||
ai_match_label: 'Excellent Match',
|
||
ai_summary:
|
||
'Exceptional fit. Twelve years of executive kitchen leadership with direct offsite catering experience and current ServSafe certification. Availability covers the full event calendar.',
|
||
ai_strengths: [
|
||
'12 years executive chef experience',
|
||
'ServSafe certified',
|
||
'Proven brigade leadership at high volume',
|
||
'Full-calendar availability',
|
||
],
|
||
ai_gaps: ['No formal culinary degree on file'],
|
||
ai_recommendation: 'Shortlisted',
|
||
score_breakdown: breakdown({
|
||
experience: 99, english: 95, reliability: 96, certifications: 98, availability: 94,
|
||
personality: 91, culture_fit: 93, communication_style: 92, attendance_expectations: 95,
|
||
physical_requirements: 90, leadership_expectations: 97, job_related_answers: 96,
|
||
verified_skills: 95, scenario_judgment: 94, employer_requirements: 98,
|
||
}),
|
||
created_date: iso('2026-07-24'),
|
||
updated_date: iso('2026-07-25'),
|
||
},
|
||
unscreened({
|
||
id: 'app_priya',
|
||
applicant_name: 'Priya Raman',
|
||
email: 'priya.raman@email.com',
|
||
phone: '+1-415-555-0110',
|
||
years_experience: 6,
|
||
english_level: 'fluent',
|
||
professional_summary: 'Sous chef moving toward executive roles in catering.',
|
||
job_posting_id: 'job_chef',
|
||
job_title: 'Executive Chef – Catering',
|
||
}),
|
||
|
||
/* Event Security Officer: 6 applicants · 2 screened · 1 hired */
|
||
{
|
||
id: 'app_marcus',
|
||
applicant_name: 'Marcus Williams',
|
||
email: 'marcus.w@email.com',
|
||
phone: '+1-415-555-0102',
|
||
years_experience: 5,
|
||
english_level: 'fluent',
|
||
certifications: ['Guard Card', 'CPR / First Aid'],
|
||
availability: ['Weekends', 'Evenings', 'Overnight'],
|
||
skills: ['Crowd management', 'De-escalation', 'Incident reporting', 'Access control'],
|
||
companies_worked: [],
|
||
client_rating: 4.8,
|
||
professional_summary:
|
||
'Licensed event security officer with five years across concerts and corporate activations. Known for defusing situations before they escalate.',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=12',
|
||
job_posting_id: 'job_security',
|
||
job_title: 'Event Security Officer',
|
||
status: 'hired',
|
||
ai_score: 94,
|
||
ai_match_label: 'Excellent Match',
|
||
ai_summary:
|
||
'Strong fit. Current Guard Card and CPR certification with five years of directly relevant event security work and overnight availability.',
|
||
ai_strengths: ['Current Guard Card', 'Five years event security', 'Documented de-escalation record'],
|
||
ai_gaps: ['No formal crowd management course on file'],
|
||
ai_recommendation: 'Shortlisted',
|
||
score_breakdown: breakdown({
|
||
experience: 92, english: 93, reliability: 95, certifications: 97, availability: 96,
|
||
personality: 90, culture_fit: 91, communication_style: 89, attendance_expectations: 96,
|
||
physical_requirements: 95, leadership_expectations: 86, job_related_answers: 93,
|
||
verified_skills: 92, scenario_judgment: 95, employer_requirements: 94,
|
||
}),
|
||
created_date: iso('2026-07-24'),
|
||
updated_date: iso('2026-07-25'),
|
||
},
|
||
{
|
||
id: 'app_dana',
|
||
applicant_name: 'Dana Whitfield',
|
||
email: 'dana.whitfield@email.com',
|
||
phone: '+1-415-555-0111',
|
||
years_experience: 4,
|
||
english_level: 'fluent',
|
||
certifications: ['Guard Card'],
|
||
availability: ['Weekends', 'Evenings'],
|
||
skills: ['Access control', 'Incident reporting'],
|
||
companies_worked: [],
|
||
client_rating: 0,
|
||
professional_summary: 'Venue security officer transitioning into private event work.',
|
||
job_posting_id: 'job_security',
|
||
job_title: 'Event Security Officer',
|
||
status: 'interview',
|
||
ai_score: 0,
|
||
interview_id: 'int_dana',
|
||
created_date: iso('2026-08-01'),
|
||
updated_date: iso('2026-08-03'),
|
||
},
|
||
unscreened({
|
||
id: 'app_omar', applicant_name: 'Omar Haddad', email: 'omar.haddad@email.com',
|
||
phone: '+1-415-555-0112', years_experience: 2, english_level: 'conversational',
|
||
job_posting_id: 'job_security', job_title: 'Event Security Officer',
|
||
}),
|
||
unscreened({
|
||
id: 'app_kevin', applicant_name: 'Kevin Boyle', email: 'kevin.boyle@email.com',
|
||
phone: '+1-415-555-0113', years_experience: 7, english_level: 'native',
|
||
job_posting_id: 'job_security', job_title: 'Event Security Officer',
|
||
}),
|
||
unscreened({
|
||
id: 'app_rosa', applicant_name: 'Rosa Delgado', email: 'rosa.delgado@email.com',
|
||
phone: '+1-415-555-0114', years_experience: 3, english_level: 'fluent',
|
||
job_posting_id: 'job_security', job_title: 'Event Security Officer',
|
||
}),
|
||
unscreened({
|
||
id: 'app_tyler', applicant_name: 'Tyler Nunez', email: 'tyler.nunez@email.com',
|
||
phone: '+1-415-555-0115', years_experience: 1, english_level: 'conversational',
|
||
job_posting_id: 'job_security', job_title: 'Event Security Officer',
|
||
}),
|
||
|
||
/* Experienced Bartender – Corporate Events: 1 applicant · 1 screened · 1 hired */
|
||
{
|
||
id: 'app_marco',
|
||
applicant_name: 'Marco Rivera',
|
||
email: 'marco.rivera@email.com',
|
||
phone: '+1-415-555-0103',
|
||
years_experience: 6,
|
||
english_level: 'fluent',
|
||
certifications: ['RBS Alcohol Server', 'TIPS Certified'],
|
||
availability: ['Weekdays', 'Evenings'],
|
||
skills: ['Batch cocktails', 'Craft cocktails', 'Bar setup', 'Inventory control'],
|
||
companies_worked: [],
|
||
client_rating: 4.7,
|
||
professional_summary:
|
||
'Corporate event bartender with six years on Bay Area tech campuses. Builds batched programs that hold quality at volume.',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=33',
|
||
job_posting_id: 'job_bartender_corp',
|
||
job_title: 'Experienced Bartender – Corporate Events',
|
||
status: 'hired',
|
||
ai_score: 92,
|
||
ai_match_label: 'Excellent Match',
|
||
ai_summary:
|
||
'Excellent fit for corporate hospitality. Six years of directly comparable work, both required certifications current, and reliable Bay Area coverage.',
|
||
ai_strengths: ['Six years corporate bartending', 'RBS and TIPS certified', 'Batch cocktail program experience'],
|
||
ai_gaps: ['Limited zero-proof program experience'],
|
||
ai_recommendation: 'Shortlisted',
|
||
score_breakdown: breakdown({
|
||
experience: 94, english: 92, reliability: 93, certifications: 96, availability: 88,
|
||
personality: 90, culture_fit: 92, communication_style: 91, attendance_expectations: 92,
|
||
physical_requirements: 89, leadership_expectations: 82, job_related_answers: 94,
|
||
verified_skills: 93, scenario_judgment: 90, employer_requirements: 93,
|
||
}),
|
||
created_date: iso('2026-07-24'),
|
||
updated_date: iso('2026-07-25'),
|
||
},
|
||
|
||
/* Event Server – Fine Dining: 3 applicants · 3 screened · 0 hired */
|
||
{
|
||
id: 'app_sofia',
|
||
applicant_name: 'Sofia Mendez',
|
||
email: 'sofia.mendez@email.com',
|
||
phone: '+1-415-555-0104',
|
||
years_experience: 4,
|
||
english_level: 'fluent',
|
||
certifications: ['Food Handler Card'],
|
||
availability: ['Weekends', 'Evenings'],
|
||
skills: ['Synchronized service', 'Tray service', 'Wine service', 'Guest relations'],
|
||
companies_worked: [],
|
||
client_rating: 4.6,
|
||
professional_summary:
|
||
'Fine dining event server with four years of coursed banquet service and wine knowledge.',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=47',
|
||
job_posting_id: 'job_server_fine',
|
||
job_title: 'Event Server – Fine Dining',
|
||
status: 'ai_screened',
|
||
ai_score: 89,
|
||
ai_match_label: 'Excellent Match',
|
||
ai_summary:
|
||
'Strong fine dining fit. Four years of coursed service with wine knowledge that exceeds the posting, and weekend availability aligned to the event calendar.',
|
||
ai_strengths: ['Four years fine dining service', 'Wine service knowledge', 'Strong guest relations'],
|
||
ai_gaps: ['No captain-level experience yet'],
|
||
ai_recommendation: 'Interview',
|
||
score_breakdown: breakdown({
|
||
experience: 88, english: 92, reliability: 90, certifications: 85, availability: 87,
|
||
personality: 91, culture_fit: 90, communication_style: 93, attendance_expectations: 89,
|
||
physical_requirements: 86, leadership_expectations: 74, job_related_answers: 90,
|
||
verified_skills: 88, scenario_judgment: 87, employer_requirements: 89,
|
||
}),
|
||
created_date: iso('2026-08-02'),
|
||
updated_date: iso('2026-08-05'),
|
||
},
|
||
{
|
||
id: 'app_tanya',
|
||
applicant_name: 'Tanya Cruz',
|
||
email: 'tanya.cruz@email.com',
|
||
phone: '+1-415-555-0105',
|
||
years_experience: 3,
|
||
english_level: 'fluent',
|
||
certifications: ['Food Handler Card'],
|
||
availability: ['Weekends'],
|
||
skills: ['Banquet service', 'Tray service', 'Table resets'],
|
||
companies_worked: [],
|
||
client_rating: 4.4,
|
||
professional_summary: 'Banquet server with three years of seated dinner service.',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=44',
|
||
job_posting_id: 'job_server_fine',
|
||
job_title: 'Event Server – Fine Dining',
|
||
status: 'interview',
|
||
ai_score: 83,
|
||
ai_match_label: 'Excellent Match',
|
||
ai_summary:
|
||
'Solid fit with room to grow. Three years of banquet service meets the requirement; weekend-only availability is the main constraint.',
|
||
ai_strengths: ['Three years banquet service', 'Reliable weekend availability', 'Clean service technique'],
|
||
ai_gaps: ['Weekend-only availability', 'No wine service training'],
|
||
ai_recommendation: 'Interview',
|
||
interview_id: 'int_tanya',
|
||
score_breakdown: breakdown({
|
||
experience: 80, english: 90, reliability: 88, certifications: 82, availability: 70,
|
||
personality: 88, culture_fit: 86, communication_style: 87, attendance_expectations: 90,
|
||
physical_requirements: 85, leadership_expectations: 68, job_related_answers: 84,
|
||
verified_skills: 81, scenario_judgment: 82, employer_requirements: 83,
|
||
}),
|
||
created_date: iso('2026-08-01'),
|
||
updated_date: iso('2026-08-05'),
|
||
},
|
||
{
|
||
id: 'app_nadia',
|
||
applicant_name: 'Nadia Petrova',
|
||
email: 'nadia.petrova@email.com',
|
||
phone: '+1-415-555-0116',
|
||
years_experience: 2,
|
||
english_level: 'conversational',
|
||
certifications: [],
|
||
availability: ['Weekends', 'Evenings'],
|
||
skills: ['Table service'],
|
||
companies_worked: [],
|
||
client_rating: 0,
|
||
professional_summary: 'Restaurant server moving into event work.',
|
||
job_posting_id: 'job_server_fine',
|
||
job_title: 'Event Server – Fine Dining',
|
||
status: 'ai_screened',
|
||
ai_score: 0,
|
||
created_date: iso('2026-08-03'),
|
||
updated_date: iso('2026-08-04'),
|
||
},
|
||
|
||
/* Bartender: 3 applicants · 3 screened · 0 hired */
|
||
{
|
||
id: 'app_jordan',
|
||
applicant_name: 'Jordan Blake',
|
||
email: 'jordan.blake@email.com',
|
||
phone: '+1-415-555-0106',
|
||
years_experience: 3,
|
||
english_level: 'fluent',
|
||
certifications: ['TIPS Certified'],
|
||
availability: ['Weekends', 'Evenings'],
|
||
skills: ['Classic cocktails', 'Bar setup', 'Speed pouring'],
|
||
companies_worked: [],
|
||
client_rating: 4.2,
|
||
professional_summary: 'Event bartender with three years of high-volume weekend service.',
|
||
job_posting_id: 'job_bartender',
|
||
job_title: 'Bartender',
|
||
status: 'interview',
|
||
ai_score: 72,
|
||
ai_match_label: 'Good Match',
|
||
ai_summary:
|
||
'Meets the core requirements. Three years of high-volume experience with current TIPS certification; cocktail range is narrower than ideal.',
|
||
ai_strengths: ['TIPS certified', 'High-volume service experience'],
|
||
ai_gaps: ['Limited classic cocktail range', 'No craft background'],
|
||
ai_recommendation: 'Interview',
|
||
interview_id: 'int_jordan',
|
||
score_breakdown: breakdown({
|
||
experience: 74, english: 85, reliability: 78, certifications: 80, availability: 82,
|
||
personality: 76, culture_fit: 74, communication_style: 78, attendance_expectations: 80,
|
||
physical_requirements: 82, leadership_expectations: 58, job_related_answers: 70,
|
||
verified_skills: 68, scenario_judgment: 72, employer_requirements: 73,
|
||
}),
|
||
created_date: iso('2026-08-01'),
|
||
updated_date: iso('2026-08-05'),
|
||
},
|
||
{
|
||
id: 'app_elena',
|
||
applicant_name: 'Elena Vasquez',
|
||
email: 'elena.vasquez@email.com',
|
||
phone: '+1-415-555-0107',
|
||
years_experience: 2,
|
||
english_level: 'conversational',
|
||
certifications: ['TIPS Certified'],
|
||
availability: ['Evenings'],
|
||
skills: ['Bar setup', 'Wine service'],
|
||
companies_worked: [],
|
||
client_rating: 4.0,
|
||
professional_summary: 'Barback stepping up to bartending at private events.',
|
||
job_posting_id: 'job_bartender',
|
||
job_title: 'Bartender',
|
||
status: 'interview',
|
||
ai_score: 68,
|
||
ai_match_label: 'Good Match',
|
||
ai_summary:
|
||
'Meets the minimum bar. Two years of experience with certification in place; availability and cocktail depth are the open questions.',
|
||
ai_strengths: ['TIPS certified', 'Strong bar setup discipline'],
|
||
ai_gaps: ['Evenings-only availability', 'Limited independent bartending time'],
|
||
ai_recommendation: 'Interview',
|
||
interview_id: 'int_elena',
|
||
score_breakdown: breakdown({
|
||
experience: 62, english: 72, reliability: 76, certifications: 80, availability: 58,
|
||
personality: 78, culture_fit: 72, communication_style: 70, attendance_expectations: 78,
|
||
physical_requirements: 80, leadership_expectations: 52, job_related_answers: 64,
|
||
verified_skills: 62, scenario_judgment: 66, employer_requirements: 68,
|
||
}),
|
||
created_date: iso('2026-08-02'),
|
||
updated_date: iso('2026-08-05'),
|
||
},
|
||
{
|
||
id: 'app_sam',
|
||
applicant_name: 'Sam Okafor',
|
||
email: 'sam.okafor@email.com',
|
||
phone: '+1-415-555-0108',
|
||
years_experience: 0,
|
||
english_level: 'basic',
|
||
certifications: [],
|
||
availability: ['Weekends'],
|
||
skills: [],
|
||
companies_worked: [],
|
||
client_rating: 0,
|
||
professional_summary: 'Looking for a first hospitality role.',
|
||
job_posting_id: 'job_bartender',
|
||
job_title: 'Bartender',
|
||
status: 'ai_screened',
|
||
ai_score: 28,
|
||
ai_match_label: 'Not a Fit',
|
||
ai_summary:
|
||
'Below the requirement for this posting. No bartending experience or alcohol service certification, and availability is limited to weekends.',
|
||
ai_strengths: ['Motivated and available weekends'],
|
||
ai_gaps: ['No bartending experience', 'No alcohol service certification', 'Basic English only'],
|
||
ai_recommendation: 'Reject',
|
||
score_breakdown: breakdown({
|
||
experience: 10, english: 35, reliability: 45, certifications: 0, availability: 50,
|
||
personality: 60, culture_fit: 48, communication_style: 38, attendance_expectations: 55,
|
||
physical_requirements: 70, leadership_expectations: 20, job_related_answers: 18,
|
||
verified_skills: 12, scenario_judgment: 25, employer_requirements: 22,
|
||
}),
|
||
created_date: iso('2026-08-03'),
|
||
updated_date: iso('2026-08-04'),
|
||
},
|
||
|
||
/* Picker: 3 applicants · 2 screened · 0 hired */
|
||
{
|
||
id: 'app_hector',
|
||
applicant_name: 'Hector Lima',
|
||
email: 'hector.lima@email.com',
|
||
phone: '+1-415-555-0109',
|
||
years_experience: 2,
|
||
english_level: 'conversational',
|
||
certifications: ['Forklift Operator'],
|
||
availability: ['Weekdays', 'Early mornings'],
|
||
skills: ['Order picking', 'Scanner operation', 'Pallet staging'],
|
||
companies_worked: [],
|
||
client_rating: 3.9,
|
||
professional_summary: 'Warehouse picker with forklift certification.',
|
||
job_posting_id: 'job_picker',
|
||
job_title: 'Picker',
|
||
status: 'ai_screened',
|
||
ai_score: 61,
|
||
ai_match_label: 'Good Match',
|
||
ai_summary:
|
||
'Adequate fit. Forklift certified with two years of picking experience; accuracy history is not yet verified.',
|
||
ai_strengths: ['Forklift certified', 'Early morning availability'],
|
||
ai_gaps: ['Unverified pick accuracy', 'Limited scanner system exposure'],
|
||
ai_recommendation: 'Maybe',
|
||
score_breakdown: breakdown({
|
||
experience: 60, english: 65, reliability: 68, certifications: 85, availability: 78,
|
||
personality: 70, culture_fit: 64, communication_style: 58, attendance_expectations: 72,
|
||
physical_requirements: 88, leadership_expectations: 40, job_related_answers: 55,
|
||
verified_skills: 52, scenario_judgment: 58, employer_requirements: 62,
|
||
}),
|
||
created_date: iso('2026-07-30'),
|
||
updated_date: iso('2026-08-01'),
|
||
},
|
||
{
|
||
id: 'app_wei',
|
||
applicant_name: 'Wei Chen',
|
||
email: 'wei.chen@email.com',
|
||
phone: '+1-415-555-0117',
|
||
years_experience: 1,
|
||
english_level: 'basic',
|
||
certifications: [],
|
||
availability: ['Weekdays'],
|
||
skills: ['Order picking'],
|
||
companies_worked: [],
|
||
client_rating: 0,
|
||
professional_summary: 'Fulfillment associate seeking steady warehouse shifts.',
|
||
job_posting_id: 'job_picker',
|
||
job_title: 'Picker',
|
||
status: 'ai_screened',
|
||
ai_score: 0,
|
||
created_date: iso('2026-07-31'),
|
||
updated_date: iso('2026-08-01'),
|
||
},
|
||
unscreened({
|
||
id: 'app_grace', applicant_name: 'Grace Mwangi', email: 'grace.mwangi@email.com',
|
||
phone: '+1-415-555-0118', years_experience: 3, english_level: 'fluent',
|
||
job_posting_id: 'job_picker', job_title: 'Picker',
|
||
}),
|
||
|
||
/* Banquet Captain – Hotel Events: 4 applicants · 2 screened · 0 hired */
|
||
{
|
||
id: 'app_ana',
|
||
applicant_name: 'Ana Ruiz',
|
||
email: 'ana.ruiz@email.com',
|
||
phone: '+1-415-555-0119',
|
||
years_experience: 5,
|
||
english_level: 'fluent',
|
||
certifications: ['Food Handler Card'],
|
||
availability: ['Weekdays', 'Weekends'],
|
||
skills: ['Banquet leadership', 'BEO reading', 'Floor coordination'],
|
||
companies_worked: [],
|
||
client_rating: 0,
|
||
professional_summary: 'Banquet server with lead-shift experience in hotel events.',
|
||
job_posting_id: 'job_banquet',
|
||
job_title: 'Banquet Captain – Hotel Events',
|
||
status: 'ai_screened',
|
||
ai_score: 0,
|
||
created_date: iso('2026-08-02'),
|
||
updated_date: iso('2026-08-03'),
|
||
},
|
||
{
|
||
id: 'app_devon',
|
||
applicant_name: 'Devon Carter',
|
||
email: 'devon.carter@email.com',
|
||
phone: '+1-415-555-0120',
|
||
years_experience: 6,
|
||
english_level: 'native',
|
||
certifications: ['Food Handler Card'],
|
||
availability: ['Weekdays', 'Weekends', 'Evenings'],
|
||
skills: ['Floor leadership', 'Client relations', 'Event reporting'],
|
||
companies_worked: [],
|
||
client_rating: 0,
|
||
professional_summary: 'Hotel banquet captain with six years directing event floors.',
|
||
job_posting_id: 'job_banquet',
|
||
job_title: 'Banquet Captain – Hotel Events',
|
||
status: 'interview',
|
||
ai_score: 0,
|
||
interview_id: 'int_devon',
|
||
created_date: iso('2026-08-01'),
|
||
updated_date: iso('2026-08-04'),
|
||
},
|
||
unscreened({
|
||
id: 'app_lucas', applicant_name: 'Lucas Moreau', email: 'lucas.moreau@email.com',
|
||
phone: '+1-415-555-0121', years_experience: 4, english_level: 'fluent',
|
||
job_posting_id: 'job_banquet', job_title: 'Banquet Captain – Hotel Events',
|
||
}),
|
||
unscreened({
|
||
id: 'app_fatima', applicant_name: 'Fatima Nasser', email: 'fatima.nasser@email.com',
|
||
phone: '+1-415-555-0122', years_experience: 2, english_level: 'fluent',
|
||
job_posting_id: 'job_banquet', job_title: 'Banquet Captain – Hotel Events',
|
||
}),
|
||
|
||
];
|
||
|
||
/* ── AI interviews ─────────────────────────────────────────────────────── */
|
||
|
||
const transcript = (candidate, role) => [
|
||
{ role: 'assistant', content: `Hi ${candidate.split(' ')[0]} — thanks for making time. Tell me about the busiest ${role} shift you've worked and how you handled it.`, timestamp: iso('2026-08-04') },
|
||
{ role: 'user', content: 'We were short two people on a 300-guest event. I re-sectioned the floor, moved the strongest server to the head tables, and pulled the rest into a runner rotation so nothing sat under the lamps.', timestamp: iso('2026-08-04'), response_time_seconds: 11 },
|
||
{ role: 'assistant', content: 'What broke first, and what did you do the moment you noticed?', timestamp: iso('2026-08-04') },
|
||
{ role: 'user', content: 'Dessert timing. I saw the pass backing up, so I pulled coffee service forward by five minutes to buy the kitchen room instead of letting plates die.', timestamp: iso('2026-08-04'), response_time_seconds: 9 },
|
||
];
|
||
|
||
const AI_INTERVIEWS = [
|
||
{
|
||
id: 'int_tanya',
|
||
application_id: 'app_tanya',
|
||
job_posting_id: 'job_server_fine',
|
||
job_title: 'Event Server – Fine Dining',
|
||
candidate_name: 'Tanya Cruz',
|
||
messages: transcript('Tanya Cruz', 'banquet'),
|
||
overall_interview_score: 72,
|
||
verdict: 'maybe',
|
||
hire_recommendation: 'Worth a trial shift on a coursed dinner before committing to the season.',
|
||
integrity_score: 100,
|
||
ai_flags: [],
|
||
category_scores: {
|
||
communication: 78, confidence: 71, experience_relevance: 74, culture_fit: 76,
|
||
problem_solving: 69, personality: 77, communication_style: 76,
|
||
attendance_expectations: 82, reliability: 80, physical_requirements: 84,
|
||
leadership_expectations: 62, scenario_judgment: 70, job_related_answers: 73,
|
||
verified_skills: 68,
|
||
},
|
||
strengths: ['Clear, calm delivery under pressure', 'Reprioritized service timing sensibly'],
|
||
concerns: ['Weekend-only availability', 'Limited wine service vocabulary'],
|
||
best_fit_roles: ['Event Server', 'Banquet Server'],
|
||
summary:
|
||
'Composed and specific about a real understaffed service. Judgment is sound; depth on fine dining vocabulary is still developing.',
|
||
reasoning:
|
||
'Answers referenced concrete decisions rather than generalities, which supports the reliability signal. Scores held back by narrow availability and thin wine knowledge.',
|
||
created_date: iso('2026-08-05'),
|
||
},
|
||
{
|
||
id: 'int_jordan',
|
||
application_id: 'app_jordan',
|
||
job_posting_id: 'job_bartender',
|
||
job_title: 'Bartender',
|
||
candidate_name: 'Jordan Blake',
|
||
messages: transcript('Jordan Blake', 'bar'),
|
||
overall_interview_score: 0,
|
||
verdict: 'maybe',
|
||
hire_recommendation: '',
|
||
integrity_score: 100,
|
||
ai_flags: [],
|
||
category_scores: {},
|
||
strengths: [],
|
||
concerns: [],
|
||
best_fit_roles: [],
|
||
summary: '',
|
||
reasoning: '',
|
||
created_date: iso('2026-08-05'),
|
||
},
|
||
{
|
||
id: 'int_elena',
|
||
application_id: 'app_elena',
|
||
job_posting_id: 'job_bartender',
|
||
job_title: 'Bartender',
|
||
candidate_name: 'Elena Vasquez',
|
||
messages: transcript('Elena Vasquez', 'bar'),
|
||
overall_interview_score: 0,
|
||
verdict: 'maybe',
|
||
hire_recommendation: '',
|
||
integrity_score: 100,
|
||
ai_flags: [],
|
||
category_scores: {},
|
||
strengths: [],
|
||
concerns: [],
|
||
best_fit_roles: [],
|
||
summary: '',
|
||
reasoning: '',
|
||
created_date: iso('2026-08-05'),
|
||
},
|
||
{
|
||
id: 'int_dana',
|
||
application_id: 'app_dana',
|
||
job_posting_id: 'job_security',
|
||
job_title: 'Event Security Officer',
|
||
candidate_name: 'Dana Whitfield',
|
||
messages: transcript('Dana Whitfield', 'door'),
|
||
overall_interview_score: 0,
|
||
verdict: 'maybe',
|
||
hire_recommendation: '',
|
||
integrity_score: 100,
|
||
ai_flags: [],
|
||
category_scores: {},
|
||
strengths: [],
|
||
concerns: [],
|
||
best_fit_roles: [],
|
||
summary: '',
|
||
reasoning: '',
|
||
created_date: iso('2026-08-03'),
|
||
},
|
||
];
|
||
|
||
/* ── Staff (hires) ─────────────────────────────────────────────────────── */
|
||
|
||
// created_date descending is the order Hired History renders.
|
||
const STAFF = [
|
||
{
|
||
id: 'staff_marco',
|
||
name: 'Marco Rivera',
|
||
email: 'marco.rivera@email.com',
|
||
phone: '+1-415-555-0103',
|
||
role: 'Experienced Bartender – Corporate Events',
|
||
profile_tier: 'Skilled',
|
||
hire_date: '2026-07-25',
|
||
application_id: 'app_marco',
|
||
job_posting_id: 'job_bartender_corp',
|
||
ai_score: 92,
|
||
status: 'onboarding',
|
||
client_rating: 0,
|
||
endorsed_skills: [],
|
||
created_date: iso('2026-07-25'),
|
||
},
|
||
{
|
||
id: 'staff_marcus',
|
||
name: 'Marcus Williams',
|
||
email: 'marcus.w@email.com',
|
||
phone: '+1-415-555-0102',
|
||
role: 'Event Security Officer',
|
||
profile_tier: 'Skilled',
|
||
hire_date: '2026-07-25',
|
||
application_id: 'app_marcus',
|
||
job_posting_id: 'job_security',
|
||
ai_score: 94,
|
||
status: 'onboarding',
|
||
client_rating: 0,
|
||
endorsed_skills: [],
|
||
created_date: iso('2026-07-25'),
|
||
},
|
||
{
|
||
id: 'staff_antoine',
|
||
name: 'Chef Antoine Dubois',
|
||
email: 'antoine.dubois@email.com',
|
||
phone: '+1-415-555-0101',
|
||
role: 'Executive Chef – Catering',
|
||
profile_tier: 'Skilled',
|
||
hire_date: '2026-07-25',
|
||
application_id: 'app_antoine',
|
||
job_posting_id: 'job_chef',
|
||
ai_score: 97,
|
||
status: 'onboarding',
|
||
client_rating: 0,
|
||
endorsed_skills: [],
|
||
created_date: iso('2026-07-25'),
|
||
},
|
||
];
|
||
|
||
/* ── Courses, badges, learning paths ───────────────────────────────────── */
|
||
|
||
const COURSES = [
|
||
{
|
||
id: 'course_service_basics',
|
||
title: 'Fine Dining Service Standards',
|
||
description:
|
||
'Coursed service, tray discipline, and the small signals that separate a polished floor from a busy one.',
|
||
category: 'Service',
|
||
difficulty: 'beginner',
|
||
xp: 120,
|
||
badge_reward: 'Service Fundamentals',
|
||
estimated_minutes: 18,
|
||
proof_skill: 'Coursed Table Service',
|
||
/* The four skill-graph fields on a record that predates them. Nothing else
|
||
about these originals changes — the ladder simply now knows where they
|
||
sit, which is what lets completing one move a worker's level. */
|
||
skill_id: 'server',
|
||
target_level: 'advanced',
|
||
required_level: 'intermediate',
|
||
completion_criteria: ['Work through the training material', 'Submit evidence for the challenge'],
|
||
verification_criteria: ['Acknowledges without excuses', 'Offers a concrete remedy', 'Protects the table experience'],
|
||
challenge: {
|
||
type: 'roleplay',
|
||
prompt:
|
||
'A guest at a seated dinner says their entrée is cold, and the kitchen is nine minutes behind. Handle it out loud, start to finish.',
|
||
ai_persona: 'A polite but disappointed guest at a wedding head table.',
|
||
rubric: [
|
||
{ criterion: 'Acknowledges without excuses', weight: 30 },
|
||
{ criterion: 'Offers a concrete remedy', weight: 40 },
|
||
{ criterion: 'Protects the table experience', weight: 30 },
|
||
],
|
||
},
|
||
unlock_requirements: { min_shifts: 0, min_reliability: 0, required_badges: [] },
|
||
quiz: [
|
||
{
|
||
question: 'A guest flags an allergy mid-service. What happens first?',
|
||
options: ['Guess from the menu', 'Stop the plate and check with the kitchen', 'Serve it anyway', 'Ask another server'],
|
||
correct_index: 1,
|
||
},
|
||
{
|
||
question: 'When do you clear a course?',
|
||
options: ['As each guest finishes', 'When the whole table has finished', 'Before dessert only', 'At the captain’s call'],
|
||
correct_index: 1,
|
||
},
|
||
],
|
||
pass_score: 70,
|
||
status: 'active',
|
||
created_date: iso('2026-06-10'),
|
||
},
|
||
{
|
||
id: 'course_responsible_service',
|
||
title: 'Responsible Alcohol Service',
|
||
description: 'Reading intoxication, refusing service without a scene, and documenting what happened.',
|
||
category: 'Bar',
|
||
difficulty: 'intermediate',
|
||
xp: 160,
|
||
badge_reward: 'Responsible Service',
|
||
estimated_minutes: 22,
|
||
proof_skill: 'Responsible Service Judgment',
|
||
skill_id: 'bartending',
|
||
target_level: 'intermediate',
|
||
required_level: 'beginner',
|
||
completion_criteria: ['Work through the training material', 'Submit evidence for the challenge'],
|
||
verification_criteria: ['Refuses clearly and kindly', 'Offers an alternative', 'Escalates appropriately'],
|
||
challenge: {
|
||
type: 'roleplay',
|
||
prompt: 'A guest who has clearly had enough asks for one more round, and their colleagues are watching. Talk it through.',
|
||
ai_persona: 'A friendly but insistent guest at a corporate holiday party.',
|
||
rubric: [
|
||
{ criterion: 'Refuses clearly and kindly', weight: 40 },
|
||
{ criterion: 'Offers an alternative', weight: 30 },
|
||
{ criterion: 'Escalates appropriately', weight: 30 },
|
||
],
|
||
},
|
||
unlock_requirements: { min_shifts: 0, min_reliability: 0, required_badges: [] },
|
||
quiz: [
|
||
{
|
||
question: 'A guest shows clear signs of intoxication. What do you do?',
|
||
options: ['Serve a weaker drink', 'Refuse service and notify your lead', 'Ignore it', 'Ask a coworker to serve them'],
|
||
correct_index: 1,
|
||
},
|
||
],
|
||
pass_score: 75,
|
||
status: 'active',
|
||
created_date: iso('2026-06-12'),
|
||
},
|
||
{
|
||
id: 'course_kitchen_safety',
|
||
title: 'Kitchen Safety & Hazard Spotting',
|
||
description: 'Find the hazard before it finds you — temperature, cross-contamination, and traffic flow.',
|
||
category: 'Kitchen',
|
||
difficulty: 'beginner',
|
||
xp: 100,
|
||
badge_reward: 'Safety Aware',
|
||
estimated_minutes: 14,
|
||
proof_skill: 'Hazard Identification',
|
||
skill_id: 'food_safety',
|
||
target_level: 'beginner',
|
||
required_level: null,
|
||
completion_criteria: ['Work through the training material', 'Submit evidence for the challenge'],
|
||
verification_criteria: ['Identifies temperature violations', 'Spots cross-contamination risk', 'Notes obstruction hazards'],
|
||
challenge: {
|
||
type: 'photo_identify',
|
||
prompt: 'Mark every food-safety hazard you can find in this prep station.',
|
||
image_url: '',
|
||
rubric: [
|
||
{ criterion: 'Identifies temperature violations', weight: 40 },
|
||
{ criterion: 'Spots cross-contamination risk', weight: 40 },
|
||
{ criterion: 'Notes obstruction hazards', weight: 20 },
|
||
],
|
||
},
|
||
unlock_requirements: { min_shifts: 0, min_reliability: 0, required_badges: [] },
|
||
quiz: [
|
||
{
|
||
question: 'What is the danger zone for cold-held food?',
|
||
options: ['Below 32°F', '41°F to 135°F', 'Above 165°F', 'Any temperature'],
|
||
correct_index: 1,
|
||
},
|
||
],
|
||
pass_score: 70,
|
||
status: 'active',
|
||
created_date: iso('2026-06-14'),
|
||
},
|
||
{
|
||
id: 'course_leadership',
|
||
title: 'Leading a Floor Team',
|
||
description: 'Pre-shift briefings, section assignments, and correcting a teammate without deflating them.',
|
||
category: 'Leadership',
|
||
difficulty: 'advanced',
|
||
xp: 240,
|
||
badge_reward: 'Floor Leader',
|
||
estimated_minutes: 30,
|
||
proof_skill: 'Team Leadership',
|
||
skill_id: 'leadership',
|
||
target_level: 'advanced',
|
||
required_level: 'intermediate',
|
||
completion_criteria: ['Work through the training material', 'Submit evidence for the challenge'],
|
||
verification_criteria: ['Assigns clear ownership', 'Communicates timing', 'Sets a tone people follow'],
|
||
challenge: {
|
||
type: 'video',
|
||
prompt: 'Record the pre-shift briefing you would give a floor team of eight before a 300-guest gala.',
|
||
rubric: [
|
||
{ criterion: 'Assigns clear ownership', weight: 35 },
|
||
{ criterion: 'Communicates timing', weight: 35 },
|
||
{ criterion: 'Sets a tone people follow', weight: 30 },
|
||
],
|
||
},
|
||
unlock_requirements: { min_shifts: 5, min_reliability: 70, required_badges: ['Service Fundamentals'] },
|
||
quiz: [],
|
||
pass_score: 80,
|
||
status: 'active',
|
||
created_date: iso('2026-06-16'),
|
||
},
|
||
];
|
||
|
||
/* ── Training modules (the skill ladders) ──────────────────────────────── */
|
||
|
||
/**
|
||
* The training behind every level of every skill.
|
||
*
|
||
* Written as a table rather than 36 hand-built records: each row is one module,
|
||
* and the shape it expands to is the same Course entity the four skills above
|
||
* use, so the challenge page, the Forge library and Owliver's evaluation all
|
||
* read these without knowing they were generated.
|
||
*
|
||
* Columns: skill · level · title · minutes · proof type · description ·
|
||
* what Owliver checks. `required_level` is the rung below, which is what makes
|
||
* the ladder a ladder rather than a menu.
|
||
*/
|
||
const MODULE_TABLE = [
|
||
/* Server — the full four-rung ladder. */
|
||
['server', 'beginner', 'Server Fundamentals', 18, 'roleplay', 'Sequence of service, tray discipline, and the first ninety seconds at a table.', ['Greets and sets expectations', 'Follows the service sequence', 'Handles the tray safely']],
|
||
['server', 'beginner', 'Workplace Safety', 14, 'photo_identify', 'Spot the hazard before it becomes an incident — spills, traffic, hot pass.', ['Identifies floor hazards', 'Spots obstruction risks', 'Knows when to stop service']],
|
||
['server', 'beginner', 'Basic Guest Service', 16, 'roleplay', 'Reading a table, timing an approach, and answering what you actually know.', ['Reads the table before approaching', 'Answers accurately', 'Closes the interaction cleanly']],
|
||
|
||
['server', 'intermediate', 'Advanced Guest Service', 20, 'roleplay', 'Difficult tables, competing demands, and keeping a section moving anyway.', ['Prioritises across tables', 'Keeps guests informed', 'Recovers timing without panic']],
|
||
['server', 'intermediate', 'Table Management', 18, 'roleplay', 'Running a section: turns, holds, and the order you touch tables in.', ['Sequences the section', 'Manages holds and turns', 'Communicates with the pass']],
|
||
['server', 'intermediate', 'Order Accuracy', 15, 'roleplay', 'Modifiers, allergens, and repeating back what you are about to send.', ['Confirms modifiers', 'Flags allergens correctly', 'Verifies before firing']],
|
||
|
||
['server', 'advanced', 'Guest Recovery', 22, 'roleplay', 'Turning a failed experience around without giving away the room.', ['Acknowledges without excuses', 'Offers a concrete remedy', 'Protects the table experience']],
|
||
['server', 'advanced', 'High-Volume Service Operations', 25, 'video', 'Three hundred covers, one pass, and a plan that survives contact.', ['Plans the run', 'Holds the standard at volume', 'Adjusts without dropping tables']],
|
||
|
||
['server', 'expert', 'Floor Leadership', 30, 'video', 'Owning the floor: assignments, pace, and the call nobody else will make.', ['Assigns clear ownership', 'Sets and holds the pace', 'Makes the decision on time']],
|
||
['server', 'expert', 'Service Coaching', 25, 'roleplay', 'Correcting a teammate mid-service without deflating them.', ['Names the behaviour, not the person', 'Gives an actionable correction', 'Confirms understanding']],
|
||
['server', 'expert', 'Operations Excellence', 28, 'roleplay', 'Reading a BEO, staffing to it, and defending the standard to a client.', ['Reads the event brief accurately', 'Staffs to the requirement', 'Holds the standard with the client']],
|
||
|
||
/* Bartending. */
|
||
['bartending', 'beginner', 'Bar Fundamentals', 16, 'roleplay', 'Station setup, glassware, and pouring to spec under a clock.', ['Sets up a working station', 'Pours to spec', 'Keeps the bar clean during service']],
|
||
['bartending', 'beginner', 'Responsible Service Basics', 14, 'roleplay', 'Checking age, reading a guest, and knowing where the line is.', ['Verifies age correctly', 'Reads intoxication signs', 'Knows the escalation path']],
|
||
|
||
['bartending', 'intermediate', 'Cocktail Specs & Speed', 20, 'video', 'Classic specs from memory, built at event pace without losing accuracy.', ['Builds to spec', 'Maintains pace', 'Recovers from a mistake cleanly']],
|
||
|
||
['bartending', 'advanced', 'High-Volume Bar Operations', 24, 'video', 'Running a bar three deep: batching, sequencing, and restock timing.', ['Batches sensibly', 'Sequences the rail', 'Restocks before it hurts']],
|
||
['bartending', 'advanced', 'Guest Judgment Behind the Bar', 20, 'roleplay', 'The refusal, the regular, and the colleague watching you make the call.', ['Refuses clearly and kindly', 'Protects the guest and the room', 'Documents what happened']],
|
||
|
||
['bartending', 'expert', 'Bar Program Leadership', 28, 'roleplay', 'Menu, training, and holding a team of bartenders to one standard.', ['Sets a standard others can follow', 'Trains rather than corrects', 'Owns the program end to end']],
|
||
['bartending', 'expert', 'Inventory & Cost Control', 24, 'roleplay', 'Par levels, variance, and explaining a number to an operator.', ['Tracks variance accurately', 'Explains the number', 'Proposes a real fix']],
|
||
|
||
/* Leadership. */
|
||
['leadership', 'beginner', 'Shift Communication', 14, 'roleplay', 'Saying the necessary thing, once, so the room hears it.', ['States the message clearly', 'Confirms it landed', 'Keeps it short']],
|
||
['leadership', 'beginner', 'Giving & Taking Direction', 16, 'roleplay', 'Taking a correction well, and giving one that can be acted on.', ['Receives correction without friction', 'Gives an actionable instruction', 'Follows up']],
|
||
|
||
['leadership', 'intermediate', 'Pre-Shift Briefings', 18, 'video', 'Two minutes that decide how the next six hours go.', ['Covers ownership and timing', 'Sets the tone', 'Ends with questions answered']],
|
||
['leadership', 'intermediate', 'Handling Conflict on the Floor', 20, 'roleplay', 'Two staff, one section, and a room that must not notice.', ['De-escalates in private', 'Resolves rather than defers', 'Protects service']],
|
||
|
||
['leadership', 'advanced', 'Section Assignment & Coverage', 22, 'roleplay', 'Matching people to sections, and covering the gap when someone drops.', ['Assigns to strength', 'Plans for absence', 'Rebalances mid-service']],
|
||
|
||
['leadership', 'expert', 'Developing Your Team', 26, 'roleplay', 'Turning a good server into the person who runs the floor next year.', ['Identifies real potential', 'Gives progressive responsibility', 'Follows through over time']],
|
||
['leadership', 'expert', 'Operations Under Pressure', 28, 'video', 'The gala that goes wrong, and the twenty minutes that decide it.', ['Triages correctly', 'Communicates under load', 'Owns the outcome']],
|
||
|
||
/* Customer Service. */
|
||
['customer_service', 'beginner', 'Guest First Impressions', 12, 'roleplay', 'The greeting, the eye contact, and the tone that sets the whole visit.', ['Opens warmly', 'Sets expectations', 'Hands off cleanly']],
|
||
['customer_service', 'beginner', 'Reading the Room', 14, 'roleplay', 'Knowing when a table wants attention and when it wants to be left alone.', ['Reads guest signals', 'Times the approach', 'Adjusts to the table']],
|
||
|
||
['customer_service', 'intermediate', 'Handling Complaints', 18, 'roleplay', 'Hearing the complaint behind the complaint, and fixing that one.', ['Listens before solving', 'Identifies the real issue', 'Resolves within authority']],
|
||
['customer_service', 'intermediate', 'Service Recovery Basics', 16, 'roleplay', 'What you can offer, what you cannot, and how to escalate fast.', ['Offers a concrete remedy', 'Stays within policy', 'Escalates without stalling']],
|
||
|
||
['customer_service', 'advanced', 'VIP & High-Stakes Guests', 20, 'roleplay', 'The head table, the client, and the guest everyone is watching.', ['Handles scrutiny calmly', 'Anticipates needs', 'Protects discretion']],
|
||
['customer_service', 'advanced', 'Client Relations', 22, 'roleplay', 'The conversation with the person who books the next event.', ['Represents the operation', 'Handles pushback', 'Secures the follow-up']],
|
||
|
||
/* Food Safety. */
|
||
['food_safety', 'beginner', 'Personal Hygiene Standards', 10, 'photo_identify', 'Handwashing, gloves, and the habits an inspector looks for first.', ['Follows hand hygiene', 'Uses gloves correctly', 'Presents to standard']],
|
||
|
||
['food_safety', 'intermediate', 'Temperature Control & HACCP', 18, 'photo_identify', 'Danger zone, hold times, and the log that proves you held it.', ['Knows the danger zone', 'Records holds accurately', 'Acts on a violation']],
|
||
['food_safety', 'intermediate', 'Allergen Management', 16, 'roleplay', 'Stopping the plate, checking the ticket, and saying it out loud.', ['Stops the plate', 'Verifies with the kitchen', 'Communicates to the guest']],
|
||
|
||
['food_safety', 'advanced', 'Food Safety Auditing', 22, 'photo_identify', 'Walking a kitchen the way an inspector does, and writing it up.', ['Finds the violations', 'Ranks by severity', 'Writes an actionable report']],
|
||
['food_safety', 'advanced', 'Incident Response & Reporting', 18, 'roleplay', 'A suspected foodborne incident, in the hour it matters.', ['Isolates the product', 'Documents accurately', 'Notifies the right people']],
|
||
];
|
||
|
||
const SKILL_CATEGORY = {
|
||
server: 'Service',
|
||
bartending: 'Bar',
|
||
leadership: 'Leadership',
|
||
customer_service: 'Service',
|
||
food_safety: 'Kitchen',
|
||
};
|
||
|
||
const LEVEL_ORDER = ['beginner', 'intermediate', 'advanced', 'expert'];
|
||
|
||
/** Level → the rung below it, which is what a module requires before it opens. */
|
||
const requiredLevelFor = (level) => LEVEL_ORDER[LEVEL_ORDER.indexOf(level) - 1] || null;
|
||
|
||
/** Difficulty is the existing field; level drives it so the two never disagree. */
|
||
const DIFFICULTY_FOR = { beginner: 'beginner', intermediate: 'intermediate', advanced: 'advanced', expert: 'advanced' };
|
||
|
||
const XP_FOR = { beginner: 100, intermediate: 150, advanced: 220, expert: 300 };
|
||
|
||
const PROMPT_FOR = {
|
||
roleplay: (title) => `Work through a ${title.toLowerCase()} scenario with Owliver, start to finish.`,
|
||
video: (title) => `Record yourself demonstrating ${title.toLowerCase()} as you would on a live shift.`,
|
||
photo_identify: (title) => `Mark everything a ${title.toLowerCase()} check should catch in this photo.`,
|
||
};
|
||
|
||
const slug = (title) => title.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_|_$/g, '');
|
||
|
||
const TRAINING_MODULES = MODULE_TABLE.map(
|
||
([skill_id, target_level, title, minutes, type, description, criteria], i) => ({
|
||
id: `mod_${skill_id}_${slug(title)}`,
|
||
title,
|
||
description,
|
||
category: SKILL_CATEGORY[skill_id],
|
||
difficulty: DIFFICULTY_FOR[target_level],
|
||
xp: XP_FOR[target_level],
|
||
estimated_minutes: minutes,
|
||
proof_skill: title,
|
||
/* The four fields that make a course a rung on a ladder. */
|
||
skill_id,
|
||
target_level,
|
||
required_level: requiredLevelFor(target_level),
|
||
completion_criteria: ['Work through the training material', 'Submit evidence for the challenge'],
|
||
verification_criteria: criteria,
|
||
challenge: {
|
||
type,
|
||
prompt: PROMPT_FOR[type](title),
|
||
ai_persona: type === 'roleplay' ? 'A guest or teammate in a live service situation.' : undefined,
|
||
rubric: (Array.isArray(criteria) ? criteria : []).map((criterion, n) => ({ criterion, weight: n === 0 ? 40 : 30 })),
|
||
},
|
||
unlock_requirements: { min_shifts: 0, min_reliability: 0, required_badges: [] },
|
||
quiz: [],
|
||
pass_score: 70,
|
||
status: 'active',
|
||
created_date: iso('2026-06-20'),
|
||
_order: i,
|
||
})
|
||
);
|
||
|
||
/** Every course the platform holds — the four originals plus the ladders. */
|
||
const COURSE_LIBRARY = [...COURSES, ...TRAINING_MODULES];
|
||
|
||
/** A module id from its skill and title, so profiles read like the ladder does. */
|
||
const mod = (skill, title) => `mod_${skill}_${slug(title)}`;
|
||
|
||
/**
|
||
* Completed training on a worker profile.
|
||
*
|
||
* Titles are looked up rather than repeated, so a renamed module cannot leave a
|
||
* profile claiming a course that no longer goes by that name.
|
||
*/
|
||
const completions = (ids, date, score = 88) =>
|
||
ids.map((id) => ({
|
||
course_id: id,
|
||
title: COURSE_LIBRARY.find((c) => c.id === id)?.title || id,
|
||
score,
|
||
completed_date: iso(date),
|
||
}));
|
||
|
||
/* The ladders, as id lists — profiles below compose them. */
|
||
const SERVER_BEGINNER = ['Server Fundamentals', 'Workplace Safety', 'Basic Guest Service'].map((t) => mod('server', t));
|
||
const SERVER_INTERMEDIATE = ['Advanced Guest Service', 'Table Management', 'Order Accuracy'].map((t) => mod('server', t));
|
||
const SERVER_ADVANCED = ['course_service_basics', mod('server', 'Guest Recovery'), mod('server', 'High-Volume Service Operations')];
|
||
const CS_BEGINNER = ['Guest First Impressions', 'Reading the Room'].map((t) => mod('customer_service', t));
|
||
const CS_INTERMEDIATE = ['Handling Complaints', 'Service Recovery Basics'].map((t) => mod('customer_service', t));
|
||
const CS_ADVANCED = ['VIP & High-Stakes Guests', 'Client Relations'].map((t) => mod('customer_service', t));
|
||
const FOOD_BEGINNER = ['course_kitchen_safety', mod('food_safety', 'Personal Hygiene Standards')];
|
||
const LEAD_BEGINNER = ['Shift Communication', 'Giving & Taking Direction'].map((t) => mod('leadership', t));
|
||
const LEAD_INTERMEDIATE = ['Pre-Shift Briefings', 'Handling Conflict on the Floor'].map((t) => mod('leadership', t));
|
||
const LEAD_ADVANCED = ['course_leadership', mod('leadership', 'Section Assignment & Coverage')];
|
||
|
||
const BADGES = [
|
||
{ id: 'badge_service', name: 'Service Fundamentals', description: 'Verified coursed table service.', level: 'bronze', requirements: 'Complete Fine Dining Service Standards', verification_status: 'verified', created_date: iso('2026-06-10') },
|
||
{ id: 'badge_responsible', name: 'Responsible Service', description: 'Verified responsible alcohol service judgment.', level: 'silver', requirements: 'Complete Responsible Alcohol Service', expiration_months: 24, verification_status: 'verified', created_date: iso('2026-06-12') },
|
||
{ id: 'badge_safety', name: 'Safety Aware', description: 'Verified hazard identification.', level: 'bronze', requirements: 'Complete Kitchen Safety & Hazard Spotting', verification_status: 'verified', created_date: iso('2026-06-14') },
|
||
{ id: 'badge_leader', name: 'Floor Leader', description: 'Verified floor team leadership.', level: 'gold', requirements: 'Complete Leading a Floor Team', verification_status: 'verified', created_date: iso('2026-06-16') },
|
||
];
|
||
|
||
const LEARNING_PATHS = [
|
||
{
|
||
id: 'path_server',
|
||
name: 'Event Server Track',
|
||
target_role: 'Event Server',
|
||
description: 'From first shift to a floor a captain can trust.',
|
||
difficulty: 'beginner',
|
||
steps: [
|
||
{ order: 1, course_id: 'course_service_basics', course_title: 'Fine Dining Service Standards' },
|
||
{ order: 2, course_id: 'course_kitchen_safety', course_title: 'Kitchen Safety & Hazard Spotting' },
|
||
{ order: 3, course_id: 'course_leadership', course_title: 'Leading a Floor Team' },
|
||
],
|
||
created_date: iso('2026-06-18'),
|
||
},
|
||
{
|
||
id: 'path_bartender',
|
||
name: 'Bartender Track',
|
||
target_role: 'Bartender',
|
||
description: 'Speed, specs, and the judgment to run a bar alone.',
|
||
difficulty: 'intermediate',
|
||
steps: [
|
||
{ order: 1, course_id: 'course_responsible_service', course_title: 'Responsible Alcohol Service' },
|
||
{ order: 2, course_id: 'course_service_basics', course_title: 'Fine Dining Service Standards' },
|
||
],
|
||
created_date: iso('2026-06-18'),
|
||
},
|
||
];
|
||
|
||
/* ── Worker profiles (Talent Pool) ─────────────────────────────────────── */
|
||
|
||
/** krow_score maps to the 300–850 career score: 94 → 817, 12 → 366, 0 → 300. */
|
||
const WORKER_PROFILES = [
|
||
{
|
||
id: 'wp_maria',
|
||
full_name: 'Maria Gonzalez',
|
||
email: 'maria.gonzalez@example.com',
|
||
phone: '+1-415-555-0201',
|
||
address: 'San Jose, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=31',
|
||
languages: ['English', 'Spanish'],
|
||
availability: ['Weekdays', 'Weekends', 'Evenings'],
|
||
transportation: 'Own vehicle',
|
||
certifications: ['Food Handler Card', 'ServSafe'],
|
||
experience: [
|
||
{ company: 'Legendary Event Staff', role: 'Banquet Captain', years: 4 },
|
||
{ company: 'Fairmont San Jose', role: 'Event Server', years: 3 },
|
||
],
|
||
experience_years: 7,
|
||
current_position: 'Banquet Captain',
|
||
desired_position: 'Event Lead',
|
||
career_goals: 'Run event operations for a hotel group within three years.',
|
||
skills: ['Floor leadership', 'Coursed service', 'Client relations', 'BEO reading', 'Scheduling'],
|
||
industries: ['Hospitality', 'Events'],
|
||
personality: 'Steady and direct. Sets expectations early and holds them without friction.',
|
||
strengths: ['Calm under pressure', 'Trains new staff well', 'Client-facing polish'],
|
||
weaknesses: ['Takes on too much rather than delegating'],
|
||
communication_style: 'Concise and warm; confirms understanding before moving on.',
|
||
salary_expectations: '$30–$36/hr',
|
||
leadership_potential: 92,
|
||
ai_interview_score: 93,
|
||
krow_score: 94,
|
||
reliability_score: 95,
|
||
profile_completion: 100,
|
||
xp: 1480,
|
||
/* Seven years on the floor, as a completed ladder: Server and Leadership to
|
||
Advanced, Customer Service to Advanced, Food Safety to Beginner. */
|
||
completed_courses: completions(
|
||
[
|
||
...SERVER_BEGINNER, ...SERVER_INTERMEDIATE, ...SERVER_ADVANCED,
|
||
...CS_BEGINNER, ...CS_INTERMEDIATE, ...CS_ADVANCED,
|
||
...FOOD_BEGINNER,
|
||
...LEAD_BEGINNER, ...LEAD_INTERMEDIATE, ...LEAD_ADVANCED,
|
||
],
|
||
'2026-07-14',
|
||
93
|
||
),
|
||
earned_badges: [
|
||
{ name: 'Service Fundamentals', level: 'bronze', course_id: 'course_service_basics', earned_date: iso('2026-06-22') },
|
||
{ name: 'Safety Aware', level: 'bronze', course_id: 'course_kitchen_safety', earned_date: iso('2026-07-01') },
|
||
{ name: 'Floor Leader', level: 'gold', course_id: 'course_leadership', earned_date: iso('2026-07-14') },
|
||
],
|
||
capabilities: [
|
||
{ skill: 'Coursed Table Service', level: 'Verified', evidence_id: 'ev_maria_service', status: 'verified', verified_date: iso('2026-06-22') },
|
||
{ skill: 'Team Leadership', level: 'Verified', evidence_id: 'ev_maria_leadership', status: 'verified', verified_date: iso('2026-07-14') },
|
||
],
|
||
shifts_completed: 64,
|
||
attendance_score: 98,
|
||
performance_score: 93,
|
||
client_rating: 4.9,
|
||
supervisor_rating: 4.8,
|
||
status: 'active',
|
||
created_date: iso('2026-06-20'),
|
||
},
|
||
{
|
||
id: 'wp_iliana',
|
||
full_name: 'Iliana Ortega',
|
||
email: 'iortega@legendaryeventstaff.com',
|
||
phone: '+1-415-555-0202',
|
||
address: 'Oakland, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=26',
|
||
languages: ['English', 'Spanish'],
|
||
availability: ['Weekends'],
|
||
transportation: 'Public transit',
|
||
certifications: ['Food Handler Card'],
|
||
experience: [{ company: 'Legendary Event Staff', role: 'Event Server', years: 1 }],
|
||
experience_years: 1,
|
||
current_position: 'Event Server',
|
||
desired_position: 'Bartender',
|
||
career_goals: 'Move behind the bar and get certified this year.',
|
||
skills: ['Table service', 'Guest relations'],
|
||
industries: ['Hospitality'],
|
||
leadership_potential: 24,
|
||
ai_interview_score: 0,
|
||
krow_score: 12,
|
||
reliability_score: 38,
|
||
profile_completion: 62,
|
||
xp: 120,
|
||
/* One year in: the Beginner rung of Server, and one Intermediate module
|
||
started — so her card reads "Beginner, advancing" rather than a flat
|
||
label that hides the work in progress. */
|
||
completed_courses: completions(
|
||
[...SERVER_BEGINNER, mod('server', 'Advanced Guest Service'), ...CS_BEGINNER],
|
||
'2026-07-28',
|
||
79
|
||
),
|
||
earned_badges: [
|
||
{ name: 'Service Fundamentals', level: 'bronze', course_id: 'course_service_basics', earned_date: iso('2026-07-28') },
|
||
],
|
||
capabilities: [],
|
||
shifts_completed: 6,
|
||
attendance_score: 92,
|
||
performance_score: 0,
|
||
client_rating: 0,
|
||
supervisor_rating: 0,
|
||
status: 'active',
|
||
created_date: iso('2026-07-22'),
|
||
},
|
||
/**
|
||
* Arun, Priya and Rahul are the same position read three ways.
|
||
*
|
||
* All three are measured against Senior Server – Fine Dining, and the only
|
||
* thing that separates them is verified training: Arun is one module short of
|
||
* qualifying, Priya is a level behind on the skill that carries the role, and
|
||
* Rahul has the ground floor but nothing above it. Nothing about their match
|
||
* is stored — completing training is what moves it.
|
||
*/
|
||
{
|
||
id: 'wp_arun',
|
||
full_name: 'Arun Kumar',
|
||
email: 'arun.kumar@example.com',
|
||
phone: '+1-408-555-0210',
|
||
address: 'San Jose, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=68',
|
||
languages: ['English', 'Tamil'],
|
||
availability: ['Weekdays', 'Weekends', 'Evenings'],
|
||
transportation: 'Own vehicle',
|
||
certifications: ['Food Handler Card'],
|
||
experience: [{ company: 'Valley Catering Co.', role: 'Event Server', years: 4 }],
|
||
experience_years: 4,
|
||
current_position: 'Event Server',
|
||
desired_position: 'Senior Server',
|
||
career_goals: 'Run a fine dining section as the senior server on the floor.',
|
||
skills: ['Coursed service', 'Guest recovery', 'Allergen handling'],
|
||
industries: ['Hospitality', 'Events'],
|
||
personality: 'Unflappable. Notices the table nobody else is watching.',
|
||
strengths: ['Calm at volume', 'Accurate under pressure'],
|
||
weaknesses: ['Quiet in briefings'],
|
||
communication_style: 'Measured; confirms detail before acting.',
|
||
salary_expectations: '$26–$32/hr',
|
||
leadership_potential: 68,
|
||
ai_interview_score: 86,
|
||
krow_score: 82,
|
||
reliability_score: 91,
|
||
profile_completion: 94,
|
||
xp: 1180,
|
||
/* Server through Intermediate, plus two of the three Advanced modules —
|
||
Fine Dining Service Standards is the one thing between him and Advanced,
|
||
and therefore between him and this role. */
|
||
completed_courses: completions(
|
||
[
|
||
...SERVER_BEGINNER, ...SERVER_INTERMEDIATE,
|
||
mod('server', 'Guest Recovery'), mod('server', 'High-Volume Service Operations'),
|
||
...CS_BEGINNER, ...CS_INTERMEDIATE,
|
||
...FOOD_BEGINNER,
|
||
...LEAD_BEGINNER,
|
||
],
|
||
'2026-08-02',
|
||
89
|
||
),
|
||
earned_badges: [],
|
||
capabilities: [],
|
||
shifts_completed: 38,
|
||
attendance_score: 96,
|
||
performance_score: 88,
|
||
client_rating: 4.7,
|
||
supervisor_rating: 4.6,
|
||
status: 'active',
|
||
created_date: iso('2026-07-05'),
|
||
},
|
||
{
|
||
id: 'wp_priya',
|
||
full_name: 'Priya Nair',
|
||
email: 'priya.nair@example.com',
|
||
phone: '+1-408-555-0211',
|
||
address: 'Santa Clara, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=47',
|
||
languages: ['English', 'Hindi'],
|
||
availability: ['Weekends', 'Evenings'],
|
||
transportation: 'Own vehicle',
|
||
certifications: ['Food Handler Card'],
|
||
experience: [{ company: 'Bay Event Staffing', role: 'Event Server', years: 2 }],
|
||
experience_years: 2,
|
||
current_position: 'Event Server',
|
||
desired_position: 'Senior Server',
|
||
career_goals: 'Move up to fine dining sections.',
|
||
skills: ['Table service', 'Guest relations'],
|
||
industries: ['Hospitality'],
|
||
leadership_potential: 45,
|
||
ai_interview_score: 74,
|
||
krow_score: 68,
|
||
reliability_score: 84,
|
||
profile_completion: 80,
|
||
xp: 760,
|
||
completed_courses: completions(
|
||
[...SERVER_BEGINNER, ...SERVER_INTERMEDIATE, ...CS_BEGINNER, ...CS_INTERMEDIATE, ...FOOD_BEGINNER],
|
||
'2026-07-30',
|
||
85
|
||
),
|
||
earned_badges: [],
|
||
capabilities: [],
|
||
shifts_completed: 21,
|
||
attendance_score: 93,
|
||
performance_score: 81,
|
||
client_rating: 4.5,
|
||
supervisor_rating: 4.4,
|
||
status: 'active',
|
||
created_date: iso('2026-07-12'),
|
||
},
|
||
{
|
||
id: 'wp_rahul',
|
||
full_name: 'Rahul Menon',
|
||
email: 'rahul.menon@example.com',
|
||
phone: '+1-408-555-0212',
|
||
address: 'Milpitas, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=59',
|
||
languages: ['English'],
|
||
availability: ['Weekends'],
|
||
transportation: 'Public transit',
|
||
certifications: [],
|
||
experience: [],
|
||
experience_years: 0,
|
||
current_position: '',
|
||
desired_position: 'Event Server',
|
||
career_goals: 'Get on a floor and learn the work properly.',
|
||
skills: [],
|
||
industries: ['Hospitality'],
|
||
leadership_potential: 20,
|
||
ai_interview_score: 0,
|
||
krow_score: 41,
|
||
reliability_score: 72,
|
||
profile_completion: 58,
|
||
xp: 320,
|
||
completed_courses: completions(
|
||
[...SERVER_BEGINNER, ...CS_BEGINNER, ...FOOD_BEGINNER, ...LEAD_BEGINNER],
|
||
'2026-08-05',
|
||
76
|
||
),
|
||
earned_badges: [],
|
||
capabilities: [],
|
||
shifts_completed: 4,
|
||
attendance_score: 100,
|
||
performance_score: 0,
|
||
client_rating: 0,
|
||
supervisor_rating: 0,
|
||
status: 'active',
|
||
created_date: iso('2026-07-28'),
|
||
},
|
||
{
|
||
id: 'wp_aravind',
|
||
full_name: 'Aravind Kumar',
|
||
email: 'aravind@tenext.in',
|
||
phone: '+1-415-555-0203',
|
||
address: 'Fremont, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=15',
|
||
languages: ['English', 'Tamil', 'Hindi'],
|
||
availability: ['Weekdays', 'Evenings'],
|
||
transportation: 'Own vehicle',
|
||
certifications: [],
|
||
experience: [],
|
||
experience_years: 0,
|
||
current_position: '',
|
||
desired_position: 'Barback',
|
||
career_goals: 'Get a first hospitality shift and build from there.',
|
||
skills: [],
|
||
industries: ['Hospitality'],
|
||
leadership_potential: 0,
|
||
ai_interview_score: 0,
|
||
krow_score: 0,
|
||
reliability_score: 0,
|
||
profile_completion: 30,
|
||
xp: 0,
|
||
completed_courses: [],
|
||
earned_badges: [],
|
||
capabilities: [],
|
||
shifts_completed: 0,
|
||
attendance_score: 100,
|
||
performance_score: 0,
|
||
client_rating: 0,
|
||
supervisor_rating: 0,
|
||
status: 'active',
|
||
created_date: iso('2026-08-02'),
|
||
},
|
||
{
|
||
id: 'wp_demo',
|
||
full_name: 'New Talent Demo',
|
||
email: 'new.demo2@example.com',
|
||
phone: '+1-415-555-0204',
|
||
address: 'San Francisco, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=9',
|
||
languages: ['English'],
|
||
availability: [],
|
||
transportation: '',
|
||
certifications: [],
|
||
experience: [],
|
||
experience_years: 0,
|
||
current_position: '',
|
||
desired_position: '',
|
||
career_goals: '',
|
||
skills: [],
|
||
industries: [],
|
||
leadership_potential: 0,
|
||
ai_interview_score: 0,
|
||
krow_score: 0,
|
||
reliability_score: 0,
|
||
profile_completion: 10,
|
||
xp: 0,
|
||
completed_courses: [],
|
||
earned_badges: [],
|
||
capabilities: [],
|
||
shifts_completed: 0,
|
||
attendance_score: 100,
|
||
performance_score: 0,
|
||
client_rating: 0,
|
||
supervisor_rating: 0,
|
||
status: 'active',
|
||
created_date: iso('2026-08-05'),
|
||
},
|
||
{
|
||
id: 'wp_jamal',
|
||
full_name: 'Jamal Whitaker',
|
||
email: 'jamal.whitaker@example.com',
|
||
phone: '+1-415-555-0205',
|
||
address: 'Berkeley, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=52',
|
||
languages: ['English'],
|
||
availability: ['Weekends', 'Evenings'],
|
||
transportation: 'Own vehicle',
|
||
certifications: [],
|
||
experience: [],
|
||
experience_years: 0,
|
||
current_position: '',
|
||
desired_position: 'Event Server',
|
||
career_goals: 'Work weekends around school.',
|
||
skills: [],
|
||
industries: ['Events'],
|
||
leadership_potential: 0,
|
||
ai_interview_score: 0,
|
||
krow_score: 0,
|
||
reliability_score: 0,
|
||
profile_completion: 25,
|
||
xp: 0,
|
||
completed_courses: [],
|
||
earned_badges: [],
|
||
capabilities: [],
|
||
shifts_completed: 0,
|
||
attendance_score: 100,
|
||
performance_score: 0,
|
||
client_rating: 0,
|
||
supervisor_rating: 0,
|
||
status: 'active',
|
||
created_date: iso('2026-08-06'),
|
||
},
|
||
{
|
||
id: 'wp_lin',
|
||
full_name: 'Lin Zhao',
|
||
email: 'lin.zhao@example.com',
|
||
phone: '+1-415-555-0206',
|
||
address: 'Daly City, CA',
|
||
selfie_url: 'https://i.pravatar.cc/240?img=20',
|
||
languages: ['English', 'Mandarin'],
|
||
availability: ['Weekdays'],
|
||
transportation: 'Public transit',
|
||
certifications: [],
|
||
experience: [],
|
||
experience_years: 0,
|
||
current_position: '',
|
||
desired_position: 'Picker',
|
||
career_goals: 'Steady weekday warehouse work.',
|
||
skills: [],
|
||
industries: ['Logistics'],
|
||
leadership_potential: 0,
|
||
ai_interview_score: 0,
|
||
krow_score: 0,
|
||
reliability_score: 0,
|
||
profile_completion: 20,
|
||
xp: 0,
|
||
completed_courses: [],
|
||
earned_badges: [],
|
||
capabilities: [],
|
||
shifts_completed: 0,
|
||
attendance_score: 100,
|
||
performance_score: 0,
|
||
client_rating: 0,
|
||
supervisor_rating: 0,
|
||
status: 'active',
|
||
created_date: iso('2026-08-06'),
|
||
},
|
||
];
|
||
|
||
/* ── Evidence (Proving Ground) ─────────────────────────────────────────── */
|
||
|
||
const EVIDENCE = [
|
||
{
|
||
id: 'ev_maria_service',
|
||
course_id: 'course_service_basics',
|
||
course_title: 'Fine Dining Service Standards',
|
||
skill: 'Coursed Table Service',
|
||
worker_email: 'maria.gonzalez@example.com',
|
||
worker_name: 'Maria Gonzalez',
|
||
type: 'roleplay',
|
||
media_url: '',
|
||
transcript:
|
||
'Acknowledged the cold entrée without excuses, offered to re-fire immediately with a comped course, and kept the rest of the table on timing.',
|
||
ai_verdict: 'verified',
|
||
ai_score: 96,
|
||
ai_rubric: { 'Acknowledges without excuses': 95, 'Offers a concrete remedy': 98, 'Protects the table experience': 94 },
|
||
ai_feedback: 'Owned the problem in one sentence and moved straight to a remedy. Exactly the instinct this role needs.',
|
||
supervisor_verified: true,
|
||
supervisor_name: 'Luis Ortega',
|
||
verified_date: iso('2026-06-23'),
|
||
created_date: iso('2026-06-22'),
|
||
},
|
||
{
|
||
id: 'ev_maria_leadership',
|
||
course_id: 'course_leadership',
|
||
course_title: 'Leading a Floor Team',
|
||
skill: 'Team Leadership',
|
||
worker_email: 'maria.gonzalez@example.com',
|
||
worker_name: 'Maria Gonzalez',
|
||
type: 'video',
|
||
media_url: '',
|
||
transcript: 'Pre-shift briefing for eight servers covering sections, coursing timing, and the VIP head table.',
|
||
ai_verdict: 'verified',
|
||
ai_score: 89,
|
||
ai_rubric: { 'Assigns clear ownership': 92, 'Communicates timing': 90, 'Sets a tone people follow': 85 },
|
||
ai_feedback: 'Assignments were unambiguous and the timing was concrete. Could invite more questions at the close.',
|
||
supervisor_verified: true,
|
||
supervisor_name: 'Luis Ortega',
|
||
verified_date: iso('2026-07-15'),
|
||
created_date: iso('2026-07-14'),
|
||
},
|
||
{
|
||
id: 'ev_iliana_service',
|
||
course_id: 'course_service_basics',
|
||
course_title: 'Fine Dining Service Standards',
|
||
skill: 'Coursed Table Service',
|
||
worker_email: 'iortega@legendaryeventstaff.com',
|
||
worker_name: 'Iliana Ortega',
|
||
type: 'roleplay',
|
||
media_url: '',
|
||
transcript: 'Apologized, offered to check with the kitchen, and returned with a timing update.',
|
||
ai_verdict: 'verified',
|
||
ai_score: 78,
|
||
ai_rubric: { 'Acknowledges without excuses': 82, 'Offers a concrete remedy': 74, 'Protects the table experience': 78 },
|
||
ai_feedback: 'Good instinct to go straight to the kitchen. Commit to a specific remedy rather than only an update.',
|
||
supervisor_verified: false,
|
||
created_date: iso('2026-07-28'),
|
||
},
|
||
];
|
||
|
||
/* ── Activity log ──────────────────────────────────────────────────────── */
|
||
|
||
const ACTIVITY_EVENTS = [
|
||
['create_position', 'demo@krow.app', 'Alex Rivera', 'employer', 'Created Banquet Captain – Hotel Events', '2026-07-18'],
|
||
['create_position', 'demo@krow.app', 'Alex Rivera', 'employer', 'Created Executive Chef – Catering', '2026-07-27'],
|
||
['apply_job', 'antoine.dubois@email.com', 'Chef Antoine Dubois', 'talent', 'Applied to Executive Chef – Catering', '2026-07-24'],
|
||
['apply_job', 'marcus.w@email.com', 'Marcus Williams', 'talent', 'Applied to Event Security Officer', '2026-07-24'],
|
||
['apply_job', 'marco.rivera@email.com', 'Marco Rivera', 'talent', 'Applied to Experienced Bartender – Corporate Events', '2026-07-24'],
|
||
['screen_candidate', 'demo@krow.app', 'Alex Rivera', 'employer', 'AI screened 3 candidates', '2026-07-24'],
|
||
['hire_candidate', 'demo@krow.app', 'Alex Rivera', 'employer', 'Hired Chef Antoine Dubois', '2026-07-25'],
|
||
['hire_candidate', 'demo@krow.app', 'Alex Rivera', 'employer', 'Hired Marcus Williams', '2026-07-25'],
|
||
['hire_candidate', 'demo@krow.app', 'Alex Rivera', 'employer', 'Hired Marco Rivera', '2026-07-25'],
|
||
['apply_job', 'sofia.mendez@email.com', 'Sofia Mendez', 'talent', 'Applied to Event Server – Fine Dining', '2026-08-02'],
|
||
['screen_candidate', 'demo@krow.app', 'Alex Rivera', 'employer', 'AI screened Sofia Mendez', '2026-08-05'],
|
||
['start_interview', 'tanya.cruz@email.com', 'Tanya Cruz', 'talent', 'Completed AI interview', '2026-08-05'],
|
||
['login', 'demo@krow.app', 'Alex Rivera', 'employer', '', '2026-08-06'],
|
||
['signup', 'new.demo2@example.com', 'New Talent Demo', 'talent', '', '2026-08-05'],
|
||
['login', 'maria.gonzalez@example.com', 'Maria Gonzalez', 'talent', '', '2026-08-06'],
|
||
];
|
||
|
||
const USER_ACTIVITY = ACTIVITY_EVENTS.map(([event_type, user_email, user_name, account_type, details, date], i) => ({
|
||
id: `act_${i + 1}`,
|
||
event_type,
|
||
user_email,
|
||
user_name,
|
||
account_type,
|
||
details,
|
||
created_date: iso(date),
|
||
}));
|
||
|
||
/* ── Signed-in demo user ───────────────────────────────────────────────── */
|
||
|
||
export const DEMO_USER = {
|
||
id: 'user_demo',
|
||
full_name: 'Alex Rivera',
|
||
email: 'demo@krow.app',
|
||
role: 'admin',
|
||
account_type: 'employer',
|
||
created_date: iso('2026-06-01'),
|
||
/* Product preferences travel with the account rather than in a store of their
|
||
own, so there is one record to persist and one thing to read. */
|
||
preferences: {
|
||
owliverDefault: true,
|
||
compactDensity: false,
|
||
emailDigest: true,
|
||
},
|
||
};
|
||
|
||
/* ── Assignments ───────────────────────────────────────────────────────────
|
||
Who is on which position, and until when — the record that turns a hire into
|
||
workforce allocation, and the one that says who is therefore not free for
|
||
anything else.
|
||
|
||
Empty by design. This deployment has no assignment records yet: they are
|
||
written by the assignment flow, not shipped as seed. The engine reads an
|
||
empty set correctly — every position simply reports nobody assigned — and
|
||
the UI omits the demand figures rather than inventing coverage that does
|
||
not exist. */
|
||
const ASSIGNMENTS = [];
|
||
|
||
export const seedData = {
|
||
JobPosting: JOB_POSTINGS,
|
||
JobApplication: JOB_APPLICATIONS,
|
||
AIInterview: AI_INTERVIEWS,
|
||
Staff: STAFF,
|
||
WorkerProfile: WORKER_PROFILES,
|
||
Course: COURSE_LIBRARY,
|
||
Badge: BADGES,
|
||
LearningPath: LEARNING_PATHS,
|
||
Certification: CERTIFICATIONS,
|
||
RoleCategory: ROLE_CATEGORIES,
|
||
UserActivity: USER_ACTIVITY,
|
||
Assignment: ASSIGNMENTS,
|
||
Evidence: EVIDENCE,
|
||
User: [DEMO_USER],
|
||
};
|