fix: don't portray special schools as failing the mainstream benchmark
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m8s
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 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m1s
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m8s
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 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m1s
Special schools, PRUs and alternative provision teach pupils with SEND who sit the same KS2/KS4 assessments but very few reach the mainstream "expected standard". Their headline attainment is therefore ~0% (or a very low Attainment 8), and the site was comparing that to the England average and painting it red — e.g. Greenmead School (a community special school) rendered as "0.0% — −62 pts below England average" with three 0% red SATs bars. That portrays a special school as catastrophically failing against a benchmark that doesn't fit it. Add a shared `isSpecialSchool()` helper (detects every DfE special-school establishment type — all contain "special" — plus PRUs / alternative provision) and drop the mainstream England comparison + "below" framing for these schools across every surface: - Detail (primary + secondary): a plain-English context note explaining the school is special and why the comparison isn't shown; England-average delta chips, "England avg" hints, the SATs national markers, the Attainment-8 "vs national" bar and the trend chart's England overlay are all suppressed. An all-zero placeholder SATs row hides the (empty) subject bar chart and the "why is combined lower" bridge. - Rankings / search rows (primary + secondary): the mainstream RWM / Attainment 8 stat shows "—" with no "vs national" delta, instead of "0% · −62 vs national". - Compare: special schools' attainment values are dropped (no misleading dot at 0% / no "Below England average" chip); progress banding, which IS a fair measure for special schools, is kept. Belt-and-braces zero-guard: a whole-row zero attainment (special or a suppressed cohort) is also treated as not-comparable, while a legitimate single 0 (e.g. 0% exceeding at a mainstream school) stays comparable. Tests: new isSpecialSchool unit tests (every DfE special type matched, no mainstream false positives); an e2e journey asserts Greenmead shows the special-school note and no England-average comparison. tsc clean; 108/108 unit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
import type { School } from '@/lib/types';
|
||||
import { formatPercentage, calculateTrend, getPhaseStyle, schoolUrl, buildOfstedListBadge, formatAgeRange, isProposedToClose } from '@/lib/utils';
|
||||
import { formatPercentage, calculateTrend, getPhaseStyle, schoolUrl, buildOfstedListBadge, formatAgeRange, isProposedToClose, isSpecialSchool } from '@/lib/utils';
|
||||
import styles from './SchoolRow.module.css';
|
||||
|
||||
interface SchoolRowProps {
|
||||
@@ -38,10 +38,19 @@ export function SchoolRow({
|
||||
school.religious_denomination &&
|
||||
school.religious_denomination !== 'Does not apply';
|
||||
|
||||
// Special schools / PRUs / AP: the mainstream RWM measure and its England
|
||||
// comparison aren't a fair judgement (their pupils have SEND), so a "0% ·
|
||||
// −62 vs national" row misrepresents them. Treat the mainstream stat as not
|
||||
// comparable — same for a placeholder all-zero value.
|
||||
const rwmComparable =
|
||||
school.rwm_expected_pct != null &&
|
||||
school.rwm_expected_pct !== 0 &&
|
||||
!isSpecialSchool(school);
|
||||
|
||||
// vs-national delta
|
||||
const rwmDelta =
|
||||
school.rwm_expected_pct != null && nationalAvgRwm != null
|
||||
? Math.round(school.rwm_expected_pct - nationalAvgRwm)
|
||||
rwmComparable && nationalAvgRwm != null
|
||||
? Math.round((school.rwm_expected_pct as number) - nationalAvgRwm)
|
||||
: null;
|
||||
|
||||
const handleCompareClick = () => {
|
||||
@@ -87,9 +96,9 @@ export function SchoolRow({
|
||||
<div className={styles.line3}>
|
||||
<span className={styles.stat}>
|
||||
<strong className={styles.statValue}>
|
||||
{school.rwm_expected_pct != null ? formatPercentage(school.rwm_expected_pct, 0) : '—'}
|
||||
{rwmComparable ? formatPercentage(school.rwm_expected_pct, 0) : '—'}
|
||||
</strong>
|
||||
{school.prev_rwm_expected_pct != null && (
|
||||
{rwmComparable && school.prev_rwm_expected_pct != null && (
|
||||
<span
|
||||
className={`${styles.trend} ${styles[`trend${trend.charAt(0).toUpperCase() + trend.slice(1)}`]}`}
|
||||
title={`Previous year: ${formatPercentage(school.prev_rwm_expected_pct)}`}
|
||||
|
||||
Reference in New Issue
Block a user