// screenMATCH API client: every call targets the /api/screenmatch namespace over the ONE shared // scoring core, so a candidate qualified here shows the same numbers as in slateMATCH and missionMATCH. // It reuses the shared request helper (session cookie, CSRF, error handling); only the paths differ, so // this module could later be extracted with its client intact. import { request } from '../../lib/api' import type { AioeStatus, CandidateListView, OpportunityFitView, OutcomeInput, RankedCandidateView, RequirementListView, ScreenView, TermView, } from '../../lib/types' const NS = '/screenmatch' export const screenApi = { requirements: () => request(`${NS}/requirements?limit=200`), requirement: (id: string) => request(`${NS}/requirements/${encodeURIComponent(id)}`), candidate: (id: string) => request(`${NS}/candidates/${encodeURIComponent(id)}`), // POST /screen is the full explainable qualification; the server persists it as the latest evaluation. screen: (candidate_id: string, requirement_id: string) => request(`${NS}/screen`, { method: 'POST', body: JSON.stringify({ candidate_id, requirement_id }), }), // Screen the whole pool against one requirement (the Candidate Screening Queue), ranked best first. rankCandidates: (requirementId: string) => request(`${NS}/requirements/${encodeURIComponent(requirementId)}/candidates`), opportunities: (candidateId: string) => request(`${NS}/candidates/${encodeURIComponent(candidateId)}/opportunities?limit=10`), // The closed loop: one click screening outcomes feed the optimization engine (flat namespace). recordOutcome: (o: OutcomeInput) => request<{ id: string; occurredAt: string }>('/outcomes', { method: 'POST', body: JSON.stringify(o) }), // The acronym and term expansion layer (global GovCon seed plus tenant additions). aliases: () => request<{ terms: TermView[] }>('/aliases'), addAlias: (alias: string, expansion: string) => request('/aliases', { method: 'POST', body: JSON.stringify({ alias, expansion }) }), deleteAlias: (id: string) => request(`/aliases/${encodeURIComponent(id)}`, { method: 'DELETE' }), // Admin proof the engine is alive. aioeStatus: () => request('/aioe/status'), // Human promotion of a pending candidate weight profile (ends shadow mode for the tenant). aioePromote: () => request<{ promotedVersion: number; message: string }>('/aioe/promote', { method: 'POST' }), }