955659580067ca8b81bd77e31e4e2554103f094d
638
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9556595800 |
feat(security): allow analytics subdomain to iframe the site
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 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 8s
Replace X-Frame-Options: SAMEORIGIN with a CSP frame-ancestors directive so analytics.schoolcompare.co.uk (Umami heatmap/recorder) can embed the site while all other origins stay blocked. X-Frame-Options cannot allow a specific sibling subdomain (ALLOW-FROM is deprecated/ignored by modern browsers), so frame-ancestors is the correct replacement. Also update the nginx snippet in DEPLOYMENT.md to match, so the reverse proxy doesn't re-inject a conflicting X-Frame-Options header. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
d02a323cdc |
Merge pull request 'fix(detail): give Results Over Time chart more height on desktop' (#78) from fix/detail-trend-chart-taller into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 58s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m13s
Reviewed-on: #78 |
||
|
|
32f8a02862 |
fix(detail): give Results Over Time chart more height on desktop
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m6s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 13s
The trend chart was capped at 280px tall on desktop, squishing the lines together and making them hard to read. Raise the base .chartContainer height to 380px in both the primary and secondary detail views. Mobile is unaffected: the base value is already overridden to height:auto by the existing max-width:768px query, where PerformanceChart's own .chartWrapper carries the canvas height. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
7e3096c881 |
Merge pull request 'feat(analytics): load Umami heatmap recorder' (#77) from feat/umami-heatmap-recorder into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 15s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 54s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 47s
Reviewed-on: #77 |
||
|
|
1f80571b1f |
feat(analytics): load Umami heatmap recorder
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 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 42s
Adds the Umami session recorder (recorder.js) that powers heatmaps, alongside the existing analytics tracker. Loaded via next/script with the same data-domains guard as the main tracker so it only fires on the production hostnames — staging runs the same image under a different host and must not feed the heatmap. Cookieless: recorder.js uses Umami's server-side session model (no cookie or local storage on the device), so it adds no new PECR consent trigger. Verified with tsc --noEmit and next build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
3132f07af2 |
Merge pull request 'fix(detail): compare each SATs bar to its own national benchmark' (#76) from fix/sats-per-level-national into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 20s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #76 |
||
|
|
8a9ba30cc2 |
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
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 |
||
|
|
388b496cc5 |
Merge pull request 'feat(admissions): surface easy-to-miss deadlines as callout boxes' (#75) from fix/rankings-admissions-accuracy into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #75 |
||
|
|
15da060e4a |
feat(admissions): surface easy-to-miss deadlines as callout boxes
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
The selective-school registration and faith-school SIF warnings were added as prose in the criteria steps, where they read as ordinary sentences and were easy to skim past. Pulled them into structured callout boxes with an amber "note" treatment (using the page's own gold accent tokens), a warning glyph, and a bold lead-in — so the two deadlines parents most often miss actually stand out. - Added a `callouts` field to Step; render as a callout group between the body and the tool link (both primary and secondary timelines). - Reverted the warning text back out of the step bodies so it isn't duplicated. Verified with tsc --noEmit and next build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
5981916b82 |
Merge pull request 'fix(rankings,admissions): correct education-accuracy audit findings' (#74) from fix/rankings-admissions-accuracy into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #74 |
||
|
|
a5b2296240 |
fix(rankings,admissions): correct accuracy issues from education audit
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
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 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m11s
Follow-up audit of the rankings and admissions pages. Admissions (AdmissionsView.tsx): - National Offer Day no longer claims offers publish "from 12:01 am"; release times are set per-council (often late afternoon, some overnight), so it now tells parents to check their council's page. - Secondary preference count no longer states a flat "up to six" (that's London/Pan-London); most LAs allow three to six. Mirrors the hedge the primary step already used. - Added the two deadlines that most often catch parents out: selective schools' separate entrance-test registration (months earlier), and faith schools' supplementary information form sent direct to the school. Covered in both the primary and secondary criteria steps. - Reworded the equal-preference tip so it's precise: order is the tie-break among schools you qualify for (you get the highest-ranked one), not irrelevant. Rankings (RankingsView.tsx): - Subtitle "Top-performing schools by X" -> "Schools ranked by X", so it isn't nonsensical for context/equity/absence metrics. - KS2 progress isn't published for 2023/24 or 2024/25 (no KS1 baseline). Selecting a primary progress metric on a recent year used to dead-end on a generic "No rankings found". Added a scoped caveat to the progress hint and an explanatory empty-state (primary only — secondary Progress 8 is published). Added an admissions smoke journey (static content, stable milestones). Verified with tsc --noEmit and next build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
af23fbf27e |
Merge pull request 'fix(home): correct education/Ofsted claims on the landing page' (#73) from fix/homepage-education-accuracy into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 51s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 43s
Reviewed-on: #73 |
||
|
|
22e9eb2d48 |
fix(home): make Att8 bar match its numbers and separate safeguarding
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m6s
Two internal-consistency fixes on the "What you'll see" mock: - The Attainment 8 bar had drifted from the numbers beside it (fill 68% / line 57% vs a 54.8 score and 45.9 national avg). Restored the mock's original 1:1 value-to-percent mapping: fill 54.8%, national line 45.9%. - The report card grouped "Safeguarding: Met" in the same five-point list as the graded areas, but safeguarding is a separate binary met/not-met judgement under the real framework. Moved it below the list behind a divider, with an outlined chip and a "separate check" label so it no longer reads as a graded area. Verified with tsc --noEmit and next build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
13253116c2 |
fix(home): correct remaining KS2/Ofsted terminology on the landing page
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
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 41s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m35s
Follow-up to the accuracy pass — the medium-severity wording issues from the same expert review: - KS2 "Exceeding" isn't a DfE term. The above-expected level is the "higher standard" for the reading and maths tests and "greater depth" for teacher-assessed writing. Labelled per subject, and brought the illustrative reading value down from an implausible 73% (national higher standard is ~29%) to a realistic strong-school figure. - Attributed inspection outcomes to Ofsted, not only the DfE (Ofsted is a separate non-ministerial department). - Hero: "2026/2027 admissions results" -> "the 2026/27 admissions round" (admissions produce offers, not results, and we don't hold per-school offer outcomes). Tightened .miniRowHead so the longer "Greater depth" label stays on one line and the three subject columns keep their bars aligned (the visual is desktop-only; hidden on mobile). Verified with tsc --noEmit and next build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
1b8adb91ee |
fix(home): correct education/Ofsted claims on the landing page
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 12s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 37s
Homepage marketing content had drifted from both the current education regime and the app's own school pages. An expert accuracy review surfaced five issues (3 critical, 2 high): - Ofsted card showed a single "OUTSTANDING" word-grade. Overall grades were abolished (Sept 2024) and inspections now produce a report card on a five-point scale (from Nov 2025). Rebuilt the card as a report card with per-area ratings + stand-alone safeguarding, matching what CompareOfsted actually renders on a school page. - Attainment 8 "National avg 50.2" was wrong; the real 2024/25 figure is 45.9. Corrected the benchmark and the illustrative school value. - Compare mock featured a KS2 "Reading progress" score, but KS2 progress isn't published for 2023/24 or 2024/25 (no post-COVID KS1 baseline). Swapped for Higher standard (RWM), which is published. - Editorial called it "UK school performance data"; the data is England-only. Now matches the hero and page metadata. - Softened the "40-page inspection report" exaggeration. Landing-page copy isn't covered by e2e journeys, so no test changes. Verified with tsc --noEmit and next build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
ca4fc647a5 |
Merge pull request 'fix(detail): let the special-school note span the full container width' (#72) from fix/special-note-full-width into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 55s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 43s
Reviewed-on: #72 |
||
|
|
261403bcd2 |
fix(detail): let the special-school note span the full container width
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m1s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
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 13s
Drop the note's `max-width: 72ch`, which left it stopping well short of the section's right edge. It now fills the results-section container like the subtitle paragraph above it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
e4c8b86fe7 |
Merge pull request 'fix(detail): align Ofsted Report Card grade chips' (#71) from fix/report-card-chip-alignment into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 52s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #71 |
||
|
|
1c1df77961 |
fix(detail): align Ofsted Report Card grade chips
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 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 8s
The grade boxes rendered inconsistently: Safeguarding "Met" was a small
0.8125rem inline pill while grade values ("Strong") were 1.25rem full-width
chips, and because category labels wrap to one or two lines each value sat at
a different vertical position. Two-line values like "Expected standard" also
produced a taller box.
Add a scoped `.gradeGrid` modifier (Report Card + OEIF grids in both the
primary and secondary detail views) that reserves two label lines so every
chip shares a baseline, and gives all value chips one font size, padding and
min-height — long text wraps inside an equal-height chip via max-width:100%.
Scoped rather than touching the shared `.metricCard`/`.metricValue` used by
the finance, phonics and admissions sections.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
|
||
|
|
993822d769 |
Merge pull request 'fix: don’t portray special schools as failing the mainstream benchmark' (#70) from fix/special-schools-not-failing into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 7s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 3m40s
Reviewed-on: #70 |
||
|
|
0b36eace9d |
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 |
||
|
|
de943ded19 |
fix(review): don't suppress a genuine mainstream 0 in the rows
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m48s
Review feedback: the rankings/search rows treated any exactly-0 attainment as not comparable regardless of school type, so a genuine 0 at a mainstream school rendered as "—" (looks like missing data) and dropped its delta — stricter and inconsistent with SchoolDetailView's placeholder check. - SchoolRow: match SchoolDetailView's ks2Placeholder signature — suppress only when ALL of RWM + reading + writing + maths are 0 (special/suppressed signature), not on a bare rwm === 0. A genuine 0% combined (some pupils met individual subjects but not all three) is not all-zero, so it stays comparable and shows its real figure + trend. - SecondarySchoolRow: Attainment 8 is a single 0–80 score with no subject breakdown to form an all-zero signature, so key off establishment type only (drop the bare att8 === 0 guard). A genuine (if extreme) 0.0 shows its value + LA delta. - For consistency, apply the same to the detail views: drop the bare attainment_8_score === 0 guard (KS4 keys off isSpecial only); KS2 keeps the all-four-subjects-zero placeholder signature. Special schools / PRUs / AP are still handled via isSpecialSchool everywhere. tsc clean; 108/108 unit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
ae6ef6860b |
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
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 |
||
|
|
4e316b4e38 |
Merge pull request 'fix(detail): label the phase of all-through admissions figures (Batch F review fix)' (#69) from fix/detail-allthrough-admissions-phase into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 52s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 56s
Reviewed-on: #69 |
||
|
|
733faefb98 |
fix(detail): label which phase all-through admissions figures cover (Batch F)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m9s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 43s
Final Ofsted/education-expert review of the detail page (Batch F) found one
clarity gap: on an all-through school the Admissions block shows a single
entry point's figures (Hessle's are the Year 7 secondary intake —
admissions.school_phase = "Secondary") but is titled just "Admissions", so a
parent interested in the reception/primary intake could read the Year 7
numbers as the whole school.
Add a phase subtitle for all-through schools ("These figures are for secondary
entry (Year 7)." / "...primary entry (Reception)."). Pure-primary and
pure-secondary pages are unambiguous and unchanged.
Rest of the review verified correct against source payloads: all three Ofsted
regimes (report card / ungraded post-Sept-2024 / carried-forward), England-
average anchoring, gap-honest trend charts (KS2 + KS4), all-through dual-phase
rendering, and the mobile layout.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
|
||
|
|
5e370d09f1 |
Merge pull request 'fix(detail): render both phases for all-through schools (Batch E)' (#68) from fix/detail-all-through into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 48s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 56s
Reviewed-on: #68 |
||
|
|
f6bb037c47 |
fix(detail): render both phases for all-through schools (Batch E)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
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 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 57s
Batch E of applying the compare-screen learnings to the school detail page — all-through handling (point 11). An all-through school carries both KS2 and KS4 figures in the same yearly rows, but SchoolDetailView flipped it to isSecondary and rendered GCSE-only, hiding the entire primary phase (SATs, phonics, KS2 trend). The Results snapshot already gated its KS2/KS4 blocks purely on data availability, so both already appeared there — but the section title, the trend chart, phonics, the nav label and the history table all still assumed a single phase. - Add an explicit `isAllThrough` flag (+ `showPrimaryContent = isPrimary || isAllThrough`); pure-secondary behaviour is unchanged. - Hero: an "All-through (primary & secondary)" meta chip for all-ages framing. - Results section: title "SATs & GCSE Results", a combined subtitle, and "Primary — KS2 SATs (Year 6)" / "Secondary — GCSEs (Year 11)" sub-headings separating the two blocks. - Results Over Time: render two stacked PerformanceCharts (KS2 SATs + GCSEs) rather than crowding both stages' series — on different scales with different gap stories — onto one axis. Each gets its correct England overlay. - Phonics section + nav item now show for all-through (primary-stage metric). - History table: an all-through column set covering both phases (RWM, Exceeding, Attainment 8, Progress 8, Eng & Maths 4+). - Nav "Results" label for all-through instead of "GCSEs". e2e: a new journey asserts an all-through school (Hessle, 137306) shows both the KS2 and KS4 results and the All-through label, with a data-driven precondition skip if staging data drifts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
9c93c3d9c2 |
Merge pull request 'fix(detail): gap-honest year axis on the detail-page trend charts (Batch D)' (#67) from fix/detail-chart-truthfulness into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 56s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #67 |
||
|
|
17bd4d5a5e |
fix(detail): gap-honest year axis on the detail-page trend charts (Batch D)
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 12s
PR Checks / Build Frontend (no push) (pull_request) Successful in 50s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 2m38s
Applies the compare screen's chart-truthfulness rules (spec §8.1) to the school detail page's time-series charts. PerformanceChart (Results Over Time, both phases): - Fill every academic year between the first and last data point via the shared fillAcademicYears helper, so cancelled/unpublished years (2019/20, 2020/21, and — for KS2 — 2021/22) render as real gaps instead of compressed time. Each series and the England overlay map onto this filled axis with null for missing years; spanGaps:false so school lines never bridge a gap. - Replace the primary-only COVID note with a distinct, honest gap caption: KS2 names the cancelled tests plus the unpublished 2021/22 school-level year; KS4 names the unpublished 2019/20–2020/21 GCSE grading years. - Mobile x-axis switches to autoSkip so the longer (gap-honest) axis stays readable; the broken line still marks a missing year even when its tick label is skipped. AdmissionsTrendChart: - Same gap-honest axis + spanGaps:false so a missing admissions year is a real gap, not compressed time. Point 12 (definite canvas heights): desktop is already a definite 280px; fix the secondary detail's mobile .chartContainer, which fixed the outer box at 220px and double-constrained PerformanceChart's own 220px canvas + chip strip (clipping the chips onto the plot) — now height:auto to match the primary view. SatsChart is out of scope (single-year per-subject CSS bars — no year axis, no canvas height to constrain). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
31ae13451a |
Merge pull request 'fix(detail): banded admissions + plain-English Progress 8 (Batch C)' (#66) from fix/detail-inclusion-admissions into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 15s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 49s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 42s
Reviewed-on: #66 |
||
|
|
4e6be0ce65 |
fix(detail): banded first-choice interpretation + plain-English P8 absence copy
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 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 24s
Batch C (points 7-10):
- Point 7: the admissions section shows the first-choice offer rate but no
sense of how severe a low rate is. Reuse the compare screen's banded
summariseAdmissions ('More than half of first choices missed out' etc.)
as an interpretive line under the tiles. (Selective/faith framing was
already present via admissionsTag.)
- Point 8: replace the jargon P8-suspended banner ('not used for
accountability purposes ... treat with caution') with the compare
screen's plain-English 'no KS2 baseline (COVID)' explanation.
- Points 9 (disadvantaged cohort sizes) and 10 (FSM benchmark) don't apply
to the detail page: it shows disadvantaged composition, not disadvantaged
attainment, and no FSM-vs-benchmark comparison — so there's no small-cohort
caveat or cross-definition fallback to fix here.
- Also fixed a stray lowercase 'national avg' provenance string Batch B
missed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
|
||
|
|
452ec77449 |
Merge pull request 'fix(detail): 'England average' provenance labelling (Batch B)' (#65) from fix/detail-provenance-anchoring into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 48s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 43s
Reviewed-on: #65 |
||
|
|
aa87fa917d |
Merge pull request 'fix(detail): Ofsted sentinel codes, sixth form, carried-forward labels (Batch A)' (#64) from fix/detail-ofsted-correctness into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 49s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 42s
Reviewed-on: #64 |
||
|
|
e36125b24a |
fix(detail): label official DfE figures as 'England average' (provenance)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m0s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 43s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 13s
Batch B (points 5-6): the detail page called every national figure a
'National avg'. All of them come from the official-DfE national-averages
marts (KS2/KS4 headlines), so they are England averages — relabel to
match the compare screen's provenance convention ('England average' for
official figures; the detail page has no computed benchmarks, so no
'state-school average (computed)' label is needed). Point 6 (anchoring
every number) is already satisfied on the detail page via DeltaChip.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
|
||
|
|
fdda52ff0a |
fix(detail): filter Ofsted sentinel codes, show sixth-form judgement, label carried-forward grades
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 11s
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 1m23s
Batch A of applying compare-screen learnings to the detail page (points 2-3):
- Point 2: the legacy OEIF sub-judgement grid rendered any non-null value
via OFSTED_LABELS[value], so Ofsted's sentinel code 9 ('not applicable')
leaked as an undefined label, and the sixth-form judgement was dropped
entirely. New shared ofstedLegacyAreas() helper returns only real grades
(1-4) and includes Sixth Form provision. Both detail views + the
all-same-grade check use it.
- Point 3: the OEIF disclaimer always claimed 'Ofsted no longer makes an
overall judgement' even when showing a carried-forward grade. It's now
grade_source-aware and labels carried-forward grades as such, matching
the compare screen.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
|
||
|
|
a2c63b3cda |
Merge pull request 'fix(list/map): report-card schools badged as Report Card, not their old grade' (#63) from fix/list-map-report-card-signal into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 21s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 54s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 41s
Reviewed-on: #63 |
||
|
|
b2b2cad5ac |
test/docs: harden report-card list e2e + correct badge docstring
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 9s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 1m4s
Review fixes on the list/map report-card PR: - e2e precondition now hard-asserts ofsted_rc_date instead of test.skip, so the backend dropping the field fails loudly (that's the regression under test), not silently skips. - Use page_size=5 (the real backend param); per_page was ignored and fell back to the default page size. - Update buildOfstedListBadge docstring to describe the ofsted_rc_date-based, report-card-wins-first detection instead of the removed framework check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
5ec4f3f7cd |
fix(list/map): badge report-card schools as Report Card, not their carried-forward grade
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m5s
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 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m48s
The search-result cards and map pins keyed report-card detection off
ofsted_framework === 'ReportCard', but the API sets ofsted_framework to the
raw event grouping ('Schools - S5'); worse, ofsted_grade (the carried-forward
legacy grade) was checked first and won. So report-card schools were badged
by their old grade — Barclay's pin/card read 'Outstanding · 2021' instead of
'Report Card · 2026'. Same root cause as the detail-page fix, different
surface.
Expose ofsted_rc_date on the list serialization (the report-card inspection
date, non-null only for report cards) and make both badge builders treat a
present rc-date as winning over any grade, using its year. Removes the dead
framework === 'ReportCard' branches.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
|
||
|
|
74bdbebd57 |
Merge pull request 'fix(detail): render & correctly date Ofsted report cards' (#62) from fix/detail-report-card-render-date into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 54s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 19s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 40s
Reviewed-on: #62 |
||
|
|
b31e71ac88 |
fix(detail): render report cards and date them by the report-card inspection
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 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 55s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m2s
The detail views detected report cards via ofsted.framework === 'ReportCard',
but the API sets framework to the raw event grouping ('Schools - S5') even
for report-card schools — so the check never matched: report-card schools
rendered as legacy 'Ofsted Rating' badges dated to a pre-Nov-2025
inspection (e.g. Barclay shown as 'Outstanding, Inspected 7 October 2021'
instead of its Feb 2026 report card).
Detect report cards by the presence of the report_card object (matching
the compare screen), and date them with rc_inspection_date, never the
legacy inspection_date. Applies to both primary and secondary detail views.
New e2e assertion against a real report-card school gates it.
Note: the list/map surface has the same latent issue via ofsted_framework
(LeafletMapInner) — flagged as a separate follow-up.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
|
||
|
|
b05f3bebc7 |
Merge pull request 'fix(ci): promotion E2E-gate check uses Actions token, not REGISTRY_TOKEN (403)' (#61) from fix/promote-status-token into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 54s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 44s
Reviewed-on: #61 |
||
|
|
ce422e6436 |
fix(ci): use the Actions token, not REGISTRY_TOKEN, to read the E2E commit status
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m5s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 36s
Promotion's 'Verify the staging E2E gate' step called the Gitea commit-status API with REGISTRY_TOKEN, which has container-registry scope but no repository scope — so the API returned 403 and promotion failed. Switch to the built-in GITHUB_TOKEN (repo read scope), matching how pr-checks.yml already authenticates to the Gitea API. REGISTRY_TOKEN is still used for the docker registry login, which is its correct scope. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
2ac26acf91 |
Merge pull request 'style(compare): shorten Ofsted link text to 'Ofsted page'' (#60) from fix/ofsted-link-text into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 52s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 41s
Reviewed-on: #60 |
||
|
|
3e77057567 |
style(compare): shorten Ofsted link text to 'Ofsted page'
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m5s
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 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
The link repeated the full school name ('Watford Grammar School for Boys's
Ofsted page') — long on mobile, and the colour-coded school name already
leads the row. Show just 'Ofsted page →'; keep the full name in aria-label
so screen readers can still tell the per-school links apart.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
|
||
|
|
e0d5a9969e |
Merge pull request 'style(compare): enlarge per-school name label in mobile section cards' (#59) from fix/mobile-cell-name-size into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 49s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 41s
Reviewed-on: #59 |
||
|
|
dc21e80a5e |
style(compare): enlarge the per-school name label in mobile section cards
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 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 14s
The colour-coded school name that leads each row in a mobile measure card was 0.8rem — a touch small to scan which school a value belongs to. Bump to 0.9rem (with a matching 10px dot) so it's easier to read. Mobile only; desktop uses the column header and hides this label. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
6d3a203699 |
Merge pull request 'fix(compare): anchor grade-5 & EBacc rows; restore secondary-button outline' (#58) from fix/secondary-anchors-button-affordance into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 40s
Reviewed-on: #58 |
||
|
|
b0c5b6bb57 |
fix(compare): anchor grade-5 & EBacc rows; restore secondary-button outline
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 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 8s
SF1 (expert sign-off): the secondary academics 'Grade 5+ in English & maths' and 'EBacc entry' rows rendered as bare numbers — the one place the 'every number anchored against the England average' promise broke. Both now show the official England anchor (already in the payload) + an Above/Close/Below verdict chip, matching Attainment 8 (which also gains a chip for consistency). Button affordance: globals.css has a duplicate .btn block whose 'border: none' overrode the base '1px solid transparent', so .btn-secondary/.btn-active's 'border-color' had no width — every outline button (the modal's '+ Compare', search-result '+ Compare', 'Comparing') rendered as borderless teal text. Give the outline variants the full 'border' shorthand so the outline renders regardless of the clobbered base. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |
||
|
|
a1128bd801 |
Merge pull request 'fix(compare): keep add-school sheet above the mobile keyboard (VisualViewport)' (#57) from fix/modal-keyboard-viewport into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 55s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 42s
Reviewed-on: #57 |
||
|
|
2fd997bfe6 |
fix(compare): keep the add-school sheet above the on-screen keyboard
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m6s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m31s
The bottom-sheet overlay was position:fixed inset:0, sized to the LAYOUT viewport, so when the mobile keyboard opened it kept full height: the sheet (anchored to the overlay's bottom) and the lower half of the dim backdrop sat behind the keyboard, hiding the search input and results. Track window.visualViewport (height + offsetTop) while the modal is open and pin the overlay to the visible region, so backdrop and sheet stay above the keyboard. Size the sheet against the overlay (max-height:100%, min-height:min(55vh,100%)) instead of vh, and drop the results list's own inner scroll on mobile so the sheet is a single scroll area. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB |