fix(detail): compare each SATs bar to its own national benchmark #76

Merged
tudor merged 1 commits from fix/sats-per-level-national into main 2026-07-21 13:56:55 +00:00
Owner

Summary

On a school page, the KS2 SATs chart drew a single national-average line across the full height of each subject, positioned at the national expected value — but that area stacks two bars (Expected and Exceeding). The national higher standard / greater depth figure is a very different, much lower number (reading higher standard ~29% vs expected ~75%), so the line crossed the Exceeding bar at completely the wrong place, making every school's exceeding result look far below national when it wasn't.

The data was already calculated

The per-subject higher-standard nationals already live in the fact_ks2_national_averages mart (reading_high_pct, writing_gd_pct, maths_high_pct) — they simply weren't serialized into the API. No recalculation needed.

Changes

  • Backend (app.py): add reading_high_pct, writing_gd_pct (writing = greater depth), maths_high_pct to the national-averages payload. New test guards they're surfaced.
  • SchoolDetailView: pass a nationalExceedingPct per subject, mapping writing to the greater-depth figure.
  • SatsChart: replace the single full-height line with a national marker on each bar's own track — a coral tick plus a nat X% label in the bar header — so Expected and Exceeding each compare against the correct benchmark.

Scope: KS2 only, as agreed. The secondary Attainment 8 chart uses one line for one measure and is untouched. Special/suppressed schools still drop the markers (both nationals pass null).

Visual

Each bar now carries its own marker; the Exceeding bars sit against ~29% / 13% / 24% instead of the misplaced ~72–75% expected line. (Preview shared in the conversation.)

Testing

  • tsc --noEmit and next build — clean
  • Backend pytest backend/tests/test_national_averages_marts.py — 3 passed (incl. the new per-subject test)

🤖 Generated with Claude Code

https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB

## Summary On a school page, the KS2 SATs chart drew a **single national-average line** across the full height of each subject, positioned at the national **expected** value — but that area stacks **two** bars (Expected and Exceeding). The national *higher standard / greater depth* figure is a very different, much lower number (reading higher standard ~29% vs expected ~75%), so the line crossed the Exceeding bar at completely the wrong place, making every school's exceeding result look far below national when it wasn't. ## The data was already calculated The per-subject higher-standard nationals already live in the `fact_ks2_national_averages` mart (`reading_high_pct`, `writing_gd_pct`, `maths_high_pct`) — they simply weren't serialized into the API. No recalculation needed. ## Changes - **Backend** (`app.py`): add `reading_high_pct`, `writing_gd_pct` (writing = *greater depth*), `maths_high_pct` to the national-averages payload. New test guards they're surfaced. - **SchoolDetailView**: pass a `nationalExceedingPct` per subject, mapping writing to the greater-depth figure. - **SatsChart**: replace the single full-height line with a **national marker on each bar's own track** — a coral tick plus a `nat X%` label in the bar header — so Expected and Exceeding each compare against the correct benchmark. **Scope:** KS2 only, as agreed. The secondary Attainment 8 chart uses one line for one measure and is untouched. Special/suppressed schools still drop the markers (both nationals pass `null`). ## Visual Each bar now carries its own marker; the Exceeding bars sit against ~29% / 13% / 24% instead of the misplaced ~72–75% expected line. (Preview shared in the conversation.) ## Testing - `tsc --noEmit` and `next build` — clean - Backend `pytest backend/tests/test_national_averages_marts.py` — 3 passed (incl. the new per-subject test) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
tudor added 1 commit 2026-07-21 13:56:01 +00:00
fix(detail): compare each SATs bar to its own national benchmark
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 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
8a9ba30cc2
The KS2 SATs chart drew a single national-average line spanning the
full height of each subject's chart area, positioned at the national
*expected* value. But the area stacks two bars — Expected and Exceeding
— and the higher-standard/greater-depth national is a very different,
much lower figure (e.g. reading higher standard ~29% vs expected ~75%).
So the line crossed the Exceeding bar at the wrong place, making every
school's exceeding result look far below national when it wasn't.

The per-subject higher-standard nationals were already computed in the
fact_ks2_national_averages mart; they just weren't serialized. Fix:

- backend: add reading_high_pct, writing_gd_pct (writing = greater
  depth) and maths_high_pct to the national-averages payload.
- SchoolDetailView: pass a nationalExceedingPct per subject, mapping
  writing to the greater-depth figure.
- SatsChart: replace the single full-height line with a national marker
  on each bar's own track (coral tick + "nat X%" in the bar header), so
  Expected and Exceeding each sit against the correct benchmark.

KS2 only; the secondary Attainment 8 chart already uses one line for
one measure and is untouched.

Verified: tsc --noEmit, next build, and backend pytest (national
averages marts, incl. a new test guarding the per-subject nationals).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
tudor merged commit 3132f07af2 into main 2026-07-21 13:56:55 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tudor/school_compare#76