fix(review): accurate PRU/AP copy, unbundle same-school trend, de-dupe note CSS
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 12s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m38s

Three review points on the special-schools change:

1. Copy accuracy — the context note said "Its pupils have special educational
   needs" for every isSpecialSchool() match, but the helper also matches pupil
   referral units and alternative provision, whose pupils are educated outside
   a mainstream setting (e.g. after exclusion) and are not necessarily SEND.
   Extracted a shared <SpecialSchoolNote> with type-aware copy: SEND wording
   only for genuine special schools; PRUs/AP get their own accurate wording.

2. Same-school trend was conflated with the England comparison — SchoolRow's
   year-over-year trend arrow (and the school's own figure) were gated on the
   same flag that drops the vs-England delta, hiding a still-meaningful trend
   for special schools with real data. Split the two: the school's OWN RWM
   figure + trend show whenever there's a real value (special schools
   included; only a placeholder all-zero row is hidden); only the vs-England
   delta is additionally dropped for special/PRU/AP. Mirrored in
   SecondarySchoolRow (own Attainment 8 shown; only the vs-LA delta dropped).

3. De-duplicated the .specialNote CSS (was copy-pasted between the two detail
   view module files) into SpecialSchoolNote.module.css, owned by the shared
   component so it can't drift.

New SpecialSchoolNote unit tests assert SEND wording for special schools and
NOT for PRUs/AP. tsc clean; 112/112 unit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
This commit is contained in:
Tudor
2026-07-20 22:09:32 +01:00
co-authored by Claude Opus 4.8
parent de943ded19
commit 0b36eace9d
9 changed files with 134 additions and 79 deletions
+8 -9
View File
@@ -55,15 +55,14 @@ export function SecondarySchoolRow({
const ofstedBadge = buildOfstedListBadge(school);
const phase = getPhaseStyle(school.phase);
const att8 = school.attainment_8_score;
// Special schools / PRUs / AP: Attainment 8 vs the LA average isn't a fair
// comparison (their pupils have SEND), so drop the delta and the number
// rather than show them trailing "the average" by design. Attainment 8 is a
// single 080 score with no subject breakdown to test for a placeholder, so
// this keys off establishment type only — a genuine (if extreme) 0.0 at a
// mainstream school still shows its real value.
const att8Comparable = att8 != null && !isSpecialSchool(school);
// The school's own Attainment 8 is a same-school figure — shown whenever it
// exists (special schools included; their type tag on line 2 gives context).
// Only the vs-LA-average delta, a benchmark comparison, is dropped for
// special schools / PRUs / AP, whose pupils aren't measured against it fairly.
const laDelta =
att8Comparable && laAvgAttainment8 != null ? (att8 as number) - laAvgAttainment8 : null;
att8 != null && !isSpecialSchool(school) && laAvgAttainment8 != null
? att8 - laAvgAttainment8
: null;
const admissionsTag = detectAdmissionsTag(school);
const sixthForm = hasSixthForm(school);
@@ -113,7 +112,7 @@ export function SecondarySchoolRow({
<div className={styles.line3}>
<span className={styles.stat}>
<strong className={styles.statValueLarge}>
{att8Comparable ? (att8 as number).toFixed(1) : '—'}
{att8 != null ? att8.toFixed(1) : '—'}
</strong>
<span className={styles.statLabel}>Attainment 8</span>
</span>