-
released this
2026-10-01 13:59:56 +00:00 | 40 commits to main since this releasePhase 3: Placement Reporting
The guiding outcome becomes measurable: distinct-learner counts computed from rows at query time (per employer, per start-date cohort month, cumulative toward the 1,000 north star).
What shipped
- GET /v1/placements/admin/overview (D-107):
total_active_placements,distinct_learners_placed(a learner placed twice counts ONCE — the outcome's noun is learners),guiding_goal: 1000,by_employer(count desc),by_cohort_month(the start_date calendar month, ascending). Revoked placements excluded from every count; every count computed from rows — never a denormalized counter. - GET /v1/employers/placements: the claimed entity's own placements (active + revoked history, honest empty state; session + claim gates).
packages/types/placement.ts(D-110): the fourth cross-boundary wire module, dual-schema pinned field-for-field againstplacements/base.pyinpins.test.ts(4 new pins incl. the seven-status union regex + the G-319 pin-split arm).- The engine-client placements section:
listOwnEmployerApplications, the five per-target transition functions,listOwnEmployerPlacements— AbortController everywhere, SessionRequiredError/ClaimRequiredError reuse, zero new error classes. - The NEW /employer/applications page (D-109 surface 1): the seven D-099 status badges, per-target transition CTAs (the matrix drives the CTA set), the hire form with employer-attested role title + employment start date; learner_id visible per the G-319 supersession (own applicants only); withdraw never offered to employers.
- The overview's real placements section replaces the mock "Placement Rate" card (D-092: never leave a convertible surface on mock); talent-match analytics stay mock-labeled honestly.
Verification
- 1096 ai-service tests (+7), 105 web (+4 pins), 87 CLI — all green, zero warnings; mypy clean (236 files); eslint 9/9; the static export builds.
- Verify four layers PASS; the counts-discipline check: zero denormalized counters anywhere.
Downloads
- GET /v1/placements/admin/overview (D-107):