// Shared employer-facing talent insights: ESAT, recent job history, and // client endorsements. Used by both the talent card and the talent detail // modal so the two stay in sync. import type { WorkerProfile } from '@/types/entities'; /** * `Partial`, because the callers render before the profile has loaded and every * read here is already guarded (`profile?.experience || []`). * * `experience` is a `jsonb` column. The registry types it `unknown`, correctly: * what sits inside a jsonb column is not in `information_schema`. This module * reads `.role` and `.company` off its entries, so it is narrowed to `any[]` — * an array whose elements are unchecked. Declaring a shape for those elements * would be inventing one, and the compiler would then defend the guess. */ type WorkerProfileRecord = Partial & { experience?: any[]; }; /** One derived endorsement row, as the talent card and detail modal render it. */ export interface ClientEndorsement { company: string; role: string; stars: number; } // ESAT — Employee Skills Assessment Transcript; derived from AI interview score export function esatTag(profile: WorkerProfileRecord) { const s = Math.round(profile?.ai_interview_score || 0); if (s > 0) return { label: `${s}/100`, cls: 'bg-[#FFF7ED] text-[#B45309]' }; return { label: 'Pending', cls: 'bg-[#F3F4F6] text-[#6B7280]' }; } // Recent job history (last 3 years). experience entries carry a duration // (`years`) rather than dates, so we surface the most recent up to 3. export function recentJobs(profile: WorkerProfileRecord) { return (profile?.experience || []).slice(0, 3).filter((e) => e && (e.role || e.company)); } // Up to 3 client endorsements, deterministically derived from companies the // worker has been placed at, rated off their aggregate client rating. export function clientEndorsements(profile: WorkerProfileRecord): ClientEndorsement[] { const companies = (profile?.experience || []) .map((e) => e?.company) .filter(Boolean); const rating = profile?.client_rating || profile?.supervisor_rating || 5; const stars = Math.max(1, Math.min(5, Math.round(rating))); const roles = ['Event Director', 'Operations Lead', 'GM', 'Owner', 'HR Partner']; if (companies.length === 0) return []; return companies.slice(0, 3).map((c, i) => ({ company: c, role: roles[i % roles.length], stars, })); }