fix(compare): expert sign-off must-fixes — phase-matched admissions, Ofsted sentinel codes, selective-school copy
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m53s

M1: admissions rounds are now selected by the active phase tab
(admissionsForPhase) — an all-through school's Year 7 round no longer
masquerades as Reception odds beside pure primaries; honest per-cell and
section fallbacks name the round (Reception / Year 7).
M2: Ofsted sentinel codes (9 = not applicable) never render as judgement
chips, and the sixth-form judgement — previously dropped — now renders
for schools that have one.
M3: 'What this means' is phase- and type-aware: selective schools get
entrance-test framing, secondary faith schools a faith-criteria note, and
the primaries' distance template never appears on the secondary tab
(admissions_policy now exposed in compare school_info).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
This commit is contained in:
Tudor
2026-07-17 12:40:42 +01:00
co-authored by Claude Fable 5
parent 163b501be6
commit 5944d88f0b
11 changed files with 300 additions and 11 deletions
+35
View File
@@ -143,6 +143,41 @@ export interface AdmissionsSummary {
interest: string | null;
}
/**
* Pick the admissions round for the ACTIVE phase tab. An all-through school
* can carry only a Year 7 (Secondary) round — rendering that beside pure
* primaries' Reception rounds made 433-forms-for-173-places read as
* Reception odds. Rows matching the target phase win (latest year first);
* rows tagged with the OTHER phase are never substituted. Untagged rows
* (legacy data, no school_phase) are used only when no row carries a phase.
*/
export function admissionsForPhase(
data:
| { admissions?: SchoolAdmissions | null; admissions_history?: SchoolAdmissions[] }
| null
| undefined,
isSecondary: boolean,
): SchoolAdmissions | null {
if (!data) return null;
const rows: SchoolAdmissions[] = [
...(data.admissions_history ?? []),
...(data.admissions ? [data.admissions] : []),
];
if (rows.length === 0) return null;
const target = isSecondary ? 'secondary' : 'primary';
const byYearDesc = (a: SchoolAdmissions, b: SchoolAdmissions) => (b.year ?? 0) - (a.year ?? 0);
const matching = rows
.filter((r) => r.school_phase?.toLowerCase() === target)
.sort(byYearDesc);
if (matching.length > 0) return matching[0];
const tagged = rows.some((r) => r.school_phase != null);
if (!tagged) return [...rows].sort(byYearDesc)[0];
return null;
}
export function summariseAdmissions(
a: SchoolAdmissions | null | undefined,
): AdmissionsSummary {