Compare commits

...
Author SHA1 Message Date
tudor 598ba9af4e Merge pull request 'fix(compare): a no-results school no longer blanks the trend chart' (#80) from fix/compare-null-year-blanks-chart 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 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 2m49s
Reviewed-on: #80
2026-07-22 14:23:25 +00:00
TudorandClaude Opus 4.8 dc85254ad2 fix(compare): a no-results school no longer blanks the trend chart
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 13s
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 54s
Adding a school with no performance data to a comparison made every
school's trend line disappear until that school was removed.

Root cause: /api/compare returns such a school with a single phantom
yearly_data row (the dim_school LEFT JOIN) whose year is null. In
buildCompareChart, Math.trunc(null) is 0, so the axis was seeded at
year 0; fillAcademicYears then walked 0, 101, 202, … and hit its
50-step cap long before reaching the real years, leaving every
school's series mapped entirely to null.

Fix: ignore yearly rows without a real numeric year when building the
axis and the per-school year map. Regression test added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:17:43 +01:00
tudor 2f038285f6 Merge pull request 'feat(security): allow analytics subdomain to iframe the site' (#79) from feat/allow-analytics-iframe-embed 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 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 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 1m15s
Reviewed-on: #79
2026-07-21 21:52:34 +00:00
TudorandClaude Opus 4.8 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>
2026-07-21 22:50:44 +01:00
tudor 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
2026-07-21 21:08:34 +00:00
TudorandClaude Opus 4.8 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
2026-07-21 22:05:10 +01:00
tudor 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
2026-07-21 15:06:04 +00:00
TudorandClaude Opus 4.8 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
2026-07-21 16:03:18 +01:00
tudor 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
2026-07-21 13:56:55 +00:00
TudorandClaude Opus 4.8 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
2026-07-21 14:55:43 +01:00
tudor 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
2026-07-21 11:27:20 +00:00
TudorandClaude Opus 4.8 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
2026-07-21 12:22:49 +01:00
tudor 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
2026-07-21 11:16:14 +00:00
TudorandClaude Opus 4.8 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
2026-07-21 12:08:50 +01:00
tudor 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
2026-07-21 09:04:57 +00:00
TudorandClaude Opus 4.8 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
2026-07-21 10:01:10 +01:00
TudorandClaude Opus 4.8 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
2026-07-21 09:07:23 +01:00
TudorandClaude Opus 4.8 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
2026-07-21 09:00:02 +01:00
tudor 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
2026-07-20 21:53:27 +00:00
TudorandClaude Opus 4.8 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
2026-07-20 22:49:11 +01:00
tudor 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
2026-07-20 21:32:45 +00:00
TudorandClaude Opus 4.8 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
2026-07-20 22:31:58 +01:00
tudor 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
2026-07-20 21:14:57 +00:00
TudorandClaude Opus 4.8 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
2026-07-20 22:09:32 +01:00
TudorandClaude Opus 4.8 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
2026-07-20 21:58:13 +01:00
TudorandClaude Opus 4.8 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
2026-07-20 20:39:16 +01:00
tudor 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
2026-07-20 16:18:44 +00:00
TudorandClaude Opus 4.8 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
2026-07-20 17:13:37 +01:00
tudor 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
2026-07-20 12:02:08 +00:00
TudorandClaude Opus 4.8 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
2026-07-20 12:53:07 +01:00
tudor 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
2026-07-20 11:42:48 +00:00
TudorandClaude Opus 4.8 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
2026-07-20 12:19:37 +01:00
tudor 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
2026-07-20 11:11:39 +00:00
TudorandClaude Fable 5 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
2026-07-20 12:03:23 +01:00
tudor 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
2026-07-20 07:52:55 +00:00
tudor 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
2026-07-20 06:21:06 +00:00
TudorandClaude Fable 5 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
2026-07-20 07:19:22 +01:00
TudorandClaude Fable 5 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
2026-07-20 07:15:33 +01:00
tudor 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
2026-07-18 20:28:19 +00:00
TudorandClaude Fable 5 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
2026-07-18 21:24:09 +01:00
TudorandClaude Fable 5 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
2026-07-18 21:14:57 +01:00
tudor 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
2026-07-18 18:13:25 +00:00
TudorandClaude Fable 5 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
2026-07-18 19:09:16 +01:00
tudor 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
2026-07-18 15:25:28 +00:00
TudorandClaude Fable 5 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
2026-07-18 16:20:03 +01:00
tudor 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
2026-07-18 14:20:09 +00:00
TudorandClaude Fable 5 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
2026-07-18 15:19:41 +01:00
tudor 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
2026-07-18 14:09:02 +00:00
TudorandClaude Fable 5 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
2026-07-18 15:06:18 +01:00
tudor 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
2026-07-18 07:29:51 +00:00
TudorandClaude Fable 5 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
2026-07-18 08:26:59 +01:00
tudor 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
2026-07-18 07:09:03 +00:00
TudorandClaude Fable 5 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
2026-07-18 08:00:31 +01:00
tudor bdd9bef349 Merge pull request 'fix(compare): repair mobile add-school modal + re-apply stranded chart-height fix' (#56) from fix/mobile-compare-polish 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 41s
Reviewed-on: #56
2026-07-17 22:11:45 +00:00
TudorandClaude Fable 5 e5f7f4c959 fix(compare): repair the mobile add-school modal
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m6s
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 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 52s
The 'add school' modal passed no title to Modal, so its header held only
the close button — shoved to the far left by justify-content:space-between
in an otherwise-empty bar — while the real title was rendered separately
inside the content. Pass the title to Modal so the header reads title
(left) + close (right), and drop the duplicate in-content heading.

Also: the mobile full-width result button targeted a dead .addButton
selector (the button never had that class), so it rendered inconsistently
— give the button a real module class and full width on mobile, tighten
the stacked cards, and give the bottom sheet a stable min-height so its
empty state isn't a tiny stub.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-17 23:02:12 +01:00
TudorandClaude Fable 5 60918da483 fix(compare): give the trend chart its own definite canvas height so the gap note can't squash it
The chart note (and the 2-row mobile chip legend) lived inside the fixed
360px/420px chartBox and competed with the canvas for it, so a longer
caption — e.g. the new KS4 gap note — shrank the mobile canvas to ~178px
and tripped the e2e >220px guard. The canvas now owns a definite height
(280px mobile / 380px desktop) with chips above and the note flowing
below at natural size, so neither can eat the plot. Verified on staging:
patched canvas renders 280px vs the squashed 178px.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-17 22:58:35 +01:00
tudor 284215fbce Merge pull request 'fix(compare): expert should-fixes S1-S4, S6 (S5/S7 closed by verification)' (#55) from fix/expert-signoff-shouldfixes 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 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 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 45s
Reviewed-on: #55
2026-07-17 17:53:16 +00:00
TudorandClaude Fable 5 200a97d0b9 fix(compare): per-school P8 explanation; disadvantaged cohort from the same yearly row
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 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m24s
Review findings: (1) the 'no KS2 baseline (COVID)' explanation was derived
from the basket-wide max year, so a school with an unrelated data gap
borrowed it from a neighbour with 2024/25 data — now judged per school on
its own latest year. (2) The '~N disadvantaged pupils' cohort multiplied
eligible_pupils and disadvantaged_pct resolved independently across years
— now both come from the same yearly row that supplies the displayed
percentage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-17 17:53:10 +01:00
TudorandClaude Fable 5 f3fa12806b fix(compare): expert should-fixes S1-S4, S6 — banded chips, P8 reason, KS4 gap caption, all-through framing, cohort sizes
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 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 3m8s
S1: first-choice chip banded (More than half / About 1 in 3 / Over 1 in 4
missed out) so a 44%-offered grammar isn't understated by half.
S2: Progress 8 explains its absence for 2024/25+ cohorts (no KS2 baseline,
COVID) instead of a bare 'No data'.
S3: KS4 trend charts get their own honest gap caption (2019/20-2020/21
unpublished; later years not in our dataset yet); y-axis 'Value'→'Score';
buildCompareChart exposes englandOnlyYears.
S4: all-through schools labelled in chips, rail caption says 'N schools ·
<phase> view' for mixed baskets, whole-school roll no longer judged
against the single-phase median, community section carries an all-ages
caveat.
S6 (spec §8.5): disadvantaged attainment shows the cohort behind it
('of ~50 disadvantaged pupils').

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-17 17:41:12 +01:00
tudor 1004f08daf Merge pull request 'fix(pipeline): annual DAG never builds the official KS4 national mart' (#54) from fix/annual-dag-ks4-national-selector 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 1m10s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 45s
Reviewed-on: #54
2026-07-17 13:28:08 +00:00
TudorandClaude Fable 5 79246edc22 fix(pipeline): build stg_ees_ks4_national in the annual EES DAG
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 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 37s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 17s
The DAG's dbt --select list predates the official-KS4-nationals stream,
so the extract loaded raw.ees_ks4_national but the staging model and
fact_ks4_national_averages were never rebuilt — staging kept serving the
old computed means after the DAG run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-17 14:15:11 +01:00
tudor 64b63b96c8 Merge pull request 'fix(compare): expert sign-off must-fixes M1-M3' (#53) from fix/expert-signoff-mustfixes into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 19s
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 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 43s
Reviewed-on: #53
2026-07-17 12:02:55 +00:00
TudorandClaude Fable 5 5944d88f0b 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
2026-07-17 12:40:42 +01:00
tudor 163b501be6 Merge pull request 'fix(compare): stale-basket fetch blanking comparisons; rail caption' (#52) from fix/compare-final-review-mustfix 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) Failing after 43s
Reviewed-on: #52
2026-07-17 06:28:27 +00:00
TudorandClaude Fable 5 80176cac4d fix(compare): drop the merge-on-fetch — cancellation alone fixes the race
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 10s
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 9s
Review finding: merging left a re-added school's old entry in the map
forever, so the covered check served stale data and the map grew
unboundedly. The cancelled flag already discards superseded responses,
which is the actual race fix; replacing keeps the map bounded to the
current selection and guarantees fresh refetches.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-17 07:27:10 +01:00
TudorandClaude Fable 5 84baf95f68 fix(compare): stale basket fetch no longer blanks a freshly opened comparison
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 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m23s
Opening a compare link while localStorage held a different basket raced a
fetch for the OLD school set against the URL's SSR data; the stale
response replaced comparisonData, so no active school had data and every
section (including the trends chart) vanished until a hard refresh.
Responses from superseded effect runs are now dropped, successful ones
merge instead of replace, and the URL-seed effect re-runs when a
client-side navigation changes ?urns=.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-17 07:16:04 +01:00
TudorandClaude Fable 5 99b769ca9e feat(compare): fill the sticky bar's label rail with a comparison caption
'COMPARING / 3 primary schools' — 0.72rem uppercase eyebrow over a
0.95rem semibold count, sized to sit alongside the 0.92rem chip names
without dominating. Desktop only; mobile pills unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 21:27:25 +01:00
tudor e8f78a1598 Merge pull request 'fix(compare): align sticky school chips with their data columns on desktop' (#51) from fix/compare-final-review-mustfix 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 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 40s
Reviewed-on: #51
2026-07-16 20:10:45 +00:00
TudorandClaude Fable 5 8e0b730629 fix(compare): align sticky school chips with their data columns on desktop
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 50s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 8s
The bar was a plain flex row while sections use a 200px-label + per-school
grid, so chips drifted off the columns they label. The bar now shares the
sections' grid template (via --school-count) at the same 761px breakpoint;
verified pixel-exact against live section columns (236/615/994). Mobile
pills unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 21:05:16 +01:00
tudor 20a27f3958 Merge pull request 'fix(compare): five must-fix findings from the final expert review' (#50) from fix/compare-final-review-mustfix 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 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m33s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 51s
Reviewed-on: #50
2026-07-16 19:16:54 +00:00
TudorandClaude Fable 5 852ed11e4d chore: untrack dbt build artifacts (target/, logs/, .user.yml) and gitignore them
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 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 46s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 3m25s
Swept in accidentally by a broad 'git add pipeline'. They embed local
absolute paths and a personal usage-tracking UUID, and a stale committed
manifest causes partial-parse/version-mismatch noise for others.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 20:09:10 +01:00
TudorandClaude Fable 5 77d7052662 docs(spec): re-verify the 2021/22 KS2 gap — expert finding refuted, footnote copy stands
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 47s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 4m1s
The final review claimed DfE published school-level 2021/22 KS2 in Dec
2022. Re-verified: the GOV.UK announcement 'Primary school performance
tables: 2022' is CANCELLED ('will not be published in key stage 2
performance tables in academic year 2021/22'), and the EES 2021/22
release carries the same statement. No code change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 19:12:07 +01:00
TudorandClaude Fable 5 c9e324635b fix(data): official DfE KS4 national headline averages; drop mislabelled computed means
New ees_ks4_national stream ingests the EES 'National characteristics
summary data' series (England, state-funded, all pupils). The old mart's
unweighted school means were 7-15 points off every headline measure and
produced an impossible national Progress 8 (-0.27). The API's computed
fallback is gone too: the footnote calls these figures official, so an
unbuilt mart now yields an empty series, never a stand-in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 19:07:49 +01:00
TudorandClaude Fable 5 1d855f3c17 fix(compare): census-sourced FSM/EAL benchmarks; never fall back across measure definitions
The FSM chip anchored against disadvantaged_pct (a different measure,
FSM6+CLA) whenever fsm_pct was null — which it always was, since the
performance df has no fsm_pct. New fact_census_benchmarks mart supplies
pupil-weighted FSM/EAL means per phase; the KS2-column medians that
produced a bogus 50% 'secondary disadvantaged' anchor are gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 19:05:15 +01:00
TudorandClaude Fable 5 9773483221 fix(compare): date report cards with their own inspection date, never the legacy one
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 14:48:17 +01:00
TudorandClaude Fable 5 e00a1b38a8 feat(pipeline): carry the report-card inspection's own date; pick newest MI file in discovery
The MI file's report-card grade columns belong to the latest FULL
inspection (col 'Inspection start date'), but inspection_date maps to the
legacy OEIF graded/ungraded dates — so report cards were being dated with
pre-Nov-2025 inspections. Also discover_csv_url() returned matches[0],
the oldest (2017) link on the GOV.UK page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 14:44:51 +01:00
TudorandClaude Fable 5 026a7ab6aa fix(compare): render all-secondary comparisons — re-run phase detection after basket hydration
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 14:42:09 +01:00
TudorandClaude Fable 5 a86a2be96c docs: plan for the five must-fix findings from the final expert review
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-16 14:39:11 +01:00
tudor d98e88f0b4 Merge pull request 'fix: preserve literal 'NULL' strings for primary key columns' (#49) from feature/ingest-independent-schools 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 50s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m25s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 0s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 44s
Reviewed-on: #49
2026-07-16 07:54:41 +00:00
Tudor 609bb923d9 fix: preserve literal 'NULL' strings for primary key columns
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 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 47s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 8s
2026-07-16 08:54:14 +01:00
tudor 4bfcd9ba9a Merge pull request 'fix: convert NaN/NULL to None and restore record properties structure in tap.py' (#48) from feature/ingest-independent-schools 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 1m22s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 41s
Reviewed-on: #48
2026-07-16 07:40:28 +00:00
Tudor 95f10bf352 fix: convert NaN/NULL to None and restore record properties structure in tap.py
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 12s
PR Checks / Build Frontend (no push) (pull_request) Successful in 42s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 47s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m46s
2026-07-16 08:29:59 +01:00
tudor 674470ceb6 Merge pull request 'feat: ingest independent schools in Ofsted tap and dbt staging' (#47) from feature/ingest-independent-schools 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 1m25s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 44s
Reviewed-on: #47
2026-07-15 22:26:39 +00:00
Tudor 8abff7a0a1 feat: ingest independent schools in Ofsted tap and dbt staging
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m6s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 50s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 47s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 10s
2026-07-15 23:21:40 +01:00
tudor 6f62c25f47 Merge pull request 'Pass phase state to compare sub-components to prevent phase metrics override by multi-phase schools' (#46) from fix/compare-expert-fixes 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 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 49s
Reviewed-on: #46
2026-07-15 16:38:49 +00:00
Tudor e74d3882ce Pass phase state to compare sub-components to prevent phase metrics override by multi-phase schools
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 9s
2026-07-15 17:38:02 +01:00
tudor 3fb3db1cc4 Merge pull request 'Fix Ofsted transitional inspections, phase tab exclusions, and FSM benchmark comparison' (#45) from fix/compare-expert-fixes into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 22s
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 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 42s
Reviewed-on: #45
2026-07-15 16:30:00 +00:00
Tudor b4b0249a06 Fix Ofsted transitional inspections, phase tab exclusions, and FSM benchmark comparison
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m9s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 19s
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 10s
2026-07-15 17:23:40 +01:00
tudor e39aef2935 Merge pull request 'fix(compare): sticky school bar hidden behind the site header' (#44) from fix/schoolbar-sticky-offset 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 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 39s
Reviewed-on: #44
2026-07-15 12:02:29 +00:00
TudorandClaude Fable 5 fef83b3bf2 fix(compare): sticky school bar hidden behind the site header
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m7s
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 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m3s
The Navigation header is position:sticky top:0 (z-index 1000). The school
bar was also sticky top:0 (z-index 10), so when scrolled it pinned at the
same top:0 *behind* the header — on mobile 57 of its 72px were covered,
leaving only a sliver, so you couldn't see which schools were selected.

Offset the bar's sticky top to the header height (65px desktop, 57px
mobile — the Navigation breakpoint is also 640px) so it pins just below.

e2e guard asserts the bar's sticky offset is at least the header height
(verified it fails against the pre-fix build).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-15 12:32:36 +01:00
tudor cf458fe05c Merge pull request 'School name cutoff fix' (#43) from fix/compare-mockup-drift 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 50s
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: #43
2026-07-15 08:01:47 +00:00
Tudor f579630fab School name cutoff fix
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 46s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 9s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 9s
2026-07-15 08:57:21 +01:00
tudor 19b41b6999 Merge pull request 'fix(compare): match mockups — remove trends table + mobile measure-first cards' (#42) from fix/compare-mockup-drift 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 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 37s
Reviewed-on: #42
2026-07-15 07:17:08 +00:00
TudorandClaude Fable 5 66bc5523f6 fix(compare): mobile measure-first cards to match the mockup
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 41s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m57s
The grid sections (At a glance, Ofsted, Getting a place, Who goes there)
collapsed generically on mobile — grey label pills, full names wrapping
to 3 lines, no dots — making the page ~2x the mockup's height and
'significantly different' from the mobile design.

Each measure is now wrapped in a <Measure> that is display:contents on
desktop (so the label + cells still flow into the shared aligned grid,
unchanged) and a white card on mobile with compact [dot][short name]
[value] rows — matching the mobile mockup. The sticky school bar becomes
scrollable short-name pills on mobile too. Adds a shortName() util.

Desktop layout is unchanged (display:contents dissolves the wrapper).
Validated the card mechanism and real content shapes (report-card cell,
badges, %+chip rows) via static previews at both widths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-15 07:50:01 +01:00
TudorandClaude Fable 5 3cb72d0a0f fix(compare): remove the year-by-year data table from Explore trends
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 12s
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 39s
The mockup's Explore trends section is the measure picker + chart only —
no data table. Removes the table (and the now-unused progressBand / band
chip / formatMetricValue plumbing that only fed it).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-15 07:29:24 +01:00
tudor b89fa47ec5 Merge pull request 'fix(compare): trends chart was squashed to ~150px — give it a real height' (#41) from fix/trends-chart-height 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 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 38s
Reviewed-on: #41
2026-07-14 22:51:04 +00:00
tudor 0c7ad0f309 Merge pull request 'test(e2e): fix flaky compare journey — select two same-phase schools' (#40) from fix/e2e-compare-samephase 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 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 37s
Reviewed-on: #40
2026-07-14 22:30:18 +00:00
TudorandClaude Fable 5 e4565e9f15 fix(compare): give the trends chart a real height (was squashed to ~150px)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m37s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 16s
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 17s
ComparisonChart runs Chart.js with maintainAspectRatio:false, so it sizes
to its container's height — which must be definite. TrendsExplorer gave
.chartBox a min-height, which doesn't resolve the chart wrapper's
height:100%, so Chart.js fell back to its ~150px default: a squashed
8.6:1 sliver that didn't match the mockups. Set a definite height (420px
desktop, 360px mobile where the chips row sits above the canvas).

Verified on staging by patching the live height: canvas went from
1287x150 to 1287x392 (desktop) / 284 (mobile) — proper ~3:1 proportions
matching the mockup, with the England dashed line, COVID/2021-22 gap and
table all reading correctly.

An e2e guard asserts the trends canvas is taller than 220px so the
squash can't regress.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 23:24:39 +01:00
TudorandClaude Fable 5 06e4898c30 test(e2e): pick two same-phase schools for the compare journey
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m41s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 16s
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 47s
The compare page's phase tabs put all-through schools (which carry KS4
data) on the secondary tab, so comparing an all-through school with a
pure primary splits them across tabs and only the active tab renders its
link. The test picked the first two 'primary' search hits without
guaranteeing same phase, so it flaked whenever a search returned an
all-through school first (e.g. URN 137306). Now selects two pure-Primary
URNs via the API — deterministic and data-invariant.

Verified against staging: was a 15.6s timeout, now passes in ~1.8s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 23:12:23 +01:00
tudor a9611e21c3 Merge pull request 'perf(api): batch supplementary queries — /api/compare stops scaling per school' (#38) from perf/batch-supplementary 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 13s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m8s
Reviewed-on: #38
2026-07-14 21:57:27 +00:00
tudor 0696518995 Merge pull request 'ci: speed up Frontend Typecheck + Tests (cache node_modules; cancel superseded runs)' (#39) from ci/frontend-checks-speedup 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 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 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m10s
Reviewed-on: #39
2026-07-14 21:57:08 +00:00
TudorandClaude Fable 5 090d5f7bec ci: speed up Frontend Typecheck + Tests; cancel superseded PR runs
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m34s
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 9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
The job does ~3s of real work (typecheck 1.4s + jest 1.3s) but installs
452 MB / 460 packages every run. Two changes:

- Cache nextjs-app/node_modules keyed on the lockfile hash (OS + node
  major pinned) and skip npm ci entirely on a hit — deps change rarely,
  so most PR pushes now do zero install. On miss, npm ci runs with
  --prefer-offline --no-audit --no-fund.
- Workflow-level concurrency with cancel-in-progress: a new commit (or an
  empty re-trigger) aborts the previous run instead of stacking a second
  full matrix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 22:54:32 +01:00
TudorandClaude Fable 5 315f1feede perf(api): batch supplementary queries — one per table, not five per school
PR Checks / Backend Smoke (pull_request) Canceled after 0s
PR Checks / Build Backend (no push) (pull_request) Canceled after 0s
PR Checks / Build Frontend (no push) (pull_request) Canceled after 0s
PR Checks / Build Pipeline (no push) (pull_request) Canceled after 0s
PR Checks / AI Code Review (Claude) (pull_request) Canceled after 0s
PR Checks / Frontend Typecheck + Tests (pull_request) Canceled after 8m16s
get_supplementary_data ran ~5 sequential DB round-trips per URN, so
/api/compare scaled at ~37ms/school (measured on staging: 1 school 155ms,
3 schools 220ms, 6 schools 340ms). get_supplementary_data_batch fetches
each table once with WHERE urn IN (...) and groups in Python, collapsing
5*N round-trips to a constant 5. get_supplementary_data is now a thin
wrapper so the detail endpoint is unchanged; the compare endpoint makes
one batched call. Each table degrades independently on failure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 22:42:10 +01:00
tudor abc03a0dd3 Merge pull request 'fix(compare): blank page on refresh + remove dead per-page comparison fetch' (#37) from fix/compare-refresh-and-fetch 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 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 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m9s
Reviewed-on: #37
2026-07-14 21:39:46 +00:00
TudorandClaude Fable 5 43a2c4a6bc fix(compare): show SSR data on refresh; drop dead per-page comparison fetch
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m42s
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 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 9s
Refresh bug: on mount the basket is empty for a beat before it hydrates
from the URL. The fetch effect nulled comparisonData on that transient
empty urnKey, then the one-shot 'SSR covers it' skip suppressed the
refetch — leaving the page blank on reload. The effect is now gated on
isInitialized, never blanks on empty (the render already shows the empty
state when nothing is selected), and decides fetch-vs-skip by whether it
already holds each requested school's data (SSR or a prior fetch).

Perf: useComparison ran a useSWR('/api/compare') whose result nothing
consumed — dead weight that fired on every page (Navigation + Toast are
global) whenever the basket was non-empty, and duplicated ComparisonView's
own fetch on the compare page. Removed; the hook now exposes basket state
only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 22:34:20 +01:00
tudor 8e4ee64140 Merge pull request 'perf(compare): import-time KS4 national averages mart; no refetch on metric change' (#36) from perf/compare-loading into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 23s
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 1m11s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 1m51s
Reviewed-on: #36
2026-07-14 20:04:45 +00:00
TudorandClaude Fable 5 d2dc78aeb5 ci: re-run PR checks (AI review job errored without posting findings)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m39s
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 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 36s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 2m5s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 13:25:24 +01:00
TudorandClaude Fable 5 619e3a1189 perf(compare): fetch only on school-set changes; use SSR payload; parallel page fetches
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m46s
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 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 36s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 5m4s
- Metric changes no longer refire /api/compare (the data is already
  client-side; the picker is presentational) — the fetch effect depends
  only on the URN set, with URL sync split into its own effect.
- The initial client fetch is skipped when the SSR payload already covers
  the selected schools; national averages + benchmarks now arrive via SSR
  props so nothing is lost by skipping.
- page.tsx fetches comparison and metrics in parallel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 13:06:52 +01:00
TudorandClaude Fable 5 52f8994401 perf(api): persist KS4 national averages as a mart; stop per-request aggregation
fact_ks4_national_averages is computed once at dbt build time (covered by
the EES DAG's stg_ees_ks4+ selector). _national_averages_payload now reads
both national-averages marts instead of scanning the performance dataframe
per year on every /api/compare request (~250ms saved per call). Fallback
for the deploy-before-DAG window computes the latest year only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 13:05:03 +01:00
tudor 9990f540f7 Merge pull request 'feat(compare): parent-first compare screen — sections, England anchors, report cards, mobile-first' (#35) from feat/compare-frontend-rebuild into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 43s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 1m1s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m57s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 46s
Reviewed-on: #35
2026-07-14 07:26:21 +00:00
TudorandClaude Fable 5 6dd9b04b50 ci: re-run PR checks (AI review job errored without posting findings)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m39s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 32s
PR Checks / Build Frontend (no push) (pull_request) Successful in 41s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 4m1s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 07:07:56 +01:00
TudorandClaude Fable 5 d0e71e2cf0 feat(api): compare school_info carries GIAS facts for the community section
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m36s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 16s
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) Failing after 11s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 00:04:03 +01:00
TudorandClaude Fable 5 6138e2b2ee Merge main (PR #34) into compare frontend branch
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-14 00:04:03 +01:00
TudorandClaude Fable 5 2f85b9c647 test(e2e): compare journeys for the parent-first redesign
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m42s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 15s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 38s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 59s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 23:59:22 +01:00
TudorandClaude Fable 5 2155256177 feat(compare): parent-first compare screen assembly
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 23:58:00 +01:00
TudorandClaude Fable 5 519584f34b feat(compare): trends explorer with England line; gap-honest axis; series regression guard
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 23:54:58 +01:00
TudorandClaude Fable 5 2573cd2490 feat(compare): academics strips with England anchors and More measures
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 23:50:29 +01:00
TudorandClaude Fable 5 9f2260ce50 feat(compare): at-a-glance, Ofsted, admissions and community sections
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 23:49:17 +01:00
tudor 4a8e798c64 Merge pull request 'feat(api): compare endpoint enrichment — supplementary blocks, national averages, benchmarks, report-card labels' (#34) from feat/compare-api-enrichment into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 24s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 57s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m5s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Failing after 4m49s
Reviewed-on: #34
2026-07-13 21:58:51 +00:00
TudorandClaude Fable 5 60cbc3f46d feat(compare): DotStrip with England-average anchor
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 19:18:33 +01:00
TudorandClaude Fable 5 48ca042b08 feat(compare): comprehension logic (report cards, admissions, verdicts, strips)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 19:17:15 +01:00
TudorandClaude Fable 5 80f057ea5a feat(compare): types for enriched comparison payload
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 19:14:55 +01:00
TudorandClaude Fable 5 9447b80bc6 docs: compare mockups as frontend design source + rebuild plan
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 19:13:18 +01:00
TudorandClaude Fable 5 c0f31a5941 feat(api): compare endpoint carries supplementary blocks, national averages and benchmarks
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m45s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 22s
PR Checks / Build Frontend (no push) (pull_request) Successful in 51s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 37s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 3m12s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 18:48:28 +01:00
TudorandClaude Fable 5 cec7941b44 feat(api): computed state-school benchmarks
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 18:45:30 +01:00
TudorandClaude Fable 5 dbaa15c099 feat(api): expose progress CIs, KS4 banding/gaps, admissions detail, report-card labels
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 18:44:29 +01:00
TudorandClaude Fable 5 b5b47ca135 feat(api): Ofsted report-card labels and provider-page URL
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 18:42:08 +01:00
TudorandClaude Fable 5 0c89b2c34e feat(api): map compare-foundation mart columns
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 18:40:55 +01:00
TudorandClaude Fable 5 4bf90b5f09 feat(pipeline): thread compare-foundation columns through fact_performance
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 15:46:43 +01:00
TudorandClaude Fable 5 17b4498c80 docs: plan for compare API enrichment
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 15:46:04 +01:00
tudor 3754947fd6 Merge pull request 'feat(pipeline): compare-screen data foundation — raw→marts promotions, national averages, Ofsted report cards' (#32) from feat/compare-data-foundation into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 12s
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 1m16s
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: #32
2026-07-13 12:52:11 +00:00
tudor 9799ad9b43 Merge pull request 'ci: two-stage deploy — staging automatic, production behind a manual approval' (#33) from chore/staged-prod-promotion 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 56s
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 39s
Reviewed-on: #33
2026-07-13 12:30:19 +00:00
TudorandClaude Fable 5 d5cd0abfee ci: re-run PR checks (AI review job errored without posting findings)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m38s
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 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 46s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 5m50s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 13:15:52 +01:00
TudorandClaude Fable 5 6877abedeb fix(ci): harden promote workflow — env-isolated untrusted input, main-ancestry check, concurrency guard
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m38s
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 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m39s
Addresses the AI review findings on PR #33:
- severe: the workflow_dispatch sha input was interpolated directly into
  the run script (shell injection with REGISTRY_TOKEN + prod webhook in
  scope). It now reaches the shell only via env, is rejected if it
  starts with '-', and is resolved locally with git rev-parse.
- minor: the resolved sha must be a 40-hex ancestor of origin/main —
  non-main refs are refused explicitly instead of implicitly.
- minor: a prod-promotion concurrency group serialises promotions
  (cancel-in-progress: false).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 13:14:28 +01:00
TudorandClaude Fable 5 436ec6151b fix(pipeline): thread KS2 progress CI columns through the legacy union and lineage model
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m39s
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 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 46s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 28s
The AI review gate caught that stg_ees_ks2's 7 new columns broke the
positional UNION ALL with stg_legacy_ks2 in int_ks2_with_lineage, and
that the lineage CTEs never emitted them (same class of bug fixed for
KS4 in 34a5de2). Legacy gets typed null placeholders at matching
positions; both lineage CTEs pass the columns through. 45/45 columns
verified name-identical in order across both union branches.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 08:42:40 +01:00
TudorandClaude Fable 5 2b563cc0bf docs: two-stage deploy model (staging auto, production manual)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m36s
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 43s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 2m10s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 08:38:37 +01:00
TudorandClaude Fable 5 75e92dc7f5 ci: manual production promotion workflow with e2e-gate verification
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 08:36:25 +01:00
TudorandClaude Fable 5 7499e7f557 ci: stop deploy pipeline at staging; production promotion becomes manual
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 08:35:39 +01:00
TudorandClaude Fable 5 dd0ff7d0c2 docs: plan for staged production promotion
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 08:34:32 +01:00
TudorandClaude Fable 5 6f925abf6b fix(pipeline): harden banding against EES sentinels; diagnostic cleanups
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m40s
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 41s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 46s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 3m17s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-13 08:22:34 +01:00
TudorandClaude Fable 5 03518520f8 fix(pipeline): unknown safeguarding values parse to NULL, not "not met"
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 22:17:11 +01:00
TudorandClaude Fable 5 c2ed002118 docs(pipeline): record Task 7 report-card grade value sample + collision check
Evidence trail for the rc_* mapping in the prior commit: real value_counts()
over the 7 MI report-card columns, confirming the 5-value grade vocabulary
and that 'Achievement'/'Safeguarding standards' match by exact string only
(no legacy OEIF column accidentally consumed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 22:13:03 +01:00
TudorandClaude Fable 5 02084e427c feat(pipeline): extract Ofsted report-card judgements (rc_* columns)
Wires the tap TODO in stg_ofsted_inspections.sql: maps the 7 confirmed
report-card MI columns (Safeguarding standards, Inclusion, Curriculum
and teaching, Achievement, Attendance and behaviour, Personal
development and wellbeing, Leadership and governance) into rc_*
fields, parsed via the new parse_report_card_grade macro against
real sampled grade values (Exceptional/Strong standard/Expected
standard/Needs attention/Urgent improvement). rc_safeguarding_met
becomes boolean from Met/Not met. rc_early_years/rc_sixth_form have
no MI column yet and are intentionally omitted from COLUMN_PRIORITY,
staying NULL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 22:12:33 +01:00
TudorandClaude Fable 5 bee63a7836 docs(spec): 2021/22 school-level KS2 is a permanent DfE source gap, not a pipeline task
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 22:10:05 +01:00
TudorandClaude Fable 5 fc21783298 chore(pipeline): verify 2021/22 legacy KS2 archive compatibility
DfE never published school-level KS2 2021/22 data publicly (confirmed via
EES release notes and by walking the Compare School Performance download
wizard, which has no ks2 checkbox for 2021-2022, same as the COVID-cancelled
2020-2021 year). No archive exists to verify column headers against or
upload to the filebrowser; Task 6 is blocked at the source-data level.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 22:08:36 +01:00
TudorandClaude Fable 5 ccd8e73fe8 fix(pipeline): include 2015/16 national averages
Widen the year filter in stg_ees_ks2_national.sql from >= 201617 to
>= 201516 so the England national-averages line no longer starts a
year late; the catalogue CSV has a real, comparable 201516 row (2015/16
was the first year of the current expected-standard tests, so it's the
correct floor).

GPS/science/scaled-score national columns confirmed present at source
with correct mapping; prod NULLs are stale raw data, backfilled by the
next extract run. No _KS2_NATIONAL_COL_MAP change accompanies this fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 22:02:28 +01:00
TudorandClaude Fable 5 5f1b6adb44 fix(pipeline): align SEN column order across KS4 union branches
int_ks4_with_lineage.sql unions stg_ees_ks4 and stg_legacy_ks4 via
`select *`, which PostgreSQL aligns positionally. stg_legacy_ks4 listed
sen_support_pct before sen_ehcp_pct while stg_ees_ks4 lists sen_ehcp_pct
before sen_support_pct, swapping the two values for legacy-sourced rows
in marts.fact_ks4_performance. Reordered stg_legacy_ks4's final select
to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 22:00:15 +01:00
TudorandClaude Fable 5 34a5de2687 feat(pipeline): Progress 8 banding and KS4 disadvantage gaps in marts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 21:55:34 +01:00
Tudor af43b291e7 feat(pipeline): KS2 progress confidence intervals and writing working-towards 2026-07-12 21:34:59 +01:00
Tudor 5a94f470e1 feat(pipeline): admissions preference breakdown and cross-LA demand in marts 2026-07-12 21:30:50 +01:00
Tudor 0fe1ea0d6a chore(pipeline): diagnostic for compare-screen data gaps 2026-07-12 21:25:00 +01:00
TudorandClaude Fable 5 297bdbd12e docs: compare-screen redesign spec, expert review, and data-foundation plan
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-12 21:19:53 +01:00
tudor 58e90fef61 Merge pull request 'fix(api): blank-name GIAS sentinel codes map to empty string, not Unknown(n)' (#27) from fix/gias-blank-name-codes into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 20s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 54s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m5s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 41s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #27
2026-07-09 21:21:08 +00:00
TudorandClaude Fable 5 3710529e49 fix(api): map blank-name GIAS sentinel codes to empty string, not Unknown
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m40s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 20s
PR Checks / Build Frontend (no push) (pull_request) Successful in 54s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 37s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m35s
ReligiousCharacter 99 (~4k schools) and AdmissionsPolicy 9 (~5.6k) carry a
code with a blank name in the GIAS CSV; the generator skipped them so they
hit the Unknown(<code>) path — wrongly triggering the Faith-priority tag
and polluting filters. Blank-only codes now map to "" (byte-identical to
the old name pipeline); accepted_values lists extended to match the seed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 22:04:53 +01:00
tudor 159207c6f5 Merge pull request 'fix(pipeline): add the missing backend cache-invalidation step to the data DAGs' (#26) from fix/daily-dag-cache-invalidation into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 13s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 51s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m3s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 43s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #26
2026-07-09 20:41:42 +00:00
TudorandClaude Fable 5 d677b54533 fix(pipeline): cache invalidation for IDACI DAG too; curl timeouts
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m37s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 48s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 35s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m40s
Addresses AI-review findings: the annual IDACI DAG also rebuilds a mart
(fact_deprivation) and needs the reload; curl gets connect/max timeouts
so an unreachable backend fails fast instead of hanging the task.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 21:26:45 +01:00
TudorandClaude Fable 5 c353e36072 fix(pipeline): actually invalidate the backend cache after data rebuilds
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m40s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 16s
PR Checks / Build Frontend (no push) (pull_request) Successful in 51s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 36s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 1m20s
The daily/monthly/annual DAG docstring promised an Invalidate Cache step
that never existed — after a marts rebuild the backend kept serving its
startup-cached (possibly empty) DataFrame until a container restart.
Add a POST /api/admin/reload task at the end of each pipeline DAG,
mirroring the sitemap DAG's admin-call pattern.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 21:12:01 +01:00
tudor d9223a6d6e Merge pull request 'fix(api): legacy name-column fallback when marts predate the GIAS code migration' (#25) from fix/gias-legacy-fallback into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 19s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 54s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Failing after 4m45s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Has been skipped
Reviewed-on: #25
2026-07-09 19:13:55 +00:00
TudorandClaude Fable 5 74ca76d150 fix(api): match missing-column fallbacks on the DBAPI error, not the statement
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m41s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 20s
PR Checks / Build Frontend (no push) (pull_request) Successful in 53s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m41s
str(ProgrammingError) embeds the full SQL, which contains every column
name — the substring check matched any error and could take the wrong
retry branch. Parse the missing column from exc.orig instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 19:29:58 +01:00
TudorandClaude Fable 5 4b75152ee0 fix(api): fall back to legacy name-column query when marts predate code migration
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m41s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 19s
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 3m8s
Closes the deploy window flagged by CI review — the backend now works
against both the old (name) and new (code) mart schemas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:48:06 +01:00
tudor 84dfc6c1bb Merge pull request 'feat: GIAS classification fields stored as codes, translated in code' (#24) from feat/gias-code-dictionaries into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 19s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 52s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m16s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Failing after 4m47s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Has been skipped
Reviewed-on: #24
2026-07-09 13:32:43 +00:00
TudorandClaude Fable 5 c26755750d docs: mark GIAS code dictionaries spec implemented
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m38s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 22s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 54s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 3m58s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:12:52 +01:00
TudorandClaude Fable 5 254a19eb42 fix(pipeline): run gias_code_names seed + drift test in the daily DAG
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:11:31 +01:00
TudorandClaude Fable 5 4f6b2b0edc feat(pipeline): typesense sync translates GIAS codes before indexing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:51:40 +01:00
TudorandClaude Fable 5 f1a013ec01 feat(api): translate GIAS codes to names at the query boundary
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:48:53 +01:00
TudorandClaude Fable 5 fa6c929a3a feat(pipeline): dim_school/dim_location store GIAS codes; seed drift test
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:45:15 +01:00
TudorandClaude Fable 5 d898e6279b feat(pipeline): ingest GIAS code columns; staging exposes codes not names
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:41:52 +01:00
TudorandClaude Fable 5 e188c2ff4b feat: GIAS code->name dictionaries generated from live bulk CSV
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:38:19 +01:00
TudorandClaude Fable 5 08bd86db05 docs: implementation plan for GIAS code dictionaries
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:10:26 +01:00
TudorandClaude Fable 5 1ae5762a0a docs: design spec for GIAS code dictionaries (codes in marts, names in code)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:55:53 +01:00
tudor bc87e56545 Merge pull request 'fix(ui): shorten proposed-to-close notice copy' (#23) from fix/proposed-to-close-copy into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 48s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 38s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #23
2026-07-08 21:52:56 +00:00
TudorandClaude Fable 5 4522cbf645 fix(ui): shorten proposed-to-close notice copy
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m38s
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 41s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 27s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 22:51:32 +01:00
tudor 7370712888 Merge pull request 'feat: include and mark 'Open, but proposed to close' schools' (#22) from feat/proposed-to-close-schools into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 20s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 55s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m10s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 41s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 10s
Reviewed-on: #22
2026-07-08 21:23:23 +00:00
TudorandClaude Fable 5 45ab479062 feat(ui): mark proposed-to-close schools in listings and detail pages
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m46s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 21s
PR Checks / Build Frontend (no push) (pull_request) Successful in 50s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 35s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m1s
Amber tag in listing rows (option A) and a slim notice strip under the
detail-page header (option E): proposed for closure, formal process not
necessarily started, check with the local authority before applying.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 22:05:55 +01:00
TudorandClaude Fable 5 6f602f4a9e feat(api): expose GIAS establishment status on school payloads
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 22:05:55 +01:00
TudorandClaude Fable 5 de81e9cdbd feat(pipeline): include 'Open, but proposed to close' schools in dims
These schools are still operating and publish results; they drop out
automatically when GIAS flips them to Closed since marts fully rebuild
each run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 21:54:08 +01:00
tudor 45c68b60b4 Merge pull request 'feat: drive sixth-form separation from GIAS OfficialSixthForm flag' (#21) from feat/gias-sixth-form-flag into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 20s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 50s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 1m23s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 0s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 44s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #21
2026-07-07 13:48:12 +00:00
TudorandClaude Fable 5 f1388ff5bd fix(pipeline): normalize GIAS OfficialSixthForm comparison with lower(trim())
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m37s
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 50s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 48s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m19s
Matches the phase derivation's guard against casing/whitespace variants in
raw GIAS data; an unmatched variant previously fell through silently to the
statutory-age fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:05:10 +01:00
TudorandClaude Fable 5 4d226fd616 test: drop unused fake exception helper
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m41s
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 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 53s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 3m17s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:36:01 +01:00
TudorandClaude Fable 5 a524cdc591 fix(api): survive missing has_sixth_form column and numpy bool serialization
- data_loader.load_school_data_as_dataframe now catches a ProgrammingError
  whose message mentions has_sixth_form (psycopg2 UndefinedColumn) and
  retries with a NULL-AS-has_sixth_form query variant, so the API keeps
  serving data (and the app.py column-fallback branch stays reachable)
  even before the nightly pipeline has rebuilt marts.dim_school.
- utils.convert_to_native now handles numpy.bool_ so GET /api/schools/{urn}
  doesn't 500 once has_sixth_form is a populated bool-dtype column.
- Update the now-stale comment on the app.py age-range fallback branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:33:25 +01:00
TudorandClaude Fable 5 3fcb1340d4 docs: mark sixth-form flag pipeline change implemented
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:43:08 +01:00
TudorandClaude Fable 5 0934c8f38c feat(ui): sixth-form badge, note and filter labels use GIAS flag
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:40:42 +01:00
TudorandClaude Fable 5 1d149ffc48 feat(api): drive has_sixth_form filter and payloads from GIAS flag
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:36:39 +01:00
TudorandClaude Fable 5 d11faefebd feat(pipeline): derive dim_school.has_sixth_form from GIAS flag
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:30:39 +01:00
TudorandClaude Fable 5 3b35849bb3 feat(pipeline): ingest GIAS OfficialSixthForm into staging
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:28:08 +01:00
TudorandClaude Fable 5 87f4c6dd40 docs: implementation plan for GIAS sixth-form flag
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:21:02 +01:00
TudorandClaude Fable 5 0309b27c84 docs: exam results phase taxonomy and sixth-form separation spec
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:02:21 +01:00
tudor 85484a80c4 Merge pull request 'fix(api): school detail 500s for schools with no performance rows' (#20) from fix/school-detail-nan-500 into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 41s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 47s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 39s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #20
2026-07-07 08:56:23 +00:00
TudorandClaude Opus 4.8 536832a524 chore: drop committed .pyc files, ignore __pycache__ everywhere
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m37s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 29s
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 1m54s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 09:37:17 +01:00
TudorandClaude Opus 4.8 87642b7b06 fix(api): serialize schools that have no performance rows
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m39s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 30s
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 2m0s
Schools without KS2/KS4 results (special post-16 institutions, sixth-form
centres, PRUs, new schools) come back from the marts LEFT JOIN with NaN in
every numeric column. school_info passed those raw pandas values straight
into JSONResponse, which renders with allow_nan=False, so the detail
endpoint 500d and the frontend turned that into a 404 on every such SEO
landing page.

Run school_info values through convert_to_native (the same treatment
yearly_data already gets), add backend unit tests plus a pytest step in PR
checks, and an e2e journey that finds a results-less school via the search
API and asserts its page renders.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 09:22:54 +01:00
tudor 929748d014 Merge pull request 'feat(home): move "use my location" beside the hero search box' (#19) from feat/near-me-by-search into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 51s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 38s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #19
2026-07-06 17:56:58 +00:00
TudorandClaude Opus 4.8 4e8df006d7 feat(home): move "use my location" beside the hero search box
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m40s
PR Checks / Backend Smoke (pull_request) Successful in 5s
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 9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m19s
The geolocation shortcut lived in the discovery strip below the results,
away from the search. Move it directly under the hero search input, paired
with the postcode hint, so the two ways to find nearby schools ("type a
postcode" / "use my location") read as one idea and are visible at first
glance.

- FilterBar gains optional onNearMe/geoState/geoError props and renders the
  teal "Use my location" pill (with spinner + error) in hero mode; the
  geolocation flow itself still lives in HomeView.
- Remove the now-duplicate near-me button and its dead CSS from the
  discovery section.
- Refresh the search hint copy to pair with the button.
- e2e: assert the "use my location" shortcut renders in the hero.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 17:01:45 +01:00
tudor 1f8284adfc Merge pull request 'fix(map): results map fullscreen falls back to an overlay on iOS' (#18) from fix/results-map-ios-fullscreen into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 48s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 38s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 8s
Reviewed-on: #18
2026-07-06 13:33:16 +00:00
TudorandClaude Fable 5 b2dc4d0779 fix(map): results map fullscreen falls back to an overlay on iOS
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m37s
PR Checks / Backend Smoke (pull_request) Successful in 5s
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 1m4s
The results-view map's fullscreen button called requestFullscreen(),
which iOS Safari doesn't implement (fullscreen is video-only there), so
tapping it did nothing on iPhones — the same gap already fixed for the
school hero map.

When the Fullscreen API is missing or its promise rejects, fall back to
a fixed-position overlay (.fsFallback, z-index 5000) driven by state,
locking body scroll while open. Leaflet re-measures on window resize, so
dispatch a resize when fullscreen toggles (the CSS overlay fires none) or
the map would fill only part of the screen. Native fullscreen is
unchanged.

New e2e journey deletes Element.requestFullscreen on a mobile viewport,
opens the results map fullscreen, and asserts the exit control appears
then releases; it fails against current production, reproducing the bug.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:09:37 +01:00
tudor 1cdcd85e41 Merge pull request 'fix(search): stop the mobile sort dropdown overflowing the viewport' (#17) from fix/mobile-sort-select-overflow into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 13s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 51s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 36s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #17
2026-07-06 12:46:48 +00:00
TudorandClaude Fable 5 a00cbe9161 fix(search): stop the mobile sort dropdown overflowing the viewport
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m37s
PR Checks / Backend Smoke (pull_request) Successful in 5s
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 9s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m3s
On a location search the results header shows the view toggle and the
sort <select> side by side. The select sizes to its widest option
('Highest Reading, Writing & Maths %', ~273px), so on a phone its right
edge ran ~46px past the viewport and was clipped off-screen.

On mobile let the select flex into the remaining space with min-width:0
so its label truncates instead of overflowing, and keep the view toggle
from shrinking. Verified live at 390px: the select now sits fully within
the viewport.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:23:29 +01:00
tudor 64121592fd Merge pull request 'feat(compare): lay mobile chart chips two per row' (#16) from feat/compare-chips-two-per-row into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 50s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 38s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #16
2026-07-06 12:16:26 +00:00
TudorandClaude Fable 5 6828f6cd44 feat(compare): lay mobile chart chips two per row
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m43s
PR Checks / Backend Smoke (pull_request) Successful in 5s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
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 1m50s
The mobile chart legend stacked one school chip per line, so up to five
schools pushed the chart down and left the plot cramped. Switch the chip
row to a two-column grid; each chip fills its column and truncates its
name with an ellipsis (full names remain on the school cards and in the
tooltip). Five schools now take three rows instead of five, giving the
chart noticeably more height.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:17:41 +01:00
tudor 331ae8d89f Merge pull request 'fix(e2e): compare-chips test must compare schools in one phase' (#15) from fix/e2e-compare-chips-phase into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 12s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 53s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Successful in 38s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Successful in 9s
Reviewed-on: #15
2026-07-06 11:01:22 +00:00
tudor 47335fcda0 Merge pull request 'fix(frontend): proxy /api and /sitemap.xml at runtime, not via baked rewrites' (#14) from fix/runtime-api-proxy into main
Deploy (staging -> E2E gate -> production) / Build Backend (FastAPI) (push) Successful in 13s
Deploy (staging -> E2E gate -> production) / Build Frontend (Next.js) (push) Successful in 48s
Deploy (staging -> E2E gate -> production) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 13s
Deploy (staging -> E2E gate -> production) / Deploy to Staging (push) Successful in 1s
Deploy (staging -> E2E gate -> production) / E2E Journeys against Staging (push) Failing after 52s
Deploy (staging -> E2E gate -> production) / Promote to Production (push) Has been skipped
Reviewed-on: #14
2026-07-06 10:11:39 +00:00
TudorandClaude Fable 5 95a5783da1 fix(frontend): proxy /api and /sitemap.xml at runtime, not via baked rewrites
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m38s
PR Checks / Backend Smoke (pull_request) Successful in 5s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
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) Successful in 3m13s
next.config.js rewrites() bakes its destination into the build
(routes-manifest.json), capturing FASTAPI_URL at build time. Because one
frontend image is promoted staging->prod, the baked backend host forced
every environment to name the backend service identically; staging names
it 'backend_stg', so the browser's /api/* calls proxied to the baked
'http://backend' and failed with getaddrinfo ENOTFOUND backend. (SSR was
unaffected because lib/api.ts reads FASTAPI_URL at runtime.)

Replace the rewrites with route handlers that read FASTAPI_URL per
request:
- app/api/[...path]/route.ts — transparent proxy for all methods, streams
  the response, strips hop-by-hop headers, and returns 502 on upstream
  failure instead of crashing.
- app/sitemap.xml/route.ts — proxies the backend sitemap (robots.ts points
  crawlers here).

The same promoted image now adapts to whatever the backend is called in
each environment. Verified: production build succeeds with /api/[...path]
and /sitemap.xml as dynamic routes and an empty rewrites manifest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:00:42 +01:00
356 changed files with 67473 additions and 1552 deletions
+3 -46
View File
@@ -1,4 +1,4 @@
name: Deploy (staging -> E2E gate -> production) name: Stage (build -> staging -> E2E gate)
on: on:
push: push:
@@ -193,48 +193,5 @@ jobs:
env: env:
BASE_URL: ${{ secrets.STAGING_BASE_URL }} BASE_URL: ${{ secrets.STAGING_BASE_URL }}
promote-prod: # Production deployment is a second, manual approval: see promote.yml
name: Promote to Production # ("Promote to Production (manual)") and docs/DEPLOY.md.
runs-on: ubuntu-latest
needs: [e2e-staging]
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Retag verified images as prod
run: |
SHORT_SHA="sha-$(echo "${{ gitea.sha }}" | cut -c1-7)"
for IMAGE in \
"${REGISTRY}/${BACKEND_IMAGE_NAME}" \
"${REGISTRY}/${FRONTEND_IMAGE_NAME}" \
"${REGISTRY}/${PIPELINE_IMAGE_NAME}"; do
# Keep a rollback pointer before moving :prod
docker buildx imagetools create -t "${IMAGE}:prod-previous" "${IMAGE}:prod" || true
docker buildx imagetools create -t "${IMAGE}:prod" "${IMAGE}:${SHORT_SHA}"
echo "Promoted ${IMAGE}:${SHORT_SHA} -> :prod"
done
- name: Trigger production stack update
run: curl -fsSk -X POST "${{ secrets.PORTAINER_PROD_WEBHOOK }}"
- name: Wait for production to become healthy
run: |
echo "Polling ${PROD_BASE_URL} for up to 5 minutes..."
for i in $(seq 1 60); do
if curl -fsS -o /dev/null --max-time 10 "${PROD_BASE_URL}/"; then
echo "Production is up (attempt $i)"
exit 0
fi
sleep 5
done
echo "Production did not become healthy in time" >&2
exit 1
env:
PROD_BASE_URL: ${{ secrets.PROD_BASE_URL }}
+24 -4
View File
@@ -5,6 +5,13 @@ on:
branches: branches:
- main - main
# Cancel superseded runs: pushing a new commit to a PR (or an empty
# re-trigger) aborts the previous still-running checks instead of running
# a second full matrix alongside them.
concurrency:
group: pr-checks-${{ gitea.event.pull_request.number }}
cancel-in-progress: true
env: env:
REGISTRY: privaterepo.sitaru.org REGISTRY: privaterepo.sitaru.org
BACKEND_IMAGE_NAME: ${{ gitea.repository }}-backend BACKEND_IMAGE_NAME: ${{ gitea.repository }}-backend
@@ -23,12 +30,22 @@ jobs:
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 22
cache: npm
cache-dependency-path: nextjs-app/package-lock.json # Cache the resolved node_modules (452 MB / 460 packages) keyed on the
# lockfile. On a hit — the common case, since deps change rarely — the
# whole `npm ci` step is skipped, not just its download phase. The key
# pins OS + node major so we never restore incompatible native binaries.
- name: Cache node_modules
id: node-modules-cache
uses: actions/cache@v4
with:
path: nextjs-app/node_modules
key: nextjs-node-modules-${{ runner.os }}-node22-${{ hashFiles('nextjs-app/package-lock.json') }}
- name: Install dependencies - name: Install dependencies
if: steps.node-modules-cache.outputs.cache-hit != 'true'
working-directory: nextjs-app working-directory: nextjs-app
run: npm ci run: npm ci --prefer-offline --no-audit --no-fund
- name: Typecheck - name: Typecheck
working-directory: nextjs-app working-directory: nextjs-app
@@ -51,11 +68,14 @@ jobs:
python-version: "3.12" python-version: "3.12"
- name: Install dependencies - name: Install dependencies
run: pip install -r requirements.txt run: pip install -r requirements.txt pytest "httpx<0.28"
- name: Import smoke test - name: Import smoke test
run: python -c "from backend.app import app; print('backend imports OK')" run: python -c "from backend.app import app; print('backend imports OK')"
- name: Backend unit tests
run: python -m pytest backend/tests -q
build-backend: build-backend:
name: Build Backend (no push) name: Build Backend (no push)
runs-on: ubuntu-latest runs-on: ubuntu-latest
+129
View File
@@ -0,0 +1,129 @@
name: Promote to Production (manual)
# Second approval gate of the deploy model: run this workflow from the
# Actions UI after testing the feature on staging. It refuses commits
# whose staging E2E gate is not green. See docs/DEPLOY.md.
on:
workflow_dispatch:
inputs:
sha:
description: >-
Commit SHA on main to promote (full or >=7 chars).
Leave empty to promote the latest main commit.
required: false
default: ""
# Only one promotion at a time; never cancel an in-flight promotion.
concurrency:
group: prod-promotion
cancel-in-progress: false
env:
REGISTRY: privaterepo.sitaru.org
BACKEND_IMAGE_NAME: ${{ gitea.repository }}-backend
FRONTEND_IMAGE_NAME: ${{ gitea.repository }}-frontend
PIPELINE_IMAGE_NAME: ${{ gitea.repository }}-pipeline
jobs:
promote-prod:
name: Promote approved commit to Production
runs-on: ubuntu-latest
steps:
- name: Checkout repository (full history for ancestry check)
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Resolve and validate target SHA
id: resolve
# SECURITY: the dispatch input is untrusted — it reaches the shell
# only via env (never spliced into `run:` with ${{ }}) and is only
# used as a quoted argument. The resolved value is validated as a
# 40-hex sha and required to be an ancestor of main before any
# later step interpolates it.
env:
SHA_INPUT: ${{ gitea.event.inputs.sha }}
run: |
set -euo pipefail
case "$SHA_INPUT" in
-*) echo "REFUSED: SHA input may not start with '-'." >&2; exit 1 ;;
esac
if [ -z "$SHA_INPUT" ]; then
SHA_INPUT="$(git rev-parse origin/main)"
fi
FULL_SHA=$(git rev-parse --verify --quiet "${SHA_INPUT}^{commit}") || {
echo "REFUSED: not a commit in this repository." >&2
exit 1
}
echo "$FULL_SHA" | grep -Eq '^[0-9a-f]{40}$'
if ! git merge-base --is-ancestor "$FULL_SHA" origin/main; then
echo "REFUSED: $FULL_SHA is not on main — only main commits are promotable." >&2
exit 1
fi
SHORT_SHA="sha-$(echo "$FULL_SHA" | cut -c1-7)"
echo "full=$FULL_SHA" >> "$GITHUB_OUTPUT"
echo "short=$SHORT_SHA" >> "$GITHUB_OUTPUT"
echo "Promoting $FULL_SHA (images tagged $SHORT_SHA)"
- name: Verify the staging E2E gate passed for this commit
# Use the built-in Actions token (GITHUB_TOKEN is the documented name;
# it carries repository read scope), NOT REGISTRY_TOKEN — the registry
# token has no repo scope, so the commit-status API returns 403.
run: |
STATUS_JSON=$(curl -fsS \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://${REGISTRY}/api/v1/repos/${{ gitea.repository }}/commits/${{ steps.resolve.outputs.full }}/status")
echo "$STATUS_JSON" | python3 -c "
import json, sys
d = json.load(sys.stdin)
ok = [s for s in d.get('statuses', [])
if 'E2E Journeys against Staging' in s.get('context', '')
and s.get('status') == 'success']
if not ok:
print('REFUSED: no successful \"E2E Journeys against Staging\" status on this commit.')
print('Contexts found:', [s.get('context') for s in d.get('statuses', [])])
sys.exit(1)
print('E2E gate verified green for this commit.')
"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Retag approved images as prod (keeping rollback pointer)
run: |
SHORT_SHA="${{ steps.resolve.outputs.short }}"
for IMAGE in \
"${REGISTRY}/${BACKEND_IMAGE_NAME}" \
"${REGISTRY}/${FRONTEND_IMAGE_NAME}" \
"${REGISTRY}/${PIPELINE_IMAGE_NAME}"; do
# Keep a rollback pointer before moving :prod
docker buildx imagetools create -t "${IMAGE}:prod-previous" "${IMAGE}:prod" || true
docker buildx imagetools create -t "${IMAGE}:prod" "${IMAGE}:${SHORT_SHA}"
echo "Promoted ${IMAGE}:${SHORT_SHA} -> :prod"
done
- name: Trigger production stack update
run: curl -fsSk -X POST "${{ secrets.PORTAINER_PROD_WEBHOOK }}"
- name: Wait for production to become healthy
run: |
echo "Polling ${PROD_BASE_URL} for up to 5 minutes..."
for i in $(seq 1 60); do
if curl -fsS -o /dev/null --max-time 10 "${PROD_BASE_URL}/"; then
echo "Production is up (attempt $i)"
exit 0
fi
sleep 5
done
echo "Production did not become healthy in time" >&2
exit 1
env:
PROD_BASE_URL: ${{ secrets.PROD_BASE_URL }}
+6 -1
View File
@@ -1,2 +1,7 @@
venv venv
backend/__pycache__ __pycache__/
# dbt local build artifacts (embed absolute paths + anonymous-usage UUID)
pipeline/transform/target/
pipeline/transform/logs/
pipeline/transform/.user.yml
@@ -0,0 +1,7 @@
[ 3229ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13147ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 29488ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 183884ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 193559ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 213136ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
[ 216340ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/146678-welland-primary-school:0
@@ -0,0 +1,4 @@
[ 3260ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13186ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 155792ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91+3:0
[ 165424ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91+3:0
@@ -0,0 +1,4 @@
[ 3144ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13088ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 23226ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 33141ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
@@ -0,0 +1,2 @@
[ 3090ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13086ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1,4 @@
[ 3320ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13262ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 31275ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 167053ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,2 @@
[ 3489ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=136916&metric=attainment_8_score:0
[ 13346ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=136916&metric=attainment_8_score:0
@@ -0,0 +1,4 @@
[ 67ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
[ 3111ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/146678-welland-primary-school:0
[ 13084ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/146678-welland-primary-school:0
[ 70899ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/146678-welland-primary-school:0
@@ -0,0 +1,2 @@
[ 3297ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13095ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,3 @@
[ 3677ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13096ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 480177ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,2 @@
[ 4073ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=136916&metric=attainment_8_score:0
[ 13162ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=136916&metric=attainment_8_score:0
@@ -0,0 +1,14 @@
[ 3410ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct:0
[ 13266ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct:0
[ 41131ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct:0
[ 49979ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 59609ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 66865ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 77770ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161%2C113105:0
[ 87487ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161%2C113105:0
[ 213040ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 222647ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 240300ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161:0
[ 248166ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161%2C136916:0
[ 257801ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?metric=rwm_expected_pct&urns=142161%2C136916:0
[ 270504ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
@@ -0,0 +1,2 @@
[ 3428ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C136916&metric=rwm_expected_pct:0
[ 13145ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C136916&metric=rwm_expected_pct:0
@@ -0,0 +1,3 @@
[ 61ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
[ 3522ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C136916&metric=rwm_expected_pct:0
[ 13114ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C136916&metric=rwm_expected_pct:0
@@ -0,0 +1,5 @@
[ 3857ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105&metric=rwm_expected_pct:0
[ 13294ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105&metric=rwm_expected_pct:0
[ 73049ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105&metric=rwm_expected_pct:0
[ 95050ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105%2C124613&metric=rwm_expected_pct:0
[ 104770ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/compare?urns=142161%2C113105%2C124613&metric=rwm_expected_pct:0
@@ -0,0 +1,18 @@
[ 3222ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 13105ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 47024ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 129393ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull:0
[ 138906ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull:0
[ 173757ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 183459ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 196217ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
[ 200016ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/148084-lady-katherine-leveson-church-of-england-primary-school:0
[ 209230ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/148084-lady-katherine-leveson-church-of-england-primary-school:0
[ 215436ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 225403ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 260204ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/104049-sharmans-cross-junior-school:0
[ 270092ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/104049-sharmans-cross-junior-school:0
[ 290140ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/104049-sharmans-cross-junior-school:0
[ 1476417ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 1486368ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
[ 1506402ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?local_authority=Solihull&metric=rwm_expected_pct:0
@@ -0,0 +1,4 @@
[ 3180ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 7050ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 13109ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 23380ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
@@ -0,0 +1,2 @@
[ 3354ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13301ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1 @@
[ 68ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
@@ -0,0 +1 @@
[ 71ms] [WARNING] Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options @ https://schoolcompare.co.uk/_next/static/chunks/b6104424f97d1001.js:0
@@ -0,0 +1 @@
[ 68ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
@@ -0,0 +1,3 @@
[ 3407ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91%203DL:0
[ 13281ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91%203DL:0
[ 33311ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=B91%203DL:0
@@ -0,0 +1,3 @@
[ 3178ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 9456ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?postcode=B91+3DL&radius=1:0
[ 19269ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?postcode=B91+3DL&radius=1:0
@@ -0,0 +1,4 @@
[ 3422ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13307ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 33265ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[15619214ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,2 @@
[ 3300ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13157ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1,2 @@
[ 3263ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 13184ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
@@ -0,0 +1,2 @@
[ 3142ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
[ 13108ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/1944d035eb1dfa50.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings:0
@@ -0,0 +1,2 @@
[ 5101581ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/8903db4d490d6a65.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 5101581ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1,4 @@
[ 3285ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 13107ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 33154ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
[ 37100ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/:0
@@ -0,0 +1,2 @@
[ 3253ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
[ 9999ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/?search=Welland+Primary:0
@@ -0,0 +1,2 @@
[ 3316ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
[ 13172ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/school/136916-the-castle-school:0
@@ -0,0 +1,2 @@
[ 3218ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?metric=rwm_high_pct:0
[ 13206ms] [WARNING] The resource https://schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://schoolcompare.co.uk/rankings?metric=rwm_high_pct:0
@@ -0,0 +1 @@
[ 77ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
@@ -0,0 +1 @@
[ 72ms] [WARNING] Deprecated API for given entry type. @ https://analytics.schoolcompare.co.uk/script.js:0
@@ -0,0 +1,2 @@
[ 3633ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=101038%2C101022%2C101036&metric=rwm_expected_pct:0
[ 13405ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=101038%2C101022%2C101036&metric=rwm_expected_pct:0
@@ -0,0 +1,10 @@
[ 336ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 338ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 351ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 3412ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
[ 10491ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 13493ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
[ 25526ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 28528ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
[ 55600ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 58602ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
@@ -0,0 +1,12 @@
[ 185ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 204ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 231ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/national-averages:0
[ 3299ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 10242ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 13245ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 25282ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 28285ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 215055ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 218057ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 260123ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/compare?urns=101038,101022:0
[ 263125ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,2 @@
[ 3573ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
[ 13319ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 166ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3388ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1 @@
[ 3248ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101038%2C101022&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 95ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://stx.schoolcompare.co.uk/search?search=primary:0
[ 3287ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/search?search=primary:0
@@ -0,0 +1,3 @@
[ 3271ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/:0
[ 8281ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 11313ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,2 @@
[ 3730ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=137306%2C138690&metric=rwm_expected_pct:0
[ 33217ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=137306%2C138690&metric=rwm_expected_pct:0
@@ -0,0 +1,3 @@
[ 137ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3227ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 7230ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,2 @@
[ 3272ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=137306%2C138690%2C139016&metric=rwm_expected_pct:0
[ 9317ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=137306%2C138690%2C139016&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 3495ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101037%2C101026%2C101014%2C101038%2C101022&metric=rwm_expected_pct:0
[ 33343ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=101037%2C101026%2C101014%2C101038%2C101022&metric=rwm_expected_pct:0
@@ -0,0 +1,3 @@
[ 166ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3265ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 33242ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,3 @@
[ 210ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3561ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?postcode=B1%201BB:0
[ 33283ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?postcode=B1%201BB:0
@@ -0,0 +1,14 @@
[ 320ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3662ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?postcode=B1%201BB:0
[ 10839ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?postcode=B1%201BB:0
[ 16913ms] TypeError: r.current?.requestFullscreen is not a function
at https://stx.schoolcompare.co.uk/_next/static/chunks/a94dcea45b9ebb2c.js:1:25166
at sY (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:160839)
at https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:166727
at tD (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:29334)
at s3 (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:162072)
at fC (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:198038)
at fN (https://stx.schoolcompare.co.uk/_next/static/chunks/69be39811437728d.js:1:197860)
at eval (eval at <anonymous> (eval at evaluate (:303:30)), <anonymous>:4:16)
at eval (eval at evaluate (:303:30), <anonymous>:4:50)
at UtilityScript.evaluate (<anonymous>:305:16)
@@ -0,0 +1,5 @@
[ 213ms] [ERROR] Failed to load resource: the server responded with a status of 500 () @ https://stx.schoolcompare.co.uk/api/la-averages:0
[ 3418ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[ 33266ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[242896019ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
[257299531ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/?search=primary:0
@@ -0,0 +1,2 @@
[ 3717ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
[ 13359ms] [WARNING] The resource https://www.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://www.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 70ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8471/favicon.ico:0
@@ -0,0 +1 @@
[ 73ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8471/favicon.ico:0
@@ -0,0 +1,3 @@
[ 3942ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
[ 131774ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362&metric=rwm_expected_pct:0
[ 419746ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 50ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8492/favicon.ico:0
@@ -0,0 +1 @@
[ 3664ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3236ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 37ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8493/favicon.ico:0
@@ -0,0 +1 @@
[ 42ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8494/favicon.ico:0
@@ -0,0 +1 @@
[ 40ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8495/favicon.ico:0
@@ -0,0 +1 @@
[ 3479ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3334ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3462ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 3520ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=136276%2C137086%2C102052&metric=attainment_8_score:0
[26254907ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=136276%2C137086%2C102052&metric=attainment_8_score:0
@@ -0,0 +1 @@
[ 3498ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3382ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1,3 @@
[ 3562ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
[ 84848ms] [WARNING] Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently @ :5
[ 122267ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=reading_expected_pct:0
@@ -0,0 +1 @@
[ 3424ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=136276%2C137086%2C102052&metric=attainment_8_score:0
@@ -0,0 +1 @@
[ 3313ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=136276%2C137086%2C102052&metric=attainment_8_score:0
@@ -0,0 +1 @@
[ 3511ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C136276&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 3364ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C136276&metric=rwm_expected_pct:0
@@ -0,0 +1,2 @@
[ 3588ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
[ 49500ms] [WARNING] The resource https://stx.schoolcompare.co.uk/_next/static/chunks/14a927d6c03d3a7e.css was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ https://stx.schoolcompare.co.uk/compare?urns=138690%2C145362%2C100140&metric=rwm_expected_pct:0
@@ -0,0 +1 @@
[ 44ms] [ERROR] Failed to load resource: the server responded with a status of 404 (File not found) @ http://localhost:8791/favicon.ico:0
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

@@ -0,0 +1,151 @@
- generic [active] [ref=f1e1]:
- link "Skip to main content" [ref=f1e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f1e3]:
- link "SchoolCompare home" [ref=f1e5] [cursor=pointer]:
- /url: /
- img [ref=f1e7]
- generic [ref=f1e11]: SchoolCompare
- navigation "Main navigation" [ref=f1e12]:
- link "Search" [ref=f1e13] [cursor=pointer]:
- /url: /
- img [ref=f1e15]
- generic [ref=f1e18]: Search
- link "Compare" [ref=f1e19] [cursor=pointer]:
- /url: /compare
- img [ref=f1e21]
- generic [ref=f1e24]: Compare
- link "Rankings" [ref=f1e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f1e27]
- generic [ref=f1e28]: Rankings
- link "Admissions" [ref=f1e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f1e31]
- generic [ref=f1e34]: Admissions
- main [ref=f1e35]:
- generic [ref=f1e36]:
- heading "Every school in England, compared." [level=1] [ref=f1e38]:
- text: Every school in England,
- emphasis [ref=f1e39]: compared.
- generic [ref=f1e42]:
- searchbox "School name or postcode" [ref=f1e43]
- button "Search" [ref=f1e44] [cursor=pointer]
- button "Schools near me" [ref=f1e47] [cursor=pointer]:
- img [ref=f1e48]
- text: Schools near me
- generic [ref=f1e51]:
- generic [ref=f1e52]:
- generic [ref=f1e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f1e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e55]:
- generic [ref=f1e56]:
- generic [ref=f1e57]: Secondary · Deadline
- generic [ref=f1e59]: 121days
- generic [ref=f1e60]: Secondary applications close
- generic [ref=f1e61]: Sat, 31 October 2026
- generic [ref=f1e62]:
- generic [ref=f1e63]: Primary · Deadline
- generic [ref=f1e65]: 197days
- generic [ref=f1e66]: Primary applications close
- generic [ref=f1e67]: Fri, 15 January 2027
- generic [ref=f1e68]:
- generic [ref=f1e69]: Secondary · Offer Day
- generic [ref=f1e71]: 242days
- generic [ref=f1e72]: Secondary National Offer Day
- generic [ref=f1e73]: Mon, 1 March 2027
- generic [ref=f1e74]:
- generic [ref=f1e75]: Primary · Offer Day
- generic [ref=f1e77]: 288days
- generic [ref=f1e78]: Primary National Offer Day
- generic [ref=f1e79]: Fri, 16 April 2027
- generic [ref=f1e80]:
- generic [ref=f1e81]: Start exploring
- generic [ref=f1e82]:
- link "Top-rated primary schools" [ref=f1e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f1e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f1e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f1e89]:
- generic [ref=f1e90]:
- heading "What you'll see on every school" [level=2] [ref=f1e91]
- generic [ref=f1e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f1e93]:
- generic [ref=f1e95]:
- generic [ref=f1e96]: Performance
- generic [ref=f1e97]: Results against the national average
- paragraph [ref=f1e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f1e100]:
- generic [ref=f1e101]: Judgement
- generic [ref=f1e102]: Ofsted at a glance
- paragraph [ref=f1e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f1e105]:
- generic [ref=f1e106]: Compare
- generic [ref=f1e107]: Side-by-side shortlists
- paragraph [ref=f1e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f1e110]:
- generic [ref=f1e111]:
- generic [ref=f1e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f1e113]
- paragraph [ref=f1e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f1e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f1e116]:
- heading "Coverage at a glance" [level=3] [ref=f1e117]
- generic [ref=f1e118]:
- generic [ref=f1e119]: Schools covered
- generic [ref=f1e120]: 24,000+
- generic [ref=f1e121]:
- generic [ref=f1e122]: Local authorities
- generic [ref=f1e123]: "182"
- generic [ref=f1e124]:
- generic [ref=f1e125]: Phases
- generic [ref=f1e126]: Primary & Secondary
- generic [ref=f1e127]:
- generic [ref=f1e128]: Latest results year
- generic [ref=f1e129]: 2024/25
- generic [ref=f1e130]:
- generic [ref=f1e131]: Historical data
- generic [ref=f1e132]: 20162025
- generic [ref=f1e133]:
- generic [ref=f1e134]: Metrics per school
- generic [ref=f1e135]: 40+
- contentinfo [ref=f1e136]:
- generic [ref=f1e137]:
- generic [ref=f1e138]:
- generic [ref=f1e139]:
- heading "SchoolCompare" [level=3] [ref=f1e140]
- paragraph [ref=f1e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f1e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f1e143]:
- heading "Product" [level=4] [ref=f1e144]
- list [ref=f1e145]:
- listitem [ref=f1e146]:
- link "Search schools" [ref=f1e147] [cursor=pointer]:
- /url: /
- listitem [ref=f1e148]:
- link "Rankings" [ref=f1e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f1e150]:
- link "Compare shortlist" [ref=f1e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f1e152]:
- link "Admissions guide" [ref=f1e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e154]:
- heading "Resources" [level=4] [ref=f1e155]
- list [ref=f1e156]:
- listitem [ref=f1e157]:
- link "School Performance Tables" [ref=f1e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f1e159]:
- link "Ofsted reports" [ref=f1e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f1e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f1e163]
@@ -0,0 +1,151 @@
- generic [ref=f1e1]:
- link "Skip to main content" [ref=f1e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f1e3]:
- link "SchoolCompare home" [ref=f1e5] [cursor=pointer]:
- /url: /
- img [ref=f1e7]
- generic [ref=f1e11]: SchoolCompare
- navigation "Main navigation" [ref=f1e12]:
- link "Search" [ref=f1e13] [cursor=pointer]:
- /url: /
- img [ref=f1e15]
- generic [ref=f1e18]: Search
- link "Compare" [ref=f1e19] [cursor=pointer]:
- /url: /compare
- img [ref=f1e21]
- generic [ref=f1e24]: Compare
- link "Rankings" [ref=f1e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f1e27]
- generic [ref=f1e28]: Rankings
- link "Admissions" [ref=f1e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f1e31]
- generic [ref=f1e34]: Admissions
- main [ref=f1e35]:
- generic [ref=f1e36]:
- heading "Every school in England, compared." [level=1] [ref=f1e38]:
- text: Every school in England,
- emphasis [ref=f1e39]: compared.
- generic [ref=f1e42]:
- searchbox "School name or postcode" [active] [ref=f1e43]
- button "Search" [ref=f1e44] [cursor=pointer]
- button "Schools near me" [ref=f1e47] [cursor=pointer]:
- img [ref=f1e48]
- text: Schools near me
- generic [ref=f1e51]:
- generic [ref=f1e52]:
- generic [ref=f1e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f1e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e55]:
- generic [ref=f1e56]:
- generic [ref=f1e57]: Secondary · Deadline
- generic [ref=f1e59]: 121days
- generic [ref=f1e60]: Secondary applications close
- generic [ref=f1e61]: Sat, 31 October 2026
- generic [ref=f1e62]:
- generic [ref=f1e63]: Primary · Deadline
- generic [ref=f1e65]: 197days
- generic [ref=f1e66]: Primary applications close
- generic [ref=f1e67]: Fri, 15 January 2027
- generic [ref=f1e68]:
- generic [ref=f1e69]: Secondary · Offer Day
- generic [ref=f1e71]: 242days
- generic [ref=f1e72]: Secondary National Offer Day
- generic [ref=f1e73]: Mon, 1 March 2027
- generic [ref=f1e74]:
- generic [ref=f1e75]: Primary · Offer Day
- generic [ref=f1e77]: 288days
- generic [ref=f1e78]: Primary National Offer Day
- generic [ref=f1e79]: Fri, 16 April 2027
- generic [ref=f1e80]:
- generic [ref=f1e81]: Start exploring
- generic [ref=f1e82]:
- link "Top-rated primary schools" [ref=f1e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f1e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f1e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f1e89]:
- generic [ref=f1e90]:
- heading "What you'll see on every school" [level=2] [ref=f1e91]
- generic [ref=f1e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f1e93]:
- generic [ref=f1e95]:
- generic [ref=f1e96]: Performance
- generic [ref=f1e97]: Results against the national average
- paragraph [ref=f1e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f1e100]:
- generic [ref=f1e101]: Judgement
- generic [ref=f1e102]: Ofsted at a glance
- paragraph [ref=f1e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f1e105]:
- generic [ref=f1e106]: Compare
- generic [ref=f1e107]: Side-by-side shortlists
- paragraph [ref=f1e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f1e110]:
- generic [ref=f1e111]:
- generic [ref=f1e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f1e113]
- paragraph [ref=f1e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f1e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f1e116]:
- heading "Coverage at a glance" [level=3] [ref=f1e117]
- generic [ref=f1e118]:
- generic [ref=f1e119]: Schools covered
- generic [ref=f1e120]: 24,000+
- generic [ref=f1e121]:
- generic [ref=f1e122]: Local authorities
- generic [ref=f1e123]: "182"
- generic [ref=f1e124]:
- generic [ref=f1e125]: Phases
- generic [ref=f1e126]: Primary & Secondary
- generic [ref=f1e127]:
- generic [ref=f1e128]: Latest results year
- generic [ref=f1e129]: 2024/25
- generic [ref=f1e130]:
- generic [ref=f1e131]: Historical data
- generic [ref=f1e132]: 20162025
- generic [ref=f1e133]:
- generic [ref=f1e134]: Metrics per school
- generic [ref=f1e135]: 40+
- contentinfo [ref=f1e136]:
- generic [ref=f1e137]:
- generic [ref=f1e138]:
- generic [ref=f1e139]:
- heading "SchoolCompare" [level=3] [ref=f1e140]
- paragraph [ref=f1e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f1e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f1e143]:
- heading "Product" [level=4] [ref=f1e144]
- list [ref=f1e145]:
- listitem [ref=f1e146]:
- link "Search schools" [ref=f1e147] [cursor=pointer]:
- /url: /
- listitem [ref=f1e148]:
- link "Rankings" [ref=f1e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f1e150]:
- link "Compare shortlist" [ref=f1e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f1e152]:
- link "Admissions guide" [ref=f1e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e154]:
- heading "Resources" [level=4] [ref=f1e155]
- list [ref=f1e156]:
- listitem [ref=f1e157]:
- link "School Performance Tables" [ref=f1e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f1e159]:
- link "Ofsted reports" [ref=f1e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f1e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f1e163]
@@ -0,0 +1,151 @@
- generic [ref=f1e1]:
- link "Skip to main content" [ref=f1e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f1e3]:
- link "SchoolCompare home" [ref=f1e5] [cursor=pointer]:
- /url: /
- img [ref=f1e7]
- generic [ref=f1e11]: SchoolCompare
- navigation "Main navigation" [ref=f1e12]:
- link "Search" [ref=f1e13] [cursor=pointer]:
- /url: /
- img [ref=f1e15]
- generic [ref=f1e18]: Search
- link "Compare" [ref=f1e19] [cursor=pointer]:
- /url: /compare
- img [ref=f1e21]
- generic [ref=f1e24]: Compare
- link "Rankings" [ref=f1e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f1e27]
- generic [ref=f1e28]: Rankings
- link "Admissions" [ref=f1e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f1e31]
- generic [ref=f1e34]: Admissions
- main [ref=f1e35]:
- generic [ref=f1e36]:
- heading "Every school in England, compared." [level=1] [ref=f1e38]:
- text: Every school in England,
- emphasis [ref=f1e39]: compared.
- generic [ref=f1e42]:
- searchbox "School name or postcode" [active] [ref=f1e43]: Welland Primary
- button "Search" [ref=f1e44] [cursor=pointer]
- button "Schools near me" [ref=f1e47] [cursor=pointer]:
- img [ref=f1e48]
- text: Schools near me
- generic [ref=f1e51]:
- generic [ref=f1e52]:
- generic [ref=f1e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f1e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e55]:
- generic [ref=f1e56]:
- generic [ref=f1e57]: Secondary · Deadline
- generic [ref=f1e59]: 121days
- generic [ref=f1e60]: Secondary applications close
- generic [ref=f1e61]: Sat, 31 October 2026
- generic [ref=f1e62]:
- generic [ref=f1e63]: Primary · Deadline
- generic [ref=f1e65]: 197days
- generic [ref=f1e66]: Primary applications close
- generic [ref=f1e67]: Fri, 15 January 2027
- generic [ref=f1e68]:
- generic [ref=f1e69]: Secondary · Offer Day
- generic [ref=f1e71]: 242days
- generic [ref=f1e72]: Secondary National Offer Day
- generic [ref=f1e73]: Mon, 1 March 2027
- generic [ref=f1e74]:
- generic [ref=f1e75]: Primary · Offer Day
- generic [ref=f1e77]: 288days
- generic [ref=f1e78]: Primary National Offer Day
- generic [ref=f1e79]: Fri, 16 April 2027
- generic [ref=f1e80]:
- generic [ref=f1e81]: Start exploring
- generic [ref=f1e82]:
- link "Top-rated primary schools" [ref=f1e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f1e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f1e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f1e89]:
- generic [ref=f1e90]:
- heading "What you'll see on every school" [level=2] [ref=f1e91]
- generic [ref=f1e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f1e93]:
- generic [ref=f1e95]:
- generic [ref=f1e96]: Performance
- generic [ref=f1e97]: Results against the national average
- paragraph [ref=f1e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f1e100]:
- generic [ref=f1e101]: Judgement
- generic [ref=f1e102]: Ofsted at a glance
- paragraph [ref=f1e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f1e105]:
- generic [ref=f1e106]: Compare
- generic [ref=f1e107]: Side-by-side shortlists
- paragraph [ref=f1e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f1e110]:
- generic [ref=f1e111]:
- generic [ref=f1e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f1e113]
- paragraph [ref=f1e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f1e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f1e116]:
- heading "Coverage at a glance" [level=3] [ref=f1e117]
- generic [ref=f1e118]:
- generic [ref=f1e119]: Schools covered
- generic [ref=f1e120]: 24,000+
- generic [ref=f1e121]:
- generic [ref=f1e122]: Local authorities
- generic [ref=f1e123]: "182"
- generic [ref=f1e124]:
- generic [ref=f1e125]: Phases
- generic [ref=f1e126]: Primary & Secondary
- generic [ref=f1e127]:
- generic [ref=f1e128]: Latest results year
- generic [ref=f1e129]: 2024/25
- generic [ref=f1e130]:
- generic [ref=f1e131]: Historical data
- generic [ref=f1e132]: 20162025
- generic [ref=f1e133]:
- generic [ref=f1e134]: Metrics per school
- generic [ref=f1e135]: 40+
- contentinfo [ref=f1e136]:
- generic [ref=f1e137]:
- generic [ref=f1e138]:
- generic [ref=f1e139]:
- heading "SchoolCompare" [level=3] [ref=f1e140]
- paragraph [ref=f1e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f1e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f1e143]:
- heading "Product" [level=4] [ref=f1e144]
- list [ref=f1e145]:
- listitem [ref=f1e146]:
- link "Search schools" [ref=f1e147] [cursor=pointer]:
- /url: /
- listitem [ref=f1e148]:
- link "Rankings" [ref=f1e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f1e150]:
- link "Compare shortlist" [ref=f1e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f1e152]:
- link "Admissions guide" [ref=f1e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e154]:
- heading "Resources" [level=4] [ref=f1e155]
- list [ref=f1e156]:
- listitem [ref=f1e157]:
- link "School Performance Tables" [ref=f1e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f1e159]:
- link "Ofsted reports" [ref=f1e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f1e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f1e163]
@@ -0,0 +1,108 @@
- generic [active] [ref=f1e1]:
- link "Skip to main content" [ref=f1e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f1e3]:
- link "SchoolCompare home" [ref=f1e5] [cursor=pointer]:
- /url: /
- img [ref=f1e7]
- generic [ref=f1e11]: SchoolCompare
- navigation "Main navigation" [ref=f1e12]:
- link "Search" [ref=f1e13] [cursor=pointer]:
- /url: /
- img [ref=f1e15]
- generic [ref=f1e18]: Search
- link "Compare" [ref=f1e19] [cursor=pointer]:
- /url: /compare
- img [ref=f1e21]
- generic [ref=f1e24]: Compare
- link "Rankings" [ref=f1e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f1e27]
- generic [ref=f1e28]: Rankings
- link "Admissions" [ref=f1e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f1e31]
- generic [ref=f1e34]: Admissions
- main [ref=f1e35]:
- generic [ref=f1e36]:
- generic [ref=f1e40]:
- generic [ref=f1e42]:
- searchbox "School name or postcode" [ref=f1e43]: Welland Primary
- button "Search" [ref=f1e44] [cursor=pointer]
- generic [ref=f1e164]:
- combobox [ref=f1e165] [cursor=pointer]:
- option "All Phases" [selected]
- option "Primary"
- button "Advanced" [ref=f1e166] [cursor=pointer]: Advanced
- button "Clear" [ref=f1e168] [cursor=pointer]
- generic [ref=f1e169]:
- generic [ref=f1e170]:
- heading "1 school found" [level=2] [ref=f1e171]
- combobox [ref=f1e173] [cursor=pointer]:
- 'option "Sort: Relevance" [selected]'
- option "Highest Reading, Writing & Maths %"
- option "Lowest Reading, Writing & Maths %"
- option "Name AZ"
- generic [ref=f1e175]:
- text: "Search: Welland Primary"
- link "×" [ref=f1e176] [cursor=pointer]:
- /url: /
- generic [ref=f1e178]:
- generic [ref=f1e179]:
- generic [ref=f1e180]:
- link "Welland Primary School" [ref=f1e181] [cursor=pointer]:
- /url: /school/146678-welland-primary-school
- generic [ref=f1e182]: Good · 2023
- generic [ref=f1e183]:
- generic [ref=f1e184]: Primary
- generic [ref=f1e185]: Academy converter
- generic [ref=f1e186]: Ages 411
- generic [ref=f1e187]:
- generic [ref=f1e188]:
- strong [ref=f1e189]: 74%
- 'generic "Previous year: 76.0%" [ref=f1e190]':
- img "Trend down" [ref=f1e191]
- generic [ref=f1e193]: Reading, Writing & Maths
- generic [ref=f1e194]: +12 pts vs national
- generic [ref=f1e195]:
- strong [ref=f1e196]: "131"
- generic [ref=f1e197]: pupils
- generic [ref=f1e199]: Worcestershire
- generic [ref=f1e200]:
- link "View" [ref=f1e201] [cursor=pointer]:
- /url: /school/146678-welland-primary-school
- button "+ Compare" [ref=f1e202] [cursor=pointer]
- contentinfo [ref=f1e136]:
- generic [ref=f1e137]:
- generic [ref=f1e138]:
- generic [ref=f1e139]:
- heading "SchoolCompare" [level=3] [ref=f1e140]
- paragraph [ref=f1e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f1e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f1e143]:
- heading "Product" [level=4] [ref=f1e144]
- list [ref=f1e145]:
- listitem [ref=f1e146]:
- link "Search schools" [ref=f1e147] [cursor=pointer]:
- /url: /
- listitem [ref=f1e148]:
- link "Rankings" [ref=f1e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f1e150]:
- link "Compare shortlist" [ref=f1e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f1e152]:
- link "Admissions guide" [ref=f1e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f1e154]:
- heading "Resources" [level=4] [ref=f1e155]
- list [ref=f1e156]:
- listitem [ref=f1e157]:
- link "School Performance Tables" [ref=f1e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f1e159]:
- link "Ofsted reports" [ref=f1e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f1e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f1e163]
@@ -0,0 +1,268 @@
- generic [active] [ref=f2e1]:
- link "Skip to main content" [ref=f2e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f2e3]:
- link "SchoolCompare home" [ref=f2e5] [cursor=pointer]:
- /url: /
- img [ref=f2e7]
- generic [ref=f2e11]: SchoolCompare
- navigation "Main navigation" [ref=f2e12]:
- link "Search" [ref=f2e13] [cursor=pointer]:
- /url: /
- img [ref=f2e15]
- generic [ref=f2e18]: Search
- link "Compare" [ref=f2e19] [cursor=pointer]:
- /url: /compare
- img [ref=f2e21]
- generic [ref=f2e24]: Compare
- link "Rankings" [ref=f2e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f2e27]
- generic [ref=f2e28]: Rankings
- link "Admissions" [ref=f2e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f2e31]
- generic [ref=f2e34]: Admissions
- main [ref=f2e35]:
- generic [ref=f2e36]:
- button "Back" [ref=f2e37] [cursor=pointer]:
- generic [ref=f2e38]:
- text: Back
- generic [ref=f2e39]:
- generic [ref=f2e40]:
- generic [ref=f2e41]:
- img [ref=f2e45] [cursor=pointer]
- generic [ref=f2e48]:
- link "Leaflet" [ref=f2e49] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f2e50]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f2e54] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f2e55] [cursor=pointer]:
- generic [ref=f2e56]:
- img [ref=f2e57]
- text: Open full map
- generic [ref=f2e59]:
- generic [ref=f2e60]:
- heading "Welland Primary School" [level=1] [ref=f2e61]
- generic [ref=f2e62]:
- generic [ref=f2e63]: Worcestershire
- generic [ref=f2e64]: Academy converter
- paragraph [ref=f2e65]:
- text: Marlbank Road, Welland, Malvern, WR13 6NE ·
- button "View on map ↗" [ref=f2e66] [cursor=pointer]
- button "+ Add to Compare" [ref=f2e68] [cursor=pointer]
- navigation "Page sections" [ref=f2e69]:
- button "Back to top" [ref=f2e70] [cursor=pointer]:
- generic [ref=f2e71]:
- button "Section Ofsted" [ref=f2e72] [cursor=pointer]:
- generic [ref=f2e73]:
- generic [ref=f2e74]: Section
- generic [ref=f2e75]: Ofsted
- generic [ref=f2e76]:
- generic [ref=f2e77]:
- heading "Ofsted Rating Inspected 6 June 2023 Ofsted reports ↗" [level=2] [ref=f2e78]:
- text: Ofsted Rating
- generic [ref=f2e79]: Inspected 6 June 2023
- link "Ofsted reports ↗" [ref=f2e80] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/146678
- generic [ref=f2e82]: Good
- paragraph [ref=f2e83]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections of state-funded schools.
- paragraph [ref=f2e84]:
- text: Rated
- strong [ref=f2e85]: Good
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f2e86]:
- heading "SATs Results (2024/25)" [level=2] [ref=f2e87]
- paragraph [ref=f2e88]: End-of-primary-school tests taken by Year 6 pupils. National averages shown for comparison.
- generic [ref=f2e89]:
- generic [ref=f2e90]:
- generic [ref=f2e91]: Reading, Writing & Maths combined
- generic [ref=f2e92]:
- text: 74.0%
- generic [ref=f2e93]: +12 pts
- generic [ref=f2e94]: "National avg: 62%"
- generic [ref=f2e95]:
- generic [ref=f2e96]: Exceeding expected level (Reading, Writing & Maths)
- generic [ref=f2e97]:
- text: 11.0%
- generic [ref=f2e98]: +3 pts
- generic [ref=f2e99]: "National avg: 8%"
- generic [ref=f2e100]:
- generic [ref=f2e101]: "?"
- generic [ref=f2e102]:
- generic [ref=f2e103]:
- text: Why is combined lower? A pupil is only counted if they met the bar in
- strong [ref=f2e104]: all three
- text: subjects. Some passed reading but not writing; some passed writing but not maths.
- generic [ref=f2e105]:
- generic [ref=f2e106]:
- text: Reading
- strong [ref=f2e107]: 74%
- generic [ref=f2e108]: ·
- generic [ref=f2e109]:
- text: Writing
- strong [ref=f2e110]: 74%
- generic [ref=f2e111]: ·
- generic [ref=f2e112]:
- text: Maths
- strong [ref=f2e113]: 81%
- generic [ref=f2e114]:
- generic [ref=f2e115]:
- text: All three
- strong [ref=f2e116]: 74%
- generic [ref=f2e117]:
- generic [ref=f2e118]:
- generic [ref=f2e119]:
- generic [ref=f2e120]: Reading
- generic [ref=f2e121]:
- generic:
- generic: 75%
- generic [ref=f2e122]:
- generic [ref=f2e124]:
- generic [ref=f2e125]: Expected
- generic [ref=f2e126]: 74%
- generic [ref=f2e130]:
- generic [ref=f2e131]: Exceeding
- generic [ref=f2e132]: 48%
- generic [ref=f2e135]:
- generic [ref=f2e137]: 0%
- generic [ref=f2e139]: 25%
- generic [ref=f2e141]: 50%
- generic [ref=f2e143]: 75%
- generic [ref=f2e145]: 100%
- generic [ref=f2e146]:
- generic [ref=f2e147]: Writing
- generic [ref=f2e148]:
- generic:
- generic: 72%
- generic [ref=f2e149]:
- generic [ref=f2e151]:
- generic [ref=f2e152]: Expected
- generic [ref=f2e153]: 74%
- generic [ref=f2e157]:
- generic [ref=f2e158]: Exceeding
- generic [ref=f2e159]: 11%
- generic [ref=f2e162]:
- generic [ref=f2e164]: 0%
- generic [ref=f2e166]: 25%
- generic [ref=f2e168]: 50%
- generic [ref=f2e170]: 75%
- generic [ref=f2e172]: 100%
- generic [ref=f2e173]:
- generic [ref=f2e174]: Maths
- generic [ref=f2e175]:
- generic:
- generic: 74%
- generic [ref=f2e176]:
- generic [ref=f2e178]:
- generic [ref=f2e179]: Expected
- generic [ref=f2e180]: 81%
- generic [ref=f2e184]:
- generic [ref=f2e185]: Exceeding
- generic [ref=f2e186]: 33%
- generic [ref=f2e189]:
- generic [ref=f2e191]: 0%
- generic [ref=f2e193]: 25%
- generic [ref=f2e195]: 50%
- generic [ref=f2e197]: 75%
- generic [ref=f2e199]: 100%
- generic [ref=f2e200]:
- generic [ref=f2e201]: Expected standard
- generic [ref=f2e203]: Exceeding / high score
- generic [ref=f2e205]: National average
- generic [ref=f2e207]:
- generic [ref=f2e208]:
- heading "Admissions" [level=2] [ref=f2e209]
- group "Admissions view" [ref=f2e210]:
- button "This year" [pressed] [ref=f2e211] [cursor=pointer]
- button "8-year trend" [ref=f2e212] [cursor=pointer]
- generic [ref=f2e215]:
- generic [ref=f2e216]:
- definition [ref=f2e217]: "21"
- term [ref=f2e218]: Places offered
- generic [ref=f2e219]:
- definition [ref=f2e220]: "19"
- term [ref=f2e221]: Wanted it first
- generic [ref=f2e222]:
- definition [ref=f2e223]:
- text: "19"
- generic [ref=f2e224]: of 19 · 100.0%
- term [ref=f2e225]: Got their first choice
- generic [ref=f2e226]:
- definition [ref=f2e227]: "45"
- term [ref=f2e228]: Applied in total
- generic [ref=f2e229]:
- heading "Pupils & Inclusion" [level=2] [ref=f2e230]
- generic [ref=f2e231]:
- generic [ref=f2e232]:
- generic [ref=f2e233]: Eligible for pupil premium
- generic [ref=f2e234]: 26.0%
- generic [ref=f2e235]: Pupils from disadvantaged backgrounds
- generic [ref=f2e236]:
- generic [ref=f2e237]: English as an additional language
- generic [ref=f2e238]: 0.0%
- generic [ref=f2e239]:
- generic [ref=f2e240]: Pupils receiving SEN support
- generic [ref=f2e241]: 4.0%
- generic [ref=f2e242]:
- generic [ref=f2e243]: Boys and girls
- generic [ref=f2e244]:
- generic [ref=f2e245]: 48%
- generic [ref=f2e246]: girls
- generic [ref=f2e247]: ·
- generic [ref=f2e248]: 52%
- generic [ref=f2e249]: boys
- 'img "Gender split: 48% girls, 52% boys" [ref=f2e250]'
- generic [ref=f2e253]: 64 girls, 70 boys
- generic [ref=f2e254]:
- heading "Results Over Time" [level=2] [ref=f2e255]
- generic [ref=f2e257]:
- generic [ref=f2e258]: ↓ Reading, Writing & Maths peaked at 81% (2022/23), currently 74%
- generic [ref=f2e259]:
- generic [ref=f2e260]: KS2 SATs · Reading, Writing & Maths
- tablist "Select metric" [ref=f2e261]:
- tab "At expected level" [selected] [ref=f2e262] [cursor=pointer]
- tab "Above expected level" [ref=f2e263] [cursor=pointer]
- tab "Pupil progress" [ref=f2e264] [cursor=pointer]
- img [ref=f2e266]
- paragraph [ref=f2e267]: "* No data for 2019/20 or 2020/21 — national assessments were cancelled due to COVID-19."
- group [ref=f2e268]:
- generic "▸ View raw year-by-year data" [ref=f2e269] [cursor=pointer]
- contentinfo [ref=f2e270]:
- generic [ref=f2e271]:
- generic [ref=f2e272]:
- generic [ref=f2e273]:
- heading "SchoolCompare" [level=3] [ref=f2e274]
- paragraph [ref=f2e275]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f2e276] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f2e277]:
- heading "Product" [level=4] [ref=f2e278]
- list [ref=f2e279]:
- listitem [ref=f2e280]:
- link "Search schools" [ref=f2e281] [cursor=pointer]:
- /url: /
- listitem [ref=f2e282]:
- link "Rankings" [ref=f2e283] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f2e284]:
- link "Compare shortlist" [ref=f2e285] [cursor=pointer]:
- /url: /compare
- listitem [ref=f2e286]:
- link "Admissions guide" [ref=f2e287] [cursor=pointer]:
- /url: /admissions
- generic [ref=f2e288]:
- heading "Resources" [level=4] [ref=f2e289]
- list [ref=f2e290]:
- listitem [ref=f2e291]:
- link "School Performance Tables" [ref=f2e292] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f2e293]:
- link "Ofsted reports" [ref=f2e294] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f2e296]: © 2026 SchoolCompare.co.uk
- alert [ref=f2e297]
@@ -0,0 +1,151 @@
- generic [active] [ref=f3e1]:
- link "Skip to main content" [ref=f3e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f3e3]:
- link "SchoolCompare home" [ref=f3e5] [cursor=pointer]:
- /url: /
- img [ref=f3e7]
- generic [ref=f3e11]: SchoolCompare
- navigation "Main navigation" [ref=f3e12]:
- link "Search" [ref=f3e13] [cursor=pointer]:
- /url: /
- img [ref=f3e15]
- generic [ref=f3e18]: Search
- link "Compare" [ref=f3e19] [cursor=pointer]:
- /url: /compare
- img [ref=f3e21]
- generic [ref=f3e24]: Compare
- link "Rankings" [ref=f3e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f3e27]
- generic [ref=f3e28]: Rankings
- link "Admissions" [ref=f3e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f3e31]
- generic [ref=f3e34]: Admissions
- main [ref=f3e35]:
- generic [ref=f3e36]:
- heading "Every school in England, compared." [level=1] [ref=f3e38]:
- text: Every school in England,
- emphasis [ref=f3e39]: compared.
- generic [ref=f3e42]:
- searchbox "School name or postcode" [ref=f3e43]
- button "Search" [ref=f3e44] [cursor=pointer]
- button "Schools near me" [ref=f3e47] [cursor=pointer]:
- img [ref=f3e48]
- text: Schools near me
- generic [ref=f3e51]:
- generic [ref=f3e52]:
- generic [ref=f3e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f3e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e55]:
- generic [ref=f3e56]:
- generic [ref=f3e57]: Secondary · Deadline
- generic [ref=f3e59]: 121days
- generic [ref=f3e60]: Secondary applications close
- generic [ref=f3e61]: Sat, 31 October 2026
- generic [ref=f3e62]:
- generic [ref=f3e63]: Primary · Deadline
- generic [ref=f3e65]: 197days
- generic [ref=f3e66]: Primary applications close
- generic [ref=f3e67]: Fri, 15 January 2027
- generic [ref=f3e68]:
- generic [ref=f3e69]: Secondary · Offer Day
- generic [ref=f3e71]: 242days
- generic [ref=f3e72]: Secondary National Offer Day
- generic [ref=f3e73]: Mon, 1 March 2027
- generic [ref=f3e74]:
- generic [ref=f3e75]: Primary · Offer Day
- generic [ref=f3e77]: 288days
- generic [ref=f3e78]: Primary National Offer Day
- generic [ref=f3e79]: Fri, 16 April 2027
- generic [ref=f3e80]:
- generic [ref=f3e81]: Start exploring
- generic [ref=f3e82]:
- link "Top-rated primary schools" [ref=f3e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f3e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f3e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f3e89]:
- generic [ref=f3e90]:
- heading "What you'll see on every school" [level=2] [ref=f3e91]
- generic [ref=f3e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f3e93]:
- generic [ref=f3e95]:
- generic [ref=f3e96]: Performance
- generic [ref=f3e97]: Results against the national average
- paragraph [ref=f3e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f3e100]:
- generic [ref=f3e101]: Judgement
- generic [ref=f3e102]: Ofsted at a glance
- paragraph [ref=f3e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f3e105]:
- generic [ref=f3e106]: Compare
- generic [ref=f3e107]: Side-by-side shortlists
- paragraph [ref=f3e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f3e110]:
- generic [ref=f3e111]:
- generic [ref=f3e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f3e113]
- paragraph [ref=f3e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f3e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f3e116]:
- heading "Coverage at a glance" [level=3] [ref=f3e117]
- generic [ref=f3e118]:
- generic [ref=f3e119]: Schools covered
- generic [ref=f3e120]: 24,000+
- generic [ref=f3e121]:
- generic [ref=f3e122]: Local authorities
- generic [ref=f3e123]: "182"
- generic [ref=f3e124]:
- generic [ref=f3e125]: Phases
- generic [ref=f3e126]: Primary & Secondary
- generic [ref=f3e127]:
- generic [ref=f3e128]: Latest results year
- generic [ref=f3e129]: 2024/25
- generic [ref=f3e130]:
- generic [ref=f3e131]: Historical data
- generic [ref=f3e132]: 20162025
- generic [ref=f3e133]:
- generic [ref=f3e134]: Metrics per school
- generic [ref=f3e135]: 40+
- contentinfo [ref=f3e136]:
- generic [ref=f3e137]:
- generic [ref=f3e138]:
- generic [ref=f3e139]:
- heading "SchoolCompare" [level=3] [ref=f3e140]
- paragraph [ref=f3e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f3e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f3e143]:
- heading "Product" [level=4] [ref=f3e144]
- list [ref=f3e145]:
- listitem [ref=f3e146]:
- link "Search schools" [ref=f3e147] [cursor=pointer]:
- /url: /
- listitem [ref=f3e148]:
- link "Rankings" [ref=f3e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f3e150]:
- link "Compare shortlist" [ref=f3e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f3e152]:
- link "Admissions guide" [ref=f3e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e154]:
- heading "Resources" [level=4] [ref=f3e155]
- list [ref=f3e156]:
- listitem [ref=f3e157]:
- link "School Performance Tables" [ref=f3e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f3e159]:
- link "Ofsted reports" [ref=f3e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f3e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f3e163]
@@ -0,0 +1,151 @@
- generic [ref=f3e1]:
- link "Skip to main content" [ref=f3e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f3e3]:
- link "SchoolCompare home" [ref=f3e5] [cursor=pointer]:
- /url: /
- img [ref=f3e7]
- generic [ref=f3e11]: SchoolCompare
- navigation "Main navigation" [ref=f3e12]:
- link "Search" [ref=f3e13] [cursor=pointer]:
- /url: /
- img [ref=f3e15]
- generic [ref=f3e18]: Search
- link "Compare" [ref=f3e19] [cursor=pointer]:
- /url: /compare
- img [ref=f3e21]
- generic [ref=f3e24]: Compare
- link "Rankings" [ref=f3e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f3e27]
- generic [ref=f3e28]: Rankings
- link "Admissions" [ref=f3e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f3e31]
- generic [ref=f3e34]: Admissions
- main [ref=f3e35]:
- generic [ref=f3e36]:
- heading "Every school in England, compared." [level=1] [ref=f3e38]:
- text: Every school in England,
- emphasis [ref=f3e39]: compared.
- generic [ref=f3e42]:
- searchbox "School name or postcode" [active] [ref=f3e43]: B91 3
- button "Search" [ref=f3e44] [cursor=pointer]
- button "Schools near me" [ref=f3e47] [cursor=pointer]:
- img [ref=f3e48]
- text: Schools near me
- generic [ref=f3e51]:
- generic [ref=f3e52]:
- generic [ref=f3e53]: Key admissions deadlines
- link "Full admissions guide →" [ref=f3e54] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e55]:
- generic [ref=f3e56]:
- generic [ref=f3e57]: Secondary · Deadline
- generic [ref=f3e59]: 121days
- generic [ref=f3e60]: Secondary applications close
- generic [ref=f3e61]: Sat, 31 October 2026
- generic [ref=f3e62]:
- generic [ref=f3e63]: Primary · Deadline
- generic [ref=f3e65]: 197days
- generic [ref=f3e66]: Primary applications close
- generic [ref=f3e67]: Fri, 15 January 2027
- generic [ref=f3e68]:
- generic [ref=f3e69]: Secondary · Offer Day
- generic [ref=f3e71]: 242days
- generic [ref=f3e72]: Secondary National Offer Day
- generic [ref=f3e73]: Mon, 1 March 2027
- generic [ref=f3e74]:
- generic [ref=f3e75]: Primary · Offer Day
- generic [ref=f3e77]: 288days
- generic [ref=f3e78]: Primary National Offer Day
- generic [ref=f3e79]: Fri, 16 April 2027
- generic [ref=f3e80]:
- generic [ref=f3e81]: Start exploring
- generic [ref=f3e82]:
- link "Top-rated primary schools" [ref=f3e83] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f3e85] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f3e87] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f3e89]:
- generic [ref=f3e90]:
- heading "What you'll see on every school" [level=2] [ref=f3e91]
- generic [ref=f3e92]: Primary or secondary — the page adapts to the phase
- generic [ref=f3e93]:
- generic [ref=f3e95]:
- generic [ref=f3e96]: Performance
- generic [ref=f3e97]: Results against the national average
- paragraph [ref=f3e98]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f3e100]:
- generic [ref=f3e101]: Judgement
- generic [ref=f3e102]: Ofsted at a glance
- paragraph [ref=f3e103]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f3e105]:
- generic [ref=f3e106]: Compare
- generic [ref=f3e107]: Side-by-side shortlists
- paragraph [ref=f3e108]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f3e110]:
- generic [ref=f3e111]:
- generic [ref=f3e112]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f3e113]
- paragraph [ref=f3e114]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f3e115]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f3e116]:
- heading "Coverage at a glance" [level=3] [ref=f3e117]
- generic [ref=f3e118]:
- generic [ref=f3e119]: Schools covered
- generic [ref=f3e120]: 24,000+
- generic [ref=f3e121]:
- generic [ref=f3e122]: Local authorities
- generic [ref=f3e123]: "182"
- generic [ref=f3e124]:
- generic [ref=f3e125]: Phases
- generic [ref=f3e126]: Primary & Secondary
- generic [ref=f3e127]:
- generic [ref=f3e128]: Latest results year
- generic [ref=f3e129]: 2024/25
- generic [ref=f3e130]:
- generic [ref=f3e131]: Historical data
- generic [ref=f3e132]: 20162025
- generic [ref=f3e133]:
- generic [ref=f3e134]: Metrics per school
- generic [ref=f3e135]: 40+
- contentinfo [ref=f3e136]:
- generic [ref=f3e137]:
- generic [ref=f3e138]:
- generic [ref=f3e139]:
- heading "SchoolCompare" [level=3] [ref=f3e140]
- paragraph [ref=f3e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f3e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f3e143]:
- heading "Product" [level=4] [ref=f3e144]
- list [ref=f3e145]:
- listitem [ref=f3e146]:
- link "Search schools" [ref=f3e147] [cursor=pointer]:
- /url: /
- listitem [ref=f3e148]:
- link "Rankings" [ref=f3e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f3e150]:
- link "Compare shortlist" [ref=f3e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f3e152]:
- link "Admissions guide" [ref=f3e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e154]:
- heading "Resources" [level=4] [ref=f3e155]
- list [ref=f3e156]:
- listitem [ref=f3e157]:
- link "School Performance Tables" [ref=f3e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f3e159]:
- link "Ofsted reports" [ref=f3e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f3e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f3e163]
@@ -0,0 +1,277 @@
- generic [ref=f3e1]:
- link "Skip to main content" [ref=f3e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f3e3]:
- link "SchoolCompare home" [ref=f3e5] [cursor=pointer]:
- /url: /
- img [ref=f3e7]
- generic [ref=f3e11]: SchoolCompare
- navigation "Main navigation" [ref=f3e12]:
- link "Search" [ref=f3e13] [cursor=pointer]:
- /url: /
- img [ref=f3e15]
- generic [ref=f3e18]: Search
- link "Compare" [ref=f3e19] [cursor=pointer]:
- /url: /compare
- img [ref=f3e21]
- generic [ref=f3e24]: Compare
- link "Rankings" [ref=f3e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f3e27]
- generic [ref=f3e28]: Rankings
- link "Admissions" [ref=f3e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f3e31]
- generic [ref=f3e34]: Admissions
- main [ref=f3e35]:
- generic [ref=f3e36]:
- generic [ref=f3e40]:
- generic [ref=f3e42]:
- searchbox "School name or postcode" [active] [ref=f3e43]: B91 3
- button "Search" [ref=f3e44] [cursor=pointer]
- generic [ref=f3e164]:
- combobox [ref=f3e165] [cursor=pointer]:
- option "All Phases" [selected]
- option "16 plus"
- option "All-through"
- option "Primary"
- option "Secondary"
- button "Advanced" [ref=f3e166] [cursor=pointer]: Advanced
- button "Clear" [ref=f3e168] [cursor=pointer]
- generic [ref=f3e169]:
- generic [ref=f3e170]:
- heading "8 schools found" [level=2] [ref=f3e171]
- combobox [ref=f3e173] [cursor=pointer]:
- 'option "Sort: Relevance" [selected]'
- option "Highest Reading, Writing & Maths %"
- option "Lowest Reading, Writing & Maths %"
- option "Highest Attainment 8"
- option "Lowest Attainment 8"
- option "Name AZ"
- generic [ref=f3e175]:
- text: "Search: B91 3"
- link "×" [ref=f3e176] [cursor=pointer]:
- /url: /
- generic [ref=f3e177]:
- generic [ref=f3e178]:
- generic [ref=f3e179]:
- generic [ref=f3e180]:
- link "Tudor Grange Academy, Solihull" [ref=f3e181] [cursor=pointer]:
- /url: /school/136310-tudor-grange-academy-solihull
- generic [ref=f3e182]: Inspected · 2025
- generic [ref=f3e183]:
- generic [ref=f3e184]: Secondary
- generic [ref=f3e185]: Academy converter
- generic [ref=f3e186]: Ages 1118
- generic [ref=f3e187]: Sixth form
- generic [ref=f3e188]: Selective
- generic [ref=f3e189]:
- generic [ref=f3e190]:
- strong [ref=f3e191]: "58.7"
- generic [ref=f3e192]: Attainment 8
- generic [ref=f3e193]: +14.4 vs LA avg
- generic [ref=f3e194]:
- strong [ref=f3e195]: "278"
- generic [ref=f3e196]: pupils
- generic [ref=f3e198]: Solihull
- generic [ref=f3e199]:
- link "View" [ref=f3e200] [cursor=pointer]:
- /url: /school/136310-tudor-grange-academy-solihull
- button "+ Compare" [ref=f3e201] [cursor=pointer]
- generic [ref=f3e202]:
- generic [ref=f3e203]:
- generic [ref=f3e204]:
- link "Solihull School" [ref=f3e205] [cursor=pointer]:
- /url: /school/104124-solihull-school
- generic [ref=f3e206]: Not yet inspected
- generic [ref=f3e207]:
- generic [ref=f3e208]: All-through
- generic [ref=f3e209]: Other independent school
- generic [ref=f3e210]: Ages 319
- generic [ref=f3e211]: Selective
- generic [ref=f3e212]:
- generic [ref=f3e213]:
- strong [ref=f3e214]: "41.4"
- generic [ref=f3e215]: Attainment 8
- generic [ref=f3e216]: "-2.9 vs LA avg"
- generic [ref=f3e217]:
- strong [ref=f3e218]: "148"
- generic [ref=f3e219]: pupils
- generic [ref=f3e221]: Solihull
- generic [ref=f3e222]:
- link "View" [ref=f3e223] [cursor=pointer]:
- /url: /school/104124-solihull-school
- button "+ Compare" [ref=f3e224] [cursor=pointer]
- generic [ref=f3e225]:
- generic [ref=f3e226]:
- generic [ref=f3e227]:
- link "St Peter's Catholic School" [ref=f3e228] [cursor=pointer]:
- /url: /school/148094-st-peters-catholic-school
- generic [ref=f3e229]: Inspected · 2025
- generic [ref=f3e230]:
- generic [ref=f3e231]: Secondary
- generic [ref=f3e232]: Academy converter
- generic [ref=f3e233]: Ages 1118
- generic [ref=f3e234]: Sixth form
- generic [ref=f3e235]: Selective
- generic [ref=f3e236]:
- generic [ref=f3e237]:
- strong [ref=f3e238]: "53.4"
- generic [ref=f3e239]: Attainment 8
- generic [ref=f3e240]: +9.1 vs LA avg
- generic [ref=f3e241]:
- strong [ref=f3e242]: "204"
- generic [ref=f3e243]: pupils
- generic [ref=f3e245]: Solihull
- generic [ref=f3e246]:
- link "View" [ref=f3e247] [cursor=pointer]:
- /url: /school/148094-st-peters-catholic-school
- button "+ Compare" [ref=f3e248] [cursor=pointer]
- generic [ref=f3e249]:
- generic [ref=f3e250]:
- generic [ref=f3e251]:
- link "Widney Junior School" [ref=f3e252] [cursor=pointer]:
- /url: /school/104054-widney-junior-school
- generic [ref=f3e253]: Good · 2024
- generic [ref=f3e254]:
- generic [ref=f3e255]: Primary
- generic [ref=f3e256]: Community school
- generic [ref=f3e257]: Ages 711
- generic [ref=f3e258]:
- generic [ref=f3e259]:
- strong [ref=f3e260]: 80%
- 'generic "Previous year: 78.0%" [ref=f3e261]':
- img "Trend up" [ref=f3e262]
- generic [ref=f3e264]: Reading, Writing & Maths
- generic [ref=f3e265]: +18 pts vs national
- generic [ref=f3e266]:
- strong [ref=f3e267]: "327"
- generic [ref=f3e268]: pupils
- generic [ref=f3e270]: Solihull
- generic [ref=f3e271]:
- link "View" [ref=f3e272] [cursor=pointer]:
- /url: /school/104054-widney-junior-school
- button "+ Compare" [ref=f3e273] [cursor=pointer]
- generic [ref=f3e274]:
- generic [ref=f3e275]:
- generic [ref=f3e276]:
- link "St Alphege Church of England Junior School" [ref=f3e277] [cursor=pointer]:
- /url: /school/104092-st-alphege-church-of-england-junior-school
- generic [ref=f3e278]: Inspected · 2025
- generic [ref=f3e279]:
- generic [ref=f3e280]: Primary
- generic [ref=f3e281]: Voluntary aided school
- generic [ref=f3e282]: Ages 711
- generic [ref=f3e283]: Church of England
- generic [ref=f3e284]:
- generic [ref=f3e285]:
- strong [ref=f3e286]: 86%
- 'generic "Previous year: 84.0%" [ref=f3e287]':
- img "Trend up" [ref=f3e288]
- generic [ref=f3e290]: Reading, Writing & Maths
- generic [ref=f3e291]: +24 pts vs national
- generic [ref=f3e292]:
- strong [ref=f3e293]: "257"
- generic [ref=f3e294]: pupils
- generic [ref=f3e296]: Solihull
- generic [ref=f3e297]:
- link "View" [ref=f3e298] [cursor=pointer]:
- /url: /school/104092-st-alphege-church-of-england-junior-school
- button "+ Compare" [ref=f3e299] [cursor=pointer]
- generic [ref=f3e300]:
- generic [ref=f3e301]:
- generic [ref=f3e302]:
- link "St Augustine's Catholic Primary School" [ref=f3e303] [cursor=pointer]:
- /url: /school/148087-st-augustines-catholic-primary-school
- generic [ref=f3e304]: Good · 2023
- generic [ref=f3e305]:
- generic [ref=f3e306]: Primary
- generic [ref=f3e307]: Academy converter
- generic [ref=f3e308]: Ages 311
- generic [ref=f3e309]: Roman Catholic
- generic [ref=f3e310]:
- generic [ref=f3e311]:
- strong [ref=f3e312]: 84%
- 'generic "Previous year: 79.0%" [ref=f3e313]':
- img "Trend up" [ref=f3e314]
- generic [ref=f3e316]: Reading, Writing & Maths
- generic [ref=f3e317]: +22 pts vs national
- generic [ref=f3e318]:
- strong [ref=f3e319]: "231"
- generic [ref=f3e320]: pupils
- generic [ref=f3e322]: Solihull
- generic [ref=f3e323]:
- link "View" [ref=f3e324] [cursor=pointer]:
- /url: /school/148087-st-augustines-catholic-primary-school
- button "+ Compare" [ref=f3e325] [cursor=pointer]
- generic [ref=f3e326]:
- generic [ref=f3e327]:
- generic [ref=f3e328]:
- link "St Alphege Church of England Infant and Nursery School" [ref=f3e329] [cursor=pointer]:
- /url: /school/104090-st-alphege-church-of-england-infant-and-nursery-school
- generic [ref=f3e330]: Inspected · 2025
- generic [ref=f3e331]:
- generic [ref=f3e332]: Primary
- generic [ref=f3e333]: Voluntary aided school
- generic [ref=f3e334]: Ages 37
- generic [ref=f3e335]: Church of England
- generic [ref=f3e337]:
- strong [ref=f3e338]:
- generic [ref=f3e339]: Reading, Writing & Maths
- generic [ref=f3e341]: Solihull
- generic [ref=f3e342]:
- link "View" [ref=f3e343] [cursor=pointer]:
- /url: /school/104090-st-alphege-church-of-england-infant-and-nursery-school
- button "+ Compare" [ref=f3e344] [cursor=pointer]
- generic [ref=f3e345]:
- generic [ref=f3e346]:
- generic [ref=f3e347]:
- link "Solihull Sixth Form College" [ref=f3e348] [cursor=pointer]:
- /url: /school/144887-solihull-sixth-form-college
- generic [ref=f3e349]: Not yet inspected
- generic [ref=f3e350]:
- generic [ref=f3e351]: Post-16
- generic [ref=f3e352]: Academy 16-19 converter
- generic [ref=f3e353]: Ages 1619
- generic [ref=f3e355]:
- strong [ref=f3e356]:
- generic [ref=f3e357]: Reading, Writing & Maths
- generic [ref=f3e359]: Solihull
- generic [ref=f3e360]:
- link "View" [ref=f3e361] [cursor=pointer]:
- /url: /school/144887-solihull-sixth-form-college
- button "+ Compare" [ref=f3e362] [cursor=pointer]
- contentinfo [ref=f3e136]:
- generic [ref=f3e137]:
- generic [ref=f3e138]:
- generic [ref=f3e139]:
- heading "SchoolCompare" [level=3] [ref=f3e140]
- paragraph [ref=f3e141]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f3e142] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f3e143]:
- heading "Product" [level=4] [ref=f3e144]
- list [ref=f3e145]:
- listitem [ref=f3e146]:
- link "Search schools" [ref=f3e147] [cursor=pointer]:
- /url: /
- listitem [ref=f3e148]:
- link "Rankings" [ref=f3e149] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f3e150]:
- link "Compare shortlist" [ref=f3e151] [cursor=pointer]:
- /url: /compare
- listitem [ref=f3e152]:
- link "Admissions guide" [ref=f3e153] [cursor=pointer]:
- /url: /admissions
- generic [ref=f3e154]:
- heading "Resources" [level=4] [ref=f3e155]
- list [ref=f3e156]:
- listitem [ref=f3e157]:
- link "School Performance Tables" [ref=f3e158] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f3e159]:
- link "Ofsted reports" [ref=f3e160] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f3e162]: © 2026 SchoolCompare.co.uk
- alert [ref=f3e163]
@@ -0,0 +1,229 @@
- generic [active] [ref=f4e1]:
- link "Skip to main content" [ref=f4e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f4e3]:
- generic [ref=f4e4]:
- link "SchoolCompare home" [ref=f4e5] [cursor=pointer]:
- /url: /
- img [ref=f4e7]
- generic [ref=f4e11]: SchoolCompare
- navigation "Main navigation" [ref=f4e12]:
- link "Search" [ref=f4e13] [cursor=pointer]:
- /url: /
- link "Compare" [ref=f4e14] [cursor=pointer]:
- /url: /compare
- link "Rankings" [ref=f4e15] [cursor=pointer]:
- /url: /rankings
- link "Admissions" [ref=f4e16] [cursor=pointer]:
- /url: /admissions
- main [ref=f4e17]:
- generic [ref=f4e18]:
- generic [ref=f4e19]:
- generic [ref=f4e20]: Updated with 2026/2027 admissions results
- heading "Every school in England, compared." [level=1] [ref=f4e22]:
- text: Every school in England,
- emphasis [ref=f4e23]: compared.
- paragraph [ref=f4e24]:
- strong [ref=f4e25]: 24,000+ primary and secondary schools
- text: with Key Stage 2 SATs, GCSE results, Ofsted grades, progress scores and admissions data — side by side, in one place.
- generic [ref=f4e28]:
- searchbox "School name or postcode" [ref=f4e29]
- button "Search" [ref=f4e30] [cursor=pointer]
- button "Schools near me" [ref=f4e33] [cursor=pointer]:
- img [ref=f4e34]
- text: Schools near me
- generic [ref=f4e37]:
- generic [ref=f4e38]:
- generic [ref=f4e39]: Key admissions deadlines
- link "Full admissions guide →" [ref=f4e40] [cursor=pointer]:
- /url: /admissions
- generic [ref=f4e41]:
- generic [ref=f4e42]:
- generic [ref=f4e43]: Secondary · Deadline
- generic [ref=f4e45]: 121days
- generic [ref=f4e46]: Secondary applications close
- generic [ref=f4e47]: Sat, 31 October 2026
- generic [ref=f4e48]:
- generic [ref=f4e49]: Primary · Deadline
- generic [ref=f4e51]: 197days
- generic [ref=f4e52]: Primary applications close
- generic [ref=f4e53]: Fri, 15 January 2027
- generic [ref=f4e54]:
- generic [ref=f4e55]: Secondary · Offer Day
- generic [ref=f4e57]: 242days
- generic [ref=f4e58]: Secondary National Offer Day
- generic [ref=f4e59]: Mon, 1 March 2027
- generic [ref=f4e60]:
- generic [ref=f4e61]: Primary · Offer Day
- generic [ref=f4e63]: 288days
- generic [ref=f4e64]: Primary National Offer Day
- generic [ref=f4e65]: Fri, 16 April 2027
- generic [ref=f4e66]:
- generic [ref=f4e67]: Start exploring
- generic [ref=f4e68]:
- link "Top-rated primary schools" [ref=f4e69] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f4e71] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f4e73] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f4e75]:
- generic [ref=f4e76]:
- heading "What you'll see on every school" [level=2] [ref=f4e77]
- generic [ref=f4e78]: Primary or secondary — the page adapts to the phase
- generic [ref=f4e79]:
- generic [ref=f4e80]:
- generic [ref=f4e81]:
- generic [ref=f4e82]:
- generic [ref=f4e83]:
- text: Primary · Year 6 ·
- strong [ref=f4e84]: Key Stage 2 SATs
- generic [ref=f4e85]:
- generic [ref=f4e86]:
- generic [ref=f4e87]: Reading
- generic [ref=f4e88]:
- generic [ref=f4e89]: Expected
- strong [ref=f4e90]: 96%
- generic [ref=f4e91]:
- generic: 75%
- generic [ref=f4e93]:
- generic [ref=f4e94]: Exceeding
- strong [ref=f4e95]: 73%
- generic [ref=f4e98]:
- generic [ref=f4e99]: Writing
- generic [ref=f4e100]:
- generic [ref=f4e101]: Expected
- strong [ref=f4e102]: 81%
- generic [ref=f4e103]:
- generic: 72%
- generic [ref=f4e105]:
- generic [ref=f4e106]: Exceeding
- strong [ref=f4e107]: 15%
- generic [ref=f4e110]:
- generic [ref=f4e111]: Maths
- generic [ref=f4e112]:
- generic [ref=f4e113]: Expected
- strong [ref=f4e114]: 85%
- generic [ref=f4e115]:
- generic: 74%
- generic [ref=f4e117]:
- generic [ref=f4e118]: Exceeding
- strong [ref=f4e119]: 47%
- generic [ref=f4e122]:
- generic [ref=f4e123]:
- text: Secondary · Year 11 ·
- strong [ref=f4e124]: GCSE Attainment 8
- generic [ref=f4e125]:
- generic [ref=f4e127]:
- generic [ref=f4e128]: This school
- generic [ref=f4e129]: National avg 50.2
- generic [ref=f4e133]:
- generic [ref=f4e134]: "62.4"
- generic [ref=f4e135]: +12.2 vs national
- generic [ref=f4e136]:
- generic [ref=f4e137]: Performance
- generic [ref=f4e138]: Results against the national average
- paragraph [ref=f4e139]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f4e140]:
- generic [ref=f4e142]:
- generic [ref=f4e145]: Latest Ofsted inspection
- generic [ref=f4e146]: OUTSTANDING
- generic [ref=f4e147]:
- text: Rated
- emphasis [ref=f4e148]: Outstanding
- text: at last inspection.
- generic [ref=f4e149]: Full inspection · March 2024
- generic [ref=f4e150]:
- generic [ref=f4e151]: Judgement
- generic [ref=f4e152]: Ofsted at a glance
- paragraph [ref=f4e153]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f4e154]:
- generic [ref=f4e156]:
- generic [ref=f4e157]:
- generic [ref=f4e158]: Metric
- generic [ref=f4e159]:
- text: Our Lady
- text: Queen of Heaven
- generic [ref=f4e160]:
- text: St Mary's
- text: Catholic Primary
- generic [ref=f4e161]:
- generic [ref=f4e162]: Reading, Writing & Maths
- generic [ref=f4e163]: 70%
- generic [ref=f4e164]: 64%
- generic [ref=f4e165]:
- generic [ref=f4e166]: Ofsted
- generic [ref=f4e167]: Outstanding
- generic [ref=f4e168]: Good
- generic [ref=f4e169]:
- generic [ref=f4e170]: Reading progress
- generic [ref=f4e171]: "+2.1"
- generic [ref=f4e172]: "+0.4"
- generic [ref=f4e173]: + pin up to 5 schools
- generic [ref=f4e174]:
- generic [ref=f4e175]: Compare
- generic [ref=f4e176]: Side-by-side shortlists
- paragraph [ref=f4e177]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f4e179]:
- generic [ref=f4e180]:
- generic [ref=f4e181]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f4e182]
- paragraph [ref=f4e183]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f4e184]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f4e185]:
- heading "Coverage at a glance" [level=3] [ref=f4e186]
- generic [ref=f4e187]:
- generic [ref=f4e188]: Schools covered
- generic [ref=f4e189]: 24,000+
- generic [ref=f4e190]:
- generic [ref=f4e191]: Local authorities
- generic [ref=f4e192]: "182"
- generic [ref=f4e193]:
- generic [ref=f4e194]: Phases
- generic [ref=f4e195]: Primary & Secondary
- generic [ref=f4e196]:
- generic [ref=f4e197]: Latest results year
- generic [ref=f4e198]: 2024/25
- generic [ref=f4e199]:
- generic [ref=f4e200]: Historical data
- generic [ref=f4e201]: 20162025
- generic [ref=f4e202]:
- generic [ref=f4e203]: Metrics per school
- generic [ref=f4e204]: 40+
- contentinfo [ref=f4e205]:
- generic [ref=f4e206]:
- generic [ref=f4e207]:
- generic [ref=f4e208]:
- heading "SchoolCompare" [level=3] [ref=f4e209]
- paragraph [ref=f4e210]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f4e211] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f4e212]:
- heading "Product" [level=4] [ref=f4e213]
- list [ref=f4e214]:
- listitem [ref=f4e215]:
- link "Search schools" [ref=f4e216] [cursor=pointer]:
- /url: /
- listitem [ref=f4e217]:
- link "Rankings" [ref=f4e218] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f4e219]:
- link "Compare shortlist" [ref=f4e220] [cursor=pointer]:
- /url: /compare
- listitem [ref=f4e221]:
- link "Admissions guide" [ref=f4e222] [cursor=pointer]:
- /url: /admissions
- generic [ref=f4e223]:
- heading "Resources" [level=4] [ref=f4e224]
- list [ref=f4e225]:
- listitem [ref=f4e226]:
- link "School Performance Tables" [ref=f4e227] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f4e228]:
- link "Ofsted reports" [ref=f4e229] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f4e231]: © 2026 SchoolCompare.co.uk
- alert [ref=f4e232]
@@ -0,0 +1,101 @@
- generic [ref=f4e1]:
- link "Skip to main content" [ref=f4e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f4e3]:
- generic [ref=f4e4]:
- link "SchoolCompare home" [ref=f4e5] [cursor=pointer]:
- /url: /
- img [ref=f4e7]
- generic [ref=f4e11]: SchoolCompare
- navigation "Main navigation" [ref=f4e12]:
- link "Search" [ref=f4e13] [cursor=pointer]:
- /url: /
- link "Compare" [ref=f4e14] [cursor=pointer]:
- /url: /compare
- link "Rankings" [ref=f4e15] [cursor=pointer]:
- /url: /rankings
- link "Admissions" [ref=f4e16] [cursor=pointer]:
- /url: /admissions
- main [ref=f4e17]:
- generic [ref=f4e18]:
- generic [ref=f4e26]:
- generic [ref=f4e28]:
- searchbox "School name or postcode" [active] [ref=f4e29]: Welland Primary
- button "Search" [ref=f4e30] [cursor=pointer]
- generic [ref=f4e233]:
- combobox [ref=f4e234] [cursor=pointer]:
- option "All Phases" [selected]
- option "Primary"
- button "Advanced" [ref=f4e235] [cursor=pointer]: Advanced
- button "Clear" [ref=f4e237] [cursor=pointer]
- generic [ref=f4e238]:
- generic [ref=f4e239]:
- heading "1 school found" [level=2] [ref=f4e240]
- combobox [ref=f4e242] [cursor=pointer]:
- 'option "Sort: Relevance" [selected]'
- option "Highest Reading, Writing & Maths %"
- option "Lowest Reading, Writing & Maths %"
- option "Name AZ"
- generic [ref=f4e244]:
- text: "Search: Welland Primary"
- link "×" [ref=f4e245] [cursor=pointer]:
- /url: /
- generic [ref=f4e247]:
- generic [ref=f4e248]:
- generic [ref=f4e249]:
- link "Welland Primary School" [ref=f4e250] [cursor=pointer]:
- /url: /school/146678-welland-primary-school
- generic [ref=f4e251]: Good · 2023
- generic [ref=f4e252]:
- generic [ref=f4e253]: Primary
- generic [ref=f4e254]: Academy converter
- generic [ref=f4e255]: Ages 411
- generic [ref=f4e256]:
- generic [ref=f4e257]:
- strong [ref=f4e258]: 74%
- 'generic "Previous year: 76.0%" [ref=f4e259]':
- img "Trend down" [ref=f4e260]
- generic [ref=f4e262]: Reading, Writing & Maths
- generic [ref=f4e263]: +12 pts vs national
- generic [ref=f4e264]:
- strong [ref=f4e265]: "131"
- generic [ref=f4e266]: pupils
- generic [ref=f4e268]: Worcestershire
- generic [ref=f4e269]:
- link "View" [ref=f4e270] [cursor=pointer]:
- /url: /school/146678-welland-primary-school
- button "+ Compare" [ref=f4e271] [cursor=pointer]
- contentinfo [ref=f4e205]:
- generic [ref=f4e206]:
- generic [ref=f4e207]:
- generic [ref=f4e208]:
- heading "SchoolCompare" [level=3] [ref=f4e209]
- paragraph [ref=f4e210]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f4e211] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f4e212]:
- heading "Product" [level=4] [ref=f4e213]
- list [ref=f4e214]:
- listitem [ref=f4e215]:
- link "Search schools" [ref=f4e216] [cursor=pointer]:
- /url: /
- listitem [ref=f4e217]:
- link "Rankings" [ref=f4e218] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f4e219]:
- link "Compare shortlist" [ref=f4e220] [cursor=pointer]:
- /url: /compare
- listitem [ref=f4e221]:
- link "Admissions guide" [ref=f4e222] [cursor=pointer]:
- /url: /admissions
- generic [ref=f4e223]:
- heading "Resources" [level=4] [ref=f4e224]
- list [ref=f4e225]:
- listitem [ref=f4e226]:
- link "School Performance Tables" [ref=f4e227] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f4e228]:
- link "Ofsted reports" [ref=f4e229] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f4e231]: © 2026 SchoolCompare.co.uk
- alert [ref=f4e232]
@@ -0,0 +1,229 @@
- generic [active] [ref=f5e1]:
- link "Skip to main content" [ref=f5e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f5e3]:
- generic [ref=f5e4]:
- link "SchoolCompare home" [ref=f5e5] [cursor=pointer]:
- /url: /
- img [ref=f5e7]
- generic [ref=f5e11]: SchoolCompare
- navigation "Main navigation" [ref=f5e12]:
- link "Search" [ref=f5e13] [cursor=pointer]:
- /url: /
- link "Compare" [ref=f5e14] [cursor=pointer]:
- /url: /compare
- link "Rankings" [ref=f5e15] [cursor=pointer]:
- /url: /rankings
- link "Admissions" [ref=f5e16] [cursor=pointer]:
- /url: /admissions
- main [ref=f5e17]:
- generic [ref=f5e18]:
- generic [ref=f5e19]:
- generic [ref=f5e20]: Updated with 2026/2027 admissions results
- heading "Every school in England, compared." [level=1] [ref=f5e22]:
- text: Every school in England,
- emphasis [ref=f5e23]: compared.
- paragraph [ref=f5e24]:
- strong [ref=f5e25]: 24,000+ primary and secondary schools
- text: with Key Stage 2 SATs, GCSE results, Ofsted grades, progress scores and admissions data — side by side, in one place.
- generic [ref=f5e28]:
- searchbox "School name or postcode" [ref=f5e29]
- button "Search" [ref=f5e30] [cursor=pointer]
- button "Schools near me" [ref=f5e33] [cursor=pointer]:
- img [ref=f5e34]
- text: Schools near me
- generic [ref=f5e37]:
- generic [ref=f5e38]:
- generic [ref=f5e39]: Key admissions deadlines
- link "Full admissions guide →" [ref=f5e40] [cursor=pointer]:
- /url: /admissions
- generic [ref=f5e41]:
- generic [ref=f5e42]:
- generic [ref=f5e43]: Secondary · Deadline
- generic [ref=f5e45]: 121days
- generic [ref=f5e46]: Secondary applications close
- generic [ref=f5e47]: Sat, 31 October 2026
- generic [ref=f5e48]:
- generic [ref=f5e49]: Primary · Deadline
- generic [ref=f5e51]: 197days
- generic [ref=f5e52]: Primary applications close
- generic [ref=f5e53]: Fri, 15 January 2027
- generic [ref=f5e54]:
- generic [ref=f5e55]: Secondary · Offer Day
- generic [ref=f5e57]: 242days
- generic [ref=f5e58]: Secondary National Offer Day
- generic [ref=f5e59]: Mon, 1 March 2027
- generic [ref=f5e60]:
- generic [ref=f5e61]: Primary · Offer Day
- generic [ref=f5e63]: 288days
- generic [ref=f5e64]: Primary National Offer Day
- generic [ref=f5e65]: Fri, 16 April 2027
- generic [ref=f5e66]:
- generic [ref=f5e67]: Start exploring
- generic [ref=f5e68]:
- link "Top-rated primary schools" [ref=f5e69] [cursor=pointer]:
- /url: /rankings
- text: Top-rated primary schools
- link "Top-rated secondary schools" [ref=f5e71] [cursor=pointer]:
- /url: /rankings
- text: Top-rated secondary schools
- link "Start a comparison" [ref=f5e73] [cursor=pointer]:
- /url: /compare
- text: Start a comparison
- generic [ref=f5e75]:
- generic [ref=f5e76]:
- heading "What you'll see on every school" [level=2] [ref=f5e77]
- generic [ref=f5e78]: Primary or secondary — the page adapts to the phase
- generic [ref=f5e79]:
- generic [ref=f5e80]:
- generic [ref=f5e81]:
- generic [ref=f5e82]:
- generic [ref=f5e83]:
- text: Primary · Year 6 ·
- strong [ref=f5e84]: Key Stage 2 SATs
- generic [ref=f5e85]:
- generic [ref=f5e86]:
- generic [ref=f5e87]: Reading
- generic [ref=f5e88]:
- generic [ref=f5e89]: Expected
- strong [ref=f5e90]: 96%
- generic [ref=f5e91]:
- generic: 75%
- generic [ref=f5e93]:
- generic [ref=f5e94]: Exceeding
- strong [ref=f5e95]: 73%
- generic [ref=f5e98]:
- generic [ref=f5e99]: Writing
- generic [ref=f5e100]:
- generic [ref=f5e101]: Expected
- strong [ref=f5e102]: 81%
- generic [ref=f5e103]:
- generic: 72%
- generic [ref=f5e105]:
- generic [ref=f5e106]: Exceeding
- strong [ref=f5e107]: 15%
- generic [ref=f5e110]:
- generic [ref=f5e111]: Maths
- generic [ref=f5e112]:
- generic [ref=f5e113]: Expected
- strong [ref=f5e114]: 85%
- generic [ref=f5e115]:
- generic: 74%
- generic [ref=f5e117]:
- generic [ref=f5e118]: Exceeding
- strong [ref=f5e119]: 47%
- generic [ref=f5e122]:
- generic [ref=f5e123]:
- text: Secondary · Year 11 ·
- strong [ref=f5e124]: GCSE Attainment 8
- generic [ref=f5e125]:
- generic [ref=f5e127]:
- generic [ref=f5e128]: This school
- generic [ref=f5e129]: National avg 50.2
- generic [ref=f5e133]:
- generic [ref=f5e134]: "62.4"
- generic [ref=f5e135]: +12.2 vs national
- generic [ref=f5e136]:
- generic [ref=f5e137]: Performance
- generic [ref=f5e138]: Results against the national average
- paragraph [ref=f5e139]: For primary schools, each subject's Expected and Exceeding percentages side by side. For secondary schools, GCSE Attainment 8 with the national benchmark overlaid.
- generic [ref=f5e140]:
- generic [ref=f5e142]:
- generic [ref=f5e145]: Latest Ofsted inspection
- generic [ref=f5e146]: OUTSTANDING
- generic [ref=f5e147]:
- text: Rated
- emphasis [ref=f5e148]: Outstanding
- text: at last inspection.
- generic [ref=f5e149]: Full inspection · March 2024
- generic [ref=f5e150]:
- generic [ref=f5e151]: Judgement
- generic [ref=f5e152]: Ofsted at a glance
- paragraph [ref=f5e153]: Current grade, inspection date, and a plain-English headline — without opening a 40-page report.
- generic [ref=f5e154]:
- generic [ref=f5e156]:
- generic [ref=f5e157]:
- generic [ref=f5e158]: Metric
- generic [ref=f5e159]:
- text: Our Lady
- text: Queen of Heaven
- generic [ref=f5e160]:
- text: St Mary's
- text: Catholic Primary
- generic [ref=f5e161]:
- generic [ref=f5e162]: Reading, Writing & Maths
- generic [ref=f5e163]: 70%
- generic [ref=f5e164]: 64%
- generic [ref=f5e165]:
- generic [ref=f5e166]: Ofsted
- generic [ref=f5e167]: Outstanding
- generic [ref=f5e168]: Good
- generic [ref=f5e169]:
- generic [ref=f5e170]: Reading progress
- generic [ref=f5e171]: "+2.1"
- generic [ref=f5e172]: "+0.4"
- generic [ref=f5e173]: + pin up to 5 schools
- generic [ref=f5e174]:
- generic [ref=f5e175]: Compare
- generic [ref=f5e176]: Side-by-side shortlists
- paragraph [ref=f5e177]: Pin up to five schools and every metric aligns in the same columns — works for primary and secondary alike.
- generic [ref=f5e179]:
- generic [ref=f5e180]:
- generic [ref=f5e181]: About school data
- heading "Making UK school performance data actually readable" [level=2] [ref=f5e182]
- paragraph [ref=f5e183]: School performance data in England is rich but fragmented. The Department for Education publishes Key Stage 2 SATs, GCSE attainment, Ofsted outcomes, progress scores, admissions figures and demographics — each in its own table, each with its own jargon.
- paragraph [ref=f5e184]: SchoolCompare brings it all into one place. Every school page shows performance against the national average, explains what the numbers mean, and lets you shortlist schools side by side. Built for parents, governors, journalists, and anyone who wants to understand a school without reading a 40-page inspection report.
- generic [ref=f5e185]:
- heading "Coverage at a glance" [level=3] [ref=f5e186]
- generic [ref=f5e187]:
- generic [ref=f5e188]: Schools covered
- generic [ref=f5e189]: 24,000+
- generic [ref=f5e190]:
- generic [ref=f5e191]: Local authorities
- generic [ref=f5e192]: "182"
- generic [ref=f5e193]:
- generic [ref=f5e194]: Phases
- generic [ref=f5e195]: Primary & Secondary
- generic [ref=f5e196]:
- generic [ref=f5e197]: Latest results year
- generic [ref=f5e198]: 2024/25
- generic [ref=f5e199]:
- generic [ref=f5e200]: Historical data
- generic [ref=f5e201]: 20162025
- generic [ref=f5e202]:
- generic [ref=f5e203]: Metrics per school
- generic [ref=f5e204]: 40+
- contentinfo [ref=f5e205]:
- generic [ref=f5e206]:
- generic [ref=f5e207]:
- generic [ref=f5e208]:
- heading "SchoolCompare" [level=3] [ref=f5e209]
- paragraph [ref=f5e210]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f5e211] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f5e212]:
- heading "Product" [level=4] [ref=f5e213]
- list [ref=f5e214]:
- listitem [ref=f5e215]:
- link "Search schools" [ref=f5e216] [cursor=pointer]:
- /url: /
- listitem [ref=f5e217]:
- link "Rankings" [ref=f5e218] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f5e219]:
- link "Compare shortlist" [ref=f5e220] [cursor=pointer]:
- /url: /compare
- listitem [ref=f5e221]:
- link "Admissions guide" [ref=f5e222] [cursor=pointer]:
- /url: /admissions
- generic [ref=f5e223]:
- heading "Resources" [level=4] [ref=f5e224]
- list [ref=f5e225]:
- listitem [ref=f5e226]:
- link "School Performance Tables" [ref=f5e227] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f5e228]:
- link "Ofsted reports" [ref=f5e229] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f5e231]: © 2026 SchoolCompare.co.uk
- alert [ref=f5e232]
@@ -0,0 +1,214 @@
- generic [active] [ref=f6e1]:
- link "Skip to main content" [ref=f6e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f6e3]:
- link "SchoolCompare home" [ref=f6e5] [cursor=pointer]:
- /url: /
- img [ref=f6e7]
- generic [ref=f6e11]: SchoolCompare
- navigation "Main navigation" [ref=f6e12]:
- link "Search" [ref=f6e13] [cursor=pointer]:
- /url: /
- img [ref=f6e15]
- generic [ref=f6e18]: Search
- link "Compare" [ref=f6e19] [cursor=pointer]:
- /url: /compare
- img [ref=f6e21]
- generic [ref=f6e24]: Compare
- link "Rankings" [ref=f6e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f6e27]
- generic [ref=f6e28]: Rankings
- link "Admissions" [ref=f6e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f6e31]
- generic [ref=f6e34]: Admissions
- main [ref=f6e35]:
- generic [ref=f6e36]:
- button "Back" [ref=f6e37] [cursor=pointer]:
- generic [ref=f6e38]:
- text: Back
- generic [ref=f6e39]:
- generic [ref=f6e40]:
- generic [ref=f6e41]:
- img [ref=f6e45] [cursor=pointer]
- generic [ref=f6e48]:
- link "Leaflet" [ref=f6e49] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f6e50]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f6e54] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f6e55] [cursor=pointer]:
- generic [ref=f6e56]:
- img [ref=f6e57]
- text: Open full map
- generic [ref=f6e59]:
- generic [ref=f6e60]:
- heading "The Castle School" [level=1] [ref=f6e61]
- generic [ref=f6e62]:
- generic [ref=f6e63]: Academy converter
- generic [ref=f6e64]: Ages 1119
- paragraph [ref=f6e65]:
- text: Wellington Road, Taunton, TA1 5AU ·
- button "View on map ↗" [ref=f6e66] [cursor=pointer]
- generic [ref=f6e67]:
- generic [ref=f6e68]:
- strong [ref=f6e69]: "Headteacher:"
- text: Mr James Lamb
- link "School website ↗" [ref=f6e71] [cursor=pointer]:
- /url: http://www.castleschool.co.uk/
- generic [ref=f6e72]:
- strong [ref=f6e73]: "Pupils:"
- text: "1,202 (capacity: 1188)"
- generic [ref=f6e74]:
- text: Part of
- strong [ref=f6e75]: BLACKDOWN EDUCATION PARTNERSHIP
- button "+ Add to Compare" [ref=f6e77] [cursor=pointer]
- navigation "Page sections" [ref=f6e78]:
- generic [ref=f6e79]:
- button "Back to top" [ref=f6e80] [cursor=pointer]: ↑ Top
- link "Ofsted" [ref=f6e82] [cursor=pointer]:
- /url: "#ofsted"
- link "GCSEs" [ref=f6e83] [cursor=pointer]:
- /url: "#gcse"
- link "Admissions" [ref=f6e84] [cursor=pointer]:
- /url: "#admissions"
- link "History" [ref=f6e85] [cursor=pointer]:
- /url: "#history"
- link "Wellbeing" [ref=f6e86] [cursor=pointer]:
- /url: "#wellbeing"
- generic [ref=f6e87]:
- heading "Ofsted Rating Inspected 3 October 2023 Ofsted reports ↗" [level=2] [ref=f6e88]:
- text: Ofsted Rating
- generic [ref=f6e89]: Inspected 3 October 2023
- link "Ofsted reports ↗" [ref=f6e90] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/136916
- generic [ref=f6e92]: Outstanding
- paragraph [ref=f6e93]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.
- paragraph [ref=f6e94]:
- text: Rated
- strong [ref=f6e95]: Outstanding
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f6e96]:
- heading "GCSE Results (2024/25)" [level=2] [ref=f6e97]
- paragraph [ref=f6e98]: GCSE results for Year 11 pupils. National averages shown for comparison.
- generic [ref=f6e99]: Progress 8 scores for 2024/25 are not used for accountability purposes following the KS2 assessment disruption. Treat with caution.
- generic [ref=f6e100]:
- generic [ref=f6e101]:
- generic [ref=f6e102]: Attainment 8 score
- generic [ref=f6e103]: "53.4"
- generic [ref=f6e104]:
- generic [ref=f6e105]: English & Maths Grade 5+
- generic [ref=f6e106]: 57.7%
- generic [ref=f6e107]:
- generic [ref=f6e108]: English & Maths Grade 4+
- generic [ref=f6e109]: 79.5%
- generic [ref=f6e110]:
- generic [ref=f6e111]: Attainment 8 — school vs national
- generic [ref=f6e114]:
- generic [ref=f6e115]: "0"
- generic [ref=f6e116]: "20"
- generic [ref=f6e117]: "40"
- generic [ref=f6e118]: "60"
- generic [ref=f6e119]: "80"
- heading "English Baccalaureate (EBacc)" [level=3] [ref=f6e120]
- generic [ref=f6e121]:
- generic [ref=f6e122]:
- generic [ref=f6e123]: Pupils entered for EBacc
- generic [ref=f6e124]: 30.1%
- generic [ref=f6e125]:
- generic [ref=f6e126]: EBacc Grade 4+
- generic [ref=f6e127]: 25.1%
- generic [ref=f6e128]:
- generic [ref=f6e129]: EBacc Grade 5+
- generic [ref=f6e130]: 20.5%
- generic [ref=f6e131]:
- generic [ref=f6e132]: EBacc average point score
- generic [ref=f6e133]: "4.72"
- generic [ref=f6e134]:
- heading "Admissions" [level=2] [ref=f6e135]
- generic [ref=f6e136]:
- generic [ref=f6e137]:
- generic [ref=f6e138]: Year 7 places offered
- generic [ref=f6e139]: "237"
- generic [ref=f6e140]:
- generic [ref=f6e141]: Total applications
- generic [ref=f6e142]: "707"
- generic [ref=f6e143]:
- generic [ref=f6e144]: 1st preference applications
- generic [ref=f6e145]: "336"
- generic [ref=f6e146]:
- generic [ref=f6e147]: Families who got their first choice
- generic [ref=f6e148]: 69.6%
- generic [ref=f6e149]: ⚠ Applications exceeded places last year
- paragraph [ref=f6e150]: Historical distance cut-off data is not available for this school. Contact the admissions authority for oversubscription criteria details.
- generic [ref=f6e151]:
- heading "Historical Results" [level=2] [ref=f6e152]
- heading "Results Over Time" [level=3] [ref=f6e153]
- generic [ref=f6e155]:
- generic [ref=f6e156]:
- generic [ref=f6e157]: GCSE results · Year 11
- tablist [ref=f6e158]:
- tab [selected] [ref=f6e159] [cursor=pointer]: Attainment 8
- tab [ref=f6e160] [cursor=pointer]: English & Maths grade 4+
- tab [ref=f6e161] [cursor=pointer]: Progress 8
- img [ref=f6e163]
- group [ref=f6e164]:
- generic "▶ View raw year-by-year data" [ref=f6e165] [cursor=pointer]
- generic [ref=f6e166]:
- heading "Wellbeing & Context" [level=2] [ref=f6e167]
- heading "Special Educational Needs (SEN)" [level=3] [ref=f6e168]
- generic [ref=f6e169]:
- generic [ref=f6e170]:
- generic [ref=f6e171]: SEN support
- generic [ref=f6e172]: 5.4%
- generic [ref=f6e173]: Without an EHCP
- generic [ref=f6e174]:
- generic [ref=f6e175]: Pupils with EHCP
- generic [ref=f6e176]: 3.8%
- generic [ref=f6e177]: Education, Health and Care Plan
- generic [ref=f6e178]:
- generic [ref=f6e179]: Total pupils
- generic [ref=f6e180]: 1,207
- 'img "Gender split: 52% girls, 48% boys" [ref=f6e181]'
- generic [ref=f6e184]:
- generic [ref=f6e185]: 52% girls
- text: ·
- generic [ref=f6e186]: 48% boys
- contentinfo [ref=f6e187]:
- generic [ref=f6e188]:
- generic [ref=f6e189]:
- generic [ref=f6e190]:
- heading "SchoolCompare" [level=3] [ref=f6e191]
- paragraph [ref=f6e192]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f6e193] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f6e194]:
- heading "Product" [level=4] [ref=f6e195]
- list [ref=f6e196]:
- listitem [ref=f6e197]:
- link "Search schools" [ref=f6e198] [cursor=pointer]:
- /url: /
- listitem [ref=f6e199]:
- link "Rankings" [ref=f6e200] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f6e201]:
- link "Compare shortlist" [ref=f6e202] [cursor=pointer]:
- /url: /compare
- listitem [ref=f6e203]:
- link "Admissions guide" [ref=f6e204] [cursor=pointer]:
- /url: /admissions
- generic [ref=f6e205]:
- heading "Resources" [level=4] [ref=f6e206]
- list [ref=f6e207]:
- listitem [ref=f6e208]:
- link "School Performance Tables" [ref=f6e209] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f6e210]:
- link "Ofsted reports" [ref=f6e211] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f6e213]: © 2026 SchoolCompare.co.uk
- alert [ref=f6e214]
@@ -0,0 +1,226 @@
- generic [ref=f6e1]:
- link "Skip to main content" [ref=f6e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f6e3]:
- link "SchoolCompare home" [ref=f6e5] [cursor=pointer]:
- /url: /
- img [ref=f6e7]
- generic [ref=f6e11]: SchoolCompare
- navigation "Main navigation" [ref=f6e12]:
- link "Search" [ref=f6e13] [cursor=pointer]:
- /url: /
- img [ref=f6e15]
- generic [ref=f6e18]: Search
- link "1 selected Compare" [ref=f6e227] [cursor=pointer]:
- /url: /compare
- generic [ref=f6e20]:
- img [ref=f6e21]
- generic "1 selected" [ref=f6e228]: "1"
- generic [ref=f6e24]: Compare
- link "Rankings" [ref=f6e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f6e27]
- generic [ref=f6e28]: Rankings
- link "Admissions" [ref=f6e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f6e31]
- generic [ref=f6e34]: Admissions
- main [ref=f6e35]:
- generic [ref=f6e36]:
- button "Back" [ref=f6e37] [cursor=pointer]:
- generic [ref=f6e38]:
- text: Back
- generic [ref=f6e39]:
- generic [ref=f6e40]:
- generic [ref=f6e41]:
- img [ref=f6e45] [cursor=pointer]
- generic [ref=f6e48]:
- link "Leaflet" [ref=f6e49] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f6e50]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f6e54] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f6e55] [cursor=pointer]:
- generic [ref=f6e56]:
- img [ref=f6e57]
- text: Open full map
- generic [ref=f6e59]:
- generic [ref=f6e60]:
- heading "The Castle School" [level=1] [ref=f6e61]
- generic [ref=f6e62]:
- generic [ref=f6e63]: Academy converter
- generic [ref=f6e64]: Ages 1119
- paragraph [ref=f6e65]:
- text: Wellington Road, Taunton, TA1 5AU ·
- button "View on map ↗" [ref=f6e66] [cursor=pointer]
- generic [ref=f6e67]:
- generic [ref=f6e68]:
- strong [ref=f6e69]: "Headteacher:"
- text: Mr James Lamb
- link "School website ↗" [ref=f6e71] [cursor=pointer]:
- /url: http://www.castleschool.co.uk/
- generic [ref=f6e72]:
- strong [ref=f6e73]: "Pupils:"
- text: "1,202 (capacity: 1188)"
- generic [ref=f6e74]:
- text: Part of
- strong [ref=f6e75]: BLACKDOWN EDUCATION PARTNERSHIP
- button "✓ In Comparison" [active] [ref=f6e229] [cursor=pointer]
- navigation "Page sections" [ref=f6e78]:
- generic [ref=f6e79]:
- button "Back to top" [ref=f6e80] [cursor=pointer]: ↑ Top
- link "Ofsted" [ref=f6e82] [cursor=pointer]:
- /url: "#ofsted"
- link "GCSEs" [ref=f6e83] [cursor=pointer]:
- /url: "#gcse"
- link "Admissions" [ref=f6e84] [cursor=pointer]:
- /url: "#admissions"
- link "History" [ref=f6e85] [cursor=pointer]:
- /url: "#history"
- link "Wellbeing" [ref=f6e86] [cursor=pointer]:
- /url: "#wellbeing"
- generic [ref=f6e87]:
- heading "Ofsted Rating Inspected 3 October 2023 Ofsted reports ↗" [level=2] [ref=f6e88]:
- text: Ofsted Rating
- generic [ref=f6e89]: Inspected 3 October 2023
- link "Ofsted reports ↗" [ref=f6e90] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/136916
- generic [ref=f6e92]: Outstanding
- paragraph [ref=f6e93]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.
- paragraph [ref=f6e94]:
- text: Rated
- strong [ref=f6e95]: Outstanding
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f6e96]:
- heading "GCSE Results (2024/25)" [level=2] [ref=f6e97]
- paragraph [ref=f6e98]: GCSE results for Year 11 pupils. National averages shown for comparison.
- generic [ref=f6e99]: Progress 8 scores for 2024/25 are not used for accountability purposes following the KS2 assessment disruption. Treat with caution.
- generic [ref=f6e100]:
- generic [ref=f6e101]:
- generic [ref=f6e102]: Attainment 8 score
- generic [ref=f6e103]:
- text: "53.4"
- generic [ref=f6e215]: +14 pts
- generic [ref=f6e216]: "National avg: 39.1"
- generic [ref=f6e104]:
- generic [ref=f6e105]: English & Maths Grade 5+
- generic [ref=f6e106]:
- text: 57.7%
- generic [ref=f6e217]: +22 pts
- generic [ref=f6e218]: "National avg: 36%"
- generic [ref=f6e107]:
- generic [ref=f6e108]: English & Maths Grade 4+
- generic [ref=f6e109]:
- text: 79.5%
- generic [ref=f6e219]: +28 pts
- generic [ref=f6e220]: "National avg: 51%"
- generic [ref=f6e110]:
- generic [ref=f6e111]: Attainment 8 — school vs national
- generic [ref=f6e222]: Nat avg 39.1
- generic [ref=f6e114]:
- generic [ref=f6e115]: "0"
- generic [ref=f6e116]: "20"
- generic [ref=f6e117]: "40"
- generic [ref=f6e118]: "60"
- generic [ref=f6e119]: "80"
- heading "English Baccalaureate (EBacc)" [level=3] [ref=f6e120]
- generic [ref=f6e121]:
- generic [ref=f6e122]:
- generic [ref=f6e123]: Pupils entered for EBacc
- generic [ref=f6e124]: 30.1%
- generic [ref=f6e125]:
- generic [ref=f6e126]: EBacc Grade 4+
- generic [ref=f6e127]: 25.1%
- generic [ref=f6e128]:
- generic [ref=f6e129]: EBacc Grade 5+
- generic [ref=f6e130]: 20.5%
- generic [ref=f6e131]:
- generic [ref=f6e132]: EBacc average point score
- generic [ref=f6e133]: "4.72"
- generic [ref=f6e134]:
- heading "Admissions" [level=2] [ref=f6e135]
- generic [ref=f6e136]:
- generic [ref=f6e137]:
- generic [ref=f6e138]: Year 7 places offered
- generic [ref=f6e139]: "237"
- generic [ref=f6e140]:
- generic [ref=f6e141]: Total applications
- generic [ref=f6e142]: "707"
- generic [ref=f6e143]:
- generic [ref=f6e144]: 1st preference applications
- generic [ref=f6e145]: "336"
- generic [ref=f6e146]:
- generic [ref=f6e147]: Families who got their first choice
- generic [ref=f6e148]: 69.6%
- generic [ref=f6e149]: ⚠ Applications exceeded places last year
- paragraph [ref=f6e150]: Historical distance cut-off data is not available for this school. Contact the admissions authority for oversubscription criteria details.
- generic [ref=f6e151]:
- heading "Historical Results" [level=2] [ref=f6e152]
- heading "Results Over Time" [level=3] [ref=f6e153]
- generic [ref=f6e155]:
- generic [ref=f6e156]:
- generic [ref=f6e157]: GCSE results · Year 11
- tablist "Select metric" [ref=f6e223]:
- tab "Attainment 8" [selected] [ref=f6e224] [cursor=pointer]
- tab "English & Maths grade 4+" [ref=f6e225] [cursor=pointer]
- tab "Progress 8" [ref=f6e226] [cursor=pointer]
- img [ref=f6e163]
- group [ref=f6e164]:
- generic "▶ View raw year-by-year data" [ref=f6e165] [cursor=pointer]
- generic [ref=f6e166]:
- heading "Wellbeing & Context" [level=2] [ref=f6e167]
- heading "Special Educational Needs (SEN)" [level=3] [ref=f6e168]
- generic [ref=f6e169]:
- generic [ref=f6e170]:
- generic [ref=f6e171]: SEN support
- generic [ref=f6e172]: 5.4%
- generic [ref=f6e173]: Without an EHCP
- generic [ref=f6e174]:
- generic [ref=f6e175]: Pupils with EHCP
- generic [ref=f6e176]: 3.8%
- generic [ref=f6e177]: Education, Health and Care Plan
- generic [ref=f6e178]:
- generic [ref=f6e179]: Total pupils
- generic [ref=f6e180]: 1,207
- 'img "Gender split: 52% girls, 48% boys" [ref=f6e181]'
- generic [ref=f6e184]:
- generic [ref=f6e185]: 52% girls
- text: ·
- generic [ref=f6e186]: 48% boys
- contentinfo [ref=f6e187]:
- generic [ref=f6e188]:
- generic [ref=f6e189]:
- generic [ref=f6e190]:
- heading "SchoolCompare" [level=3] [ref=f6e191]
- paragraph [ref=f6e192]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f6e193] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f6e194]:
- heading "Product" [level=4] [ref=f6e195]
- list [ref=f6e196]:
- listitem [ref=f6e197]:
- link "Search schools" [ref=f6e198] [cursor=pointer]:
- /url: /
- listitem [ref=f6e199]:
- link "Rankings" [ref=f6e200] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f6e201]:
- link "Compare shortlist" [ref=f6e202] [cursor=pointer]:
- /url: /compare
- listitem [ref=f6e203]:
- link "Admissions guide" [ref=f6e204] [cursor=pointer]:
- /url: /admissions
- generic [ref=f6e205]:
- heading "Resources" [level=4] [ref=f6e206]
- list [ref=f6e207]:
- listitem [ref=f6e208]:
- link "School Performance Tables" [ref=f6e209] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f6e210]:
- link "Ofsted reports" [ref=f6e211] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f6e213]: © 2026 SchoolCompare.co.uk
- alert [ref=f6e214]
@@ -0,0 +1,120 @@
- generic [active] [ref=f7e1]:
- link "Skip to main content" [ref=f7e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f7e3]:
- link "SchoolCompare home" [ref=f7e5] [cursor=pointer]:
- /url: /
- img [ref=f7e7]
- generic [ref=f7e11]: SchoolCompare
- navigation "Main navigation" [ref=f7e12]:
- link "Search" [ref=f7e13] [cursor=pointer]:
- /url: /
- img [ref=f7e15]
- generic [ref=f7e18]: Search
- link "1 selected Compare" [ref=f7e19] [cursor=pointer]:
- /url: /compare
- generic [ref=f7e20]:
- img [ref=f7e21]
- generic "1 selected" [ref=f7e24]: "1"
- generic [ref=f7e25]: Compare
- link "Rankings" [ref=f7e26] [cursor=pointer]:
- /url: /rankings
- img [ref=f7e28]
- generic [ref=f7e29]: Rankings
- link "Admissions" [ref=f7e30] [cursor=pointer]:
- /url: /admissions
- img [ref=f7e32]
- generic [ref=f7e35]: Admissions
- main [ref=f7e36]:
- generic [ref=f7e37]:
- generic [ref=f7e39]:
- generic [ref=f7e40]:
- heading "Compare Schools" [level=1] [ref=f7e41]
- paragraph [ref=f7e42]: Comparing 1 school
- generic [ref=f7e43]:
- button "+ Add School" [ref=f7e44] [cursor=pointer]
- button "Share" [ref=f7e45] [cursor=pointer]:
- img [ref=f7e46]
- text: Share
- generic [ref=f7e49]:
- button "Primary (1)" [ref=f7e50] [cursor=pointer]
- button "Secondary (0)" [ref=f7e51] [cursor=pointer]
- generic [ref=f7e52]:
- generic [ref=f7e53]: "Select Metric:"
- combobox "Select Metric:" [ref=f7e54] [cursor=pointer]:
- option "Reading, Writing & Maths Combined %" [selected]
- option "Reading Expected %"
- option "Writing Expected %"
- option "Maths Expected %"
- option "GPS Expected %"
- option "Science Expected %"
- option "Reading, Writing & Maths Combined Higher %"
- option "Reading Higher %"
- option "Writing Higher %"
- option "Maths Higher %"
- option "GPS Higher %"
- option "Reading Progress"
- option "Writing Progress"
- option "Maths Progress"
- option "Reading Average Score"
- option "Maths Average Score"
- option "GPS Average Score"
- option "Reading, Writing & Maths Expected % (Boys)"
- option "Reading, Writing & Maths Expected % (Girls)"
- option "Reading, Writing & Maths Higher % (Boys)"
- option "Reading, Writing & Maths Higher % (Girls)"
- option "Reading, Writing & Maths Expected % (Disadvantaged)"
- option "Reading, Writing & Maths Expected % (Non-Disadvantaged)"
- option "Disadvantaged Gap"
- option "% Disadvantaged Pupils"
- option "% EAL Pupils"
- option "% SEN Support"
- option "% Pupil Stability"
- option "Reading Test Absence %"
- option "GPS Test Absence %"
- option "Maths Test Absence %"
- option "Writing Absence %"
- option "Science Absence %"
- paragraph [ref=f7e55]: "% meeting expected standard in reading, writing and maths"
- generic [ref=f7e58]:
- button "Remove The Castle School" [ref=f7e59] [cursor=pointer]: ×
- heading "The Castle School" [level=2] [ref=f7e60]:
- link "The Castle School" [ref=f7e61] [cursor=pointer]:
- /url: /school/136916-the-castle-school
- generic [ref=f7e62]:
- generic [ref=f7e63]: Somerset
- generic [ref=f7e64]: Academy converter
- contentinfo [ref=f7e76]:
- generic [ref=f7e77]:
- generic [ref=f7e78]:
- generic [ref=f7e79]:
- heading "SchoolCompare" [level=3] [ref=f7e80]
- paragraph [ref=f7e81]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f7e82] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f7e83]:
- heading "Product" [level=4] [ref=f7e84]
- list [ref=f7e85]:
- listitem [ref=f7e86]:
- link "Search schools" [ref=f7e87] [cursor=pointer]:
- /url: /
- listitem [ref=f7e88]:
- link "Rankings" [ref=f7e89] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f7e90]:
- link "Compare shortlist" [ref=f7e91] [cursor=pointer]:
- /url: /compare
- listitem [ref=f7e92]:
- link "Admissions guide" [ref=f7e93] [cursor=pointer]:
- /url: /admissions
- generic [ref=f7e94]:
- heading "Resources" [level=4] [ref=f7e95]
- list [ref=f7e96]:
- listitem [ref=f7e97]:
- link "School Performance Tables" [ref=f7e98] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f7e99]:
- link "Ofsted reports" [ref=f7e100] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f7e102]: © 2026 SchoolCompare.co.uk
- alert [ref=f7e103]
@@ -0,0 +1,270 @@
- generic [active] [ref=f8e1]:
- link "Skip to main content" [ref=f8e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f8e3]:
- link "SchoolCompare home" [ref=f8e5] [cursor=pointer]:
- /url: /
- img [ref=f8e7]
- generic [ref=f8e11]: SchoolCompare
- navigation "Main navigation" [ref=f8e12]:
- link "Search" [ref=f8e13] [cursor=pointer]:
- /url: /
- img [ref=f8e15]
- generic [ref=f8e18]: Search
- link "1 selected Compare" [ref=f8e19] [cursor=pointer]:
- /url: /compare
- generic [ref=f8e20]:
- img [ref=f8e21]
- generic "1 selected" [ref=f8e24]: "1"
- generic [ref=f8e25]: Compare
- link "Rankings" [ref=f8e26] [cursor=pointer]:
- /url: /rankings
- img [ref=f8e28]
- generic [ref=f8e29]: Rankings
- link "Admissions" [ref=f8e30] [cursor=pointer]:
- /url: /admissions
- img [ref=f8e32]
- generic [ref=f8e35]: Admissions
- main [ref=f8e36]:
- generic [ref=f8e37]:
- button "Back" [ref=f8e38] [cursor=pointer]:
- generic [ref=f8e39]:
- text: Back
- generic [ref=f8e40]:
- generic [ref=f8e41]:
- generic [ref=f8e42]:
- img [ref=f8e46] [cursor=pointer]
- generic [ref=f8e49]:
- link "Leaflet" [ref=f8e50] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f8e51]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f8e55] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f8e56] [cursor=pointer]:
- generic [ref=f8e57]:
- img [ref=f8e58]
- text: Open full map
- generic [ref=f8e60]:
- generic [ref=f8e61]:
- heading "Welland Primary School" [level=1] [ref=f8e62]
- generic [ref=f8e63]:
- generic [ref=f8e64]: Worcestershire
- generic [ref=f8e65]: Academy converter
- paragraph [ref=f8e66]:
- text: Marlbank Road, Welland, Malvern, WR13 6NE ·
- button "View on map ↗" [ref=f8e67] [cursor=pointer]
- button "+ Add to Compare" [ref=f8e69] [cursor=pointer]
- navigation "Page sections" [ref=f8e70]:
- button "Back to top" [ref=f8e71] [cursor=pointer]:
- generic [ref=f8e72]:
- button "Section Ofsted" [ref=f8e73] [cursor=pointer]:
- generic [ref=f8e74]:
- generic [ref=f8e75]: Section
- generic [ref=f8e76]: Ofsted
- generic [ref=f8e77]:
- generic [ref=f8e78]:
- heading "Ofsted Rating Inspected 6 June 2023 Ofsted reports ↗" [level=2] [ref=f8e79]:
- text: Ofsted Rating
- generic [ref=f8e80]: Inspected 6 June 2023
- link "Ofsted reports ↗" [ref=f8e81] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/146678
- generic [ref=f8e83]: Good
- paragraph [ref=f8e84]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections of state-funded schools.
- paragraph [ref=f8e85]:
- text: Rated
- strong [ref=f8e86]: Good
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f8e87]:
- heading "SATs Results (2024/25)" [level=2] [ref=f8e88]
- paragraph [ref=f8e89]: End-of-primary-school tests taken by Year 6 pupils. National averages shown for comparison.
- generic [ref=f8e90]:
- generic [ref=f8e91]:
- generic [ref=f8e92]: Reading, Writing & Maths combined
- generic [ref=f8e93]:
- text: 74.0%
- generic [ref=f8e94]: +12 pts
- generic [ref=f8e95]: "National avg: 62%"
- generic [ref=f8e96]:
- generic [ref=f8e97]: Exceeding expected level (Reading, Writing & Maths)
- generic [ref=f8e98]:
- text: 11.0%
- generic [ref=f8e99]: +3 pts
- generic [ref=f8e100]: "National avg: 8%"
- generic [ref=f8e101]:
- generic [ref=f8e102]: "?"
- generic [ref=f8e103]:
- generic [ref=f8e104]:
- text: Why is combined lower? A pupil is only counted if they met the bar in
- strong [ref=f8e105]: all three
- text: subjects. Some passed reading but not writing; some passed writing but not maths.
- generic [ref=f8e106]:
- generic [ref=f8e107]:
- text: Reading
- strong [ref=f8e108]: 74%
- generic [ref=f8e109]: ·
- generic [ref=f8e110]:
- text: Writing
- strong [ref=f8e111]: 74%
- generic [ref=f8e112]: ·
- generic [ref=f8e113]:
- text: Maths
- strong [ref=f8e114]: 81%
- generic [ref=f8e115]:
- generic [ref=f8e116]:
- text: All three
- strong [ref=f8e117]: 74%
- generic [ref=f8e118]:
- generic [ref=f8e119]:
- generic [ref=f8e120]:
- generic [ref=f8e121]: Reading
- generic [ref=f8e122]:
- generic:
- generic: 75%
- generic [ref=f8e123]:
- generic [ref=f8e125]:
- generic [ref=f8e126]: Expected
- generic [ref=f8e127]: 74%
- generic [ref=f8e131]:
- generic [ref=f8e132]: Exceeding
- generic [ref=f8e133]: 48%
- generic [ref=f8e136]:
- generic [ref=f8e138]: 0%
- generic [ref=f8e140]: 25%
- generic [ref=f8e142]: 50%
- generic [ref=f8e144]: 75%
- generic [ref=f8e146]: 100%
- generic [ref=f8e147]:
- generic [ref=f8e148]: Writing
- generic [ref=f8e149]:
- generic:
- generic: 72%
- generic [ref=f8e150]:
- generic [ref=f8e152]:
- generic [ref=f8e153]: Expected
- generic [ref=f8e154]: 74%
- generic [ref=f8e158]:
- generic [ref=f8e159]: Exceeding
- generic [ref=f8e160]: 11%
- generic [ref=f8e163]:
- generic [ref=f8e165]: 0%
- generic [ref=f8e167]: 25%
- generic [ref=f8e169]: 50%
- generic [ref=f8e171]: 75%
- generic [ref=f8e173]: 100%
- generic [ref=f8e174]:
- generic [ref=f8e175]: Maths
- generic [ref=f8e176]:
- generic:
- generic: 74%
- generic [ref=f8e177]:
- generic [ref=f8e179]:
- generic [ref=f8e180]: Expected
- generic [ref=f8e181]: 81%
- generic [ref=f8e185]:
- generic [ref=f8e186]: Exceeding
- generic [ref=f8e187]: 33%
- generic [ref=f8e190]:
- generic [ref=f8e192]: 0%
- generic [ref=f8e194]: 25%
- generic [ref=f8e196]: 50%
- generic [ref=f8e198]: 75%
- generic [ref=f8e200]: 100%
- generic [ref=f8e201]:
- generic [ref=f8e202]: Expected standard
- generic [ref=f8e204]: Exceeding / high score
- generic [ref=f8e206]: National average
- generic [ref=f8e208]:
- generic [ref=f8e209]:
- heading "Admissions" [level=2] [ref=f8e210]
- group "Admissions view" [ref=f8e211]:
- button "This year" [pressed] [ref=f8e212] [cursor=pointer]
- button "8-year trend" [ref=f8e213] [cursor=pointer]
- generic [ref=f8e216]:
- generic [ref=f8e217]:
- definition [ref=f8e218]: "21"
- term [ref=f8e219]: Places offered
- generic [ref=f8e220]:
- definition [ref=f8e221]: "19"
- term [ref=f8e222]: Wanted it first
- generic [ref=f8e223]:
- definition [ref=f8e224]:
- text: "19"
- generic [ref=f8e225]: of 19 · 100.0%
- term [ref=f8e226]: Got their first choice
- generic [ref=f8e227]:
- definition [ref=f8e228]: "45"
- term [ref=f8e229]: Applied in total
- generic [ref=f8e230]:
- heading "Pupils & Inclusion" [level=2] [ref=f8e231]
- generic [ref=f8e232]:
- generic [ref=f8e233]:
- generic [ref=f8e234]: Eligible for pupil premium
- generic [ref=f8e235]: 26.0%
- generic [ref=f8e236]: Pupils from disadvantaged backgrounds
- generic [ref=f8e237]:
- generic [ref=f8e238]: English as an additional language
- generic [ref=f8e239]: 0.0%
- generic [ref=f8e240]:
- generic [ref=f8e241]: Pupils receiving SEN support
- generic [ref=f8e242]: 4.0%
- generic [ref=f8e243]:
- generic [ref=f8e244]: Boys and girls
- generic [ref=f8e245]:
- generic [ref=f8e246]: 48%
- generic [ref=f8e247]: girls
- generic [ref=f8e248]: ·
- generic [ref=f8e249]: 52%
- generic [ref=f8e250]: boys
- 'img "Gender split: 48% girls, 52% boys" [ref=f8e251]'
- generic [ref=f8e254]: 64 girls, 70 boys
- generic [ref=f8e255]:
- heading "Results Over Time" [level=2] [ref=f8e256]
- generic [ref=f8e258]:
- generic [ref=f8e259]: ↓ Reading, Writing & Maths peaked at 81% (2022/23), currently 74%
- generic [ref=f8e260]:
- generic [ref=f8e261]: KS2 SATs · Reading, Writing & Maths
- tablist "Select metric" [ref=f8e262]:
- tab "At expected level" [selected] [ref=f8e263] [cursor=pointer]
- tab "Above expected level" [ref=f8e264] [cursor=pointer]
- tab "Pupil progress" [ref=f8e265] [cursor=pointer]
- img [ref=f8e267]
- paragraph [ref=f8e268]: "* No data for 2019/20 or 2020/21 — national assessments were cancelled due to COVID-19."
- group [ref=f8e269]:
- generic "▸ View raw year-by-year data" [ref=f8e270] [cursor=pointer]
- contentinfo [ref=f8e271]:
- generic [ref=f8e272]:
- generic [ref=f8e273]:
- generic [ref=f8e274]:
- heading "SchoolCompare" [level=3] [ref=f8e275]
- paragraph [ref=f8e276]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f8e277] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f8e278]:
- heading "Product" [level=4] [ref=f8e279]
- list [ref=f8e280]:
- listitem [ref=f8e281]:
- link "Search schools" [ref=f8e282] [cursor=pointer]:
- /url: /
- listitem [ref=f8e283]:
- link "Rankings" [ref=f8e284] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f8e285]:
- link "Compare shortlist" [ref=f8e286] [cursor=pointer]:
- /url: /compare
- listitem [ref=f8e287]:
- link "Admissions guide" [ref=f8e288] [cursor=pointer]:
- /url: /admissions
- generic [ref=f8e289]:
- heading "Resources" [level=4] [ref=f8e290]
- list [ref=f8e291]:
- listitem [ref=f8e292]:
- link "School Performance Tables" [ref=f8e293] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f8e294]:
- link "Ofsted reports" [ref=f8e295] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f8e297]: © 2026 SchoolCompare.co.uk
- alert [ref=f8e298]
@@ -0,0 +1,226 @@
- generic [active] [ref=f9e1]:
- link "Skip to main content" [ref=f9e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f9e3]:
- link "SchoolCompare home" [ref=f9e5] [cursor=pointer]:
- /url: /
- img [ref=f9e7]
- generic [ref=f9e11]: SchoolCompare
- navigation "Main navigation" [ref=f9e12]:
- link "Search" [ref=f9e13] [cursor=pointer]:
- /url: /
- img [ref=f9e15]
- generic [ref=f9e18]: Search
- link "1 selected Compare" [ref=f9e19] [cursor=pointer]:
- /url: /compare
- generic [ref=f9e20]:
- img [ref=f9e21]
- generic "1 selected" [ref=f9e24]: "1"
- generic [ref=f9e25]: Compare
- link "Rankings" [ref=f9e26] [cursor=pointer]:
- /url: /rankings
- img [ref=f9e28]
- generic [ref=f9e29]: Rankings
- link "Admissions" [ref=f9e30] [cursor=pointer]:
- /url: /admissions
- img [ref=f9e32]
- generic [ref=f9e35]: Admissions
- main [ref=f9e36]:
- generic [ref=f9e37]:
- button "Back" [ref=f9e38] [cursor=pointer]:
- generic [ref=f9e39]:
- text: Back
- generic [ref=f9e40]:
- generic [ref=f9e41]:
- generic [ref=f9e42]:
- img [ref=f9e46] [cursor=pointer]
- generic [ref=f9e49]:
- link "Leaflet" [ref=f9e50] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f9e51]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f9e55] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f9e56] [cursor=pointer]:
- generic [ref=f9e57]:
- img [ref=f9e58]
- text: Open full map
- generic [ref=f9e60]:
- generic [ref=f9e61]:
- heading "The Castle School" [level=1] [ref=f9e62]
- generic [ref=f9e63]:
- generic [ref=f9e64]: Academy converter
- generic [ref=f9e65]: Ages 1119
- paragraph [ref=f9e66]:
- text: Wellington Road, Taunton, TA1 5AU ·
- button "View on map ↗" [ref=f9e67] [cursor=pointer]
- generic [ref=f9e68]:
- generic [ref=f9e69]:
- strong [ref=f9e70]: "Headteacher:"
- text: Mr James Lamb
- link "School website ↗" [ref=f9e72] [cursor=pointer]:
- /url: http://www.castleschool.co.uk/
- generic [ref=f9e73]:
- strong [ref=f9e74]: "Pupils:"
- text: "1,202 (capacity: 1188)"
- generic [ref=f9e75]:
- text: Part of
- strong [ref=f9e76]: BLACKDOWN EDUCATION PARTNERSHIP
- button "✓ In Comparison" [ref=f9e78] [cursor=pointer]
- navigation "Page sections" [ref=f9e79]:
- generic [ref=f9e80]:
- button "Back to top" [ref=f9e81] [cursor=pointer]: ↑ Top
- link "Ofsted" [ref=f9e83] [cursor=pointer]:
- /url: "#ofsted"
- link "GCSEs" [ref=f9e84] [cursor=pointer]:
- /url: "#gcse"
- link "Admissions" [ref=f9e85] [cursor=pointer]:
- /url: "#admissions"
- link "History" [ref=f9e86] [cursor=pointer]:
- /url: "#history"
- link "Wellbeing" [ref=f9e87] [cursor=pointer]:
- /url: "#wellbeing"
- generic [ref=f9e88]:
- heading "Ofsted Rating Inspected 3 October 2023 Ofsted reports ↗" [level=2] [ref=f9e89]:
- text: Ofsted Rating
- generic [ref=f9e90]: Inspected 3 October 2023
- link "Ofsted reports ↗" [ref=f9e91] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/136916
- generic [ref=f9e93]: Outstanding
- paragraph [ref=f9e94]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.
- paragraph [ref=f9e95]:
- text: Rated
- strong [ref=f9e96]: Outstanding
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f9e97]:
- heading "GCSE Results (2024/25)" [level=2] [ref=f9e98]
- paragraph [ref=f9e99]: GCSE results for Year 11 pupils. National averages shown for comparison.
- generic [ref=f9e100]: Progress 8 scores for 2024/25 are not used for accountability purposes following the KS2 assessment disruption. Treat with caution.
- generic [ref=f9e101]:
- generic [ref=f9e102]:
- generic [ref=f9e103]: Attainment 8 score
- generic [ref=f9e104]:
- text: "53.4"
- generic [ref=f9e105]: +14 pts
- generic [ref=f9e106]: "National avg: 39.1"
- generic [ref=f9e107]:
- generic [ref=f9e108]: English & Maths Grade 5+
- generic [ref=f9e109]:
- text: 57.7%
- generic [ref=f9e110]: +22 pts
- generic [ref=f9e111]: "National avg: 36%"
- generic [ref=f9e112]:
- generic [ref=f9e113]: English & Maths Grade 4+
- generic [ref=f9e114]:
- text: 79.5%
- generic [ref=f9e115]: +28 pts
- generic [ref=f9e116]: "National avg: 51%"
- generic [ref=f9e117]:
- generic [ref=f9e118]: Attainment 8 — school vs national
- generic [ref=f9e122]: Nat avg 39.1
- generic [ref=f9e123]:
- generic [ref=f9e124]: "0"
- generic [ref=f9e125]: "20"
- generic [ref=f9e126]: "40"
- generic [ref=f9e127]: "60"
- generic [ref=f9e128]: "80"
- heading "English Baccalaureate (EBacc)" [level=3] [ref=f9e129]
- generic [ref=f9e130]:
- generic [ref=f9e131]:
- generic [ref=f9e132]: Pupils entered for EBacc
- generic [ref=f9e133]: 30.1%
- generic [ref=f9e134]:
- generic [ref=f9e135]: EBacc Grade 4+
- generic [ref=f9e136]: 25.1%
- generic [ref=f9e137]:
- generic [ref=f9e138]: EBacc Grade 5+
- generic [ref=f9e139]: 20.5%
- generic [ref=f9e140]:
- generic [ref=f9e141]: EBacc average point score
- generic [ref=f9e142]: "4.72"
- generic [ref=f9e143]:
- heading "Admissions" [level=2] [ref=f9e144]
- generic [ref=f9e145]:
- generic [ref=f9e146]:
- generic [ref=f9e147]: Year 7 places offered
- generic [ref=f9e148]: "237"
- generic [ref=f9e149]:
- generic [ref=f9e150]: Total applications
- generic [ref=f9e151]: "707"
- generic [ref=f9e152]:
- generic [ref=f9e153]: 1st preference applications
- generic [ref=f9e154]: "336"
- generic [ref=f9e155]:
- generic [ref=f9e156]: Families who got their first choice
- generic [ref=f9e157]: 69.6%
- generic [ref=f9e158]: ⚠ Applications exceeded places last year
- paragraph [ref=f9e159]: Historical distance cut-off data is not available for this school. Contact the admissions authority for oversubscription criteria details.
- generic [ref=f9e160]:
- heading "Historical Results" [level=2] [ref=f9e161]
- heading "Results Over Time" [level=3] [ref=f9e162]
- generic [ref=f9e164]:
- generic [ref=f9e165]:
- generic [ref=f9e166]: GCSE results · Year 11
- tablist "Select metric" [ref=f9e167]:
- tab "Attainment 8" [selected] [ref=f9e168] [cursor=pointer]
- tab "English & Maths grade 4+" [ref=f9e169] [cursor=pointer]
- tab "Progress 8" [ref=f9e170] [cursor=pointer]
- img [ref=f9e172]
- group [ref=f9e173]:
- generic "▶ View raw year-by-year data" [ref=f9e174] [cursor=pointer]
- generic [ref=f9e175]:
- heading "Wellbeing & Context" [level=2] [ref=f9e176]
- heading "Special Educational Needs (SEN)" [level=3] [ref=f9e177]
- generic [ref=f9e178]:
- generic [ref=f9e179]:
- generic [ref=f9e180]: SEN support
- generic [ref=f9e181]: 5.4%
- generic [ref=f9e182]: Without an EHCP
- generic [ref=f9e183]:
- generic [ref=f9e184]: Pupils with EHCP
- generic [ref=f9e185]: 3.8%
- generic [ref=f9e186]: Education, Health and Care Plan
- generic [ref=f9e187]:
- generic [ref=f9e188]: Total pupils
- generic [ref=f9e189]: 1,207
- 'img "Gender split: 52% girls, 48% boys" [ref=f9e190]'
- generic [ref=f9e193]:
- generic [ref=f9e194]: 52% girls
- text: ·
- generic [ref=f9e195]: 48% boys
- contentinfo [ref=f9e196]:
- generic [ref=f9e197]:
- generic [ref=f9e198]:
- generic [ref=f9e199]:
- heading "SchoolCompare" [level=3] [ref=f9e200]
- paragraph [ref=f9e201]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f9e202] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f9e203]:
- heading "Product" [level=4] [ref=f9e204]
- list [ref=f9e205]:
- listitem [ref=f9e206]:
- link "Search schools" [ref=f9e207] [cursor=pointer]:
- /url: /
- listitem [ref=f9e208]:
- link "Rankings" [ref=f9e209] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f9e210]:
- link "Compare shortlist" [ref=f9e211] [cursor=pointer]:
- /url: /compare
- listitem [ref=f9e212]:
- link "Admissions guide" [ref=f9e213] [cursor=pointer]:
- /url: /admissions
- generic [ref=f9e214]:
- heading "Resources" [level=4] [ref=f9e215]
- list [ref=f9e216]:
- listitem [ref=f9e217]:
- link "School Performance Tables" [ref=f9e218] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f9e219]:
- link "Ofsted reports" [ref=f9e220] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f9e222]: © 2026 SchoolCompare.co.uk
- alert [ref=f9e223]
@@ -0,0 +1,230 @@
- generic [active] [ref=f10e1]:
- link "Skip to main content" [ref=f10e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f10e3]:
- generic [ref=f10e4]:
- link "SchoolCompare home" [ref=f10e5] [cursor=pointer]:
- /url: /
- img [ref=f10e7]
- generic [ref=f10e11]: SchoolCompare
- navigation "Main navigation" [ref=f10e12]:
- link "Search" [ref=f10e13] [cursor=pointer]:
- /url: /
- link "Compare 1" [ref=f10e14] [cursor=pointer]:
- /url: /compare
- text: Compare
- generic [ref=f10e15]: "1"
- link "Rankings" [ref=f10e16] [cursor=pointer]:
- /url: /rankings
- link "Admissions" [ref=f10e17] [cursor=pointer]:
- /url: /admissions
- main [ref=f10e18]:
- generic [ref=f10e19]:
- button "Back" [ref=f10e20] [cursor=pointer]:
- generic [ref=f10e21]:
- text: Back
- generic [ref=f10e22]:
- generic [ref=f10e23]:
- generic [ref=f10e24]:
- img [ref=f10e28] [cursor=pointer]
- generic [ref=f10e31]:
- link "Leaflet" [ref=f10e32] [cursor=pointer]:
- /url: https://leafletjs.com
- img [ref=f10e33]
- text: Leaflet
- text: "| ©"
- link "OpenStreetMap" [ref=f10e37] [cursor=pointer]:
- /url: https://www.openstreetmap.org/copyright
- text: contributors
- button "Open full map" [ref=f10e38] [cursor=pointer]:
- generic [ref=f10e39]:
- img [ref=f10e40]
- text: Open full map
- generic [ref=f10e42]:
- generic [ref=f10e43]:
- heading "The Castle School" [level=1] [ref=f10e44]
- generic [ref=f10e45]:
- generic [ref=f10e46]: Academy converter
- generic [ref=f10e47]: Ages 1119
- paragraph [ref=f10e48]:
- text: Wellington Road, Taunton, TA1 5AU ·
- button "View on map ↗" [ref=f10e49] [cursor=pointer]
- generic [ref=f10e50]:
- generic [ref=f10e51]:
- strong [ref=f10e52]: "Headteacher:"
- text: Mr James Lamb
- link "School website ↗" [ref=f10e54] [cursor=pointer]:
- /url: http://www.castleschool.co.uk/
- generic [ref=f10e55]:
- strong [ref=f10e56]: "Pupils:"
- text: "1,202 (capacity: 1188)"
- generic [ref=f10e57]:
- text: Part of
- strong [ref=f10e58]: BLACKDOWN EDUCATION PARTNERSHIP
- button "✓ In Comparison" [ref=f10e60] [cursor=pointer]
- navigation "Page sections" [ref=f10e61]:
- generic [ref=f10e62]:
- button "Back to top" [ref=f10e63] [cursor=pointer]: ↑ Top
- link "Ofsted" [ref=f10e65] [cursor=pointer]:
- /url: "#ofsted"
- link "GCSEs" [ref=f10e66] [cursor=pointer]:
- /url: "#gcse"
- link "Admissions" [ref=f10e67] [cursor=pointer]:
- /url: "#admissions"
- link "History" [ref=f10e68] [cursor=pointer]:
- /url: "#history"
- link "Wellbeing" [ref=f10e69] [cursor=pointer]:
- /url: "#wellbeing"
- generic [ref=f10e70]:
- heading "Ofsted Rating Inspected 3 October 2023 Ofsted reports ↗" [level=2] [ref=f10e71]:
- text: Ofsted Rating
- generic [ref=f10e72]: Inspected 3 October 2023
- link "Ofsted reports ↗" [ref=f10e73] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/inspection-reports/find-inspection-report/provider/ELS/136916
- generic [ref=f10e75]: Outstanding
- paragraph [ref=f10e76]: From September 2024, Ofsted no longer makes an overall effectiveness judgement in inspections.
- paragraph [ref=f10e77]:
- text: Rated
- strong [ref=f10e78]: Outstanding
- text: across all inspected areas — Quality of Teaching, Behaviour, Pupils' Development and Leadership.
- generic [ref=f10e79]:
- heading "GCSE Results (2024/25)" [level=2] [ref=f10e80]
- paragraph [ref=f10e81]: GCSE results for Year 11 pupils. National averages shown for comparison.
- generic [ref=f10e82]: Progress 8 scores for 2024/25 are not used for accountability purposes following the KS2 assessment disruption. Treat with caution.
- generic [ref=f10e83]:
- generic [ref=f10e84]:
- generic [ref=f10e85]:
- text: Attainment 8 score
- img "Attainment 8" [ref=f10e87]: ⓘ
- generic [ref=f10e88]:
- text: "53.4"
- generic [ref=f10e89]: +14 pts
- generic [ref=f10e90]: "National avg: 39.1"
- generic [ref=f10e91]:
- generic [ref=f10e92]:
- text: English & Maths Grade 5+
- img "English & Maths — Grade 5+ (Strong Pass)" [ref=f10e94]: ⓘ
- generic [ref=f10e95]:
- text: 57.7%
- generic [ref=f10e96]: +22 pts
- generic [ref=f10e97]: "National avg: 36%"
- generic [ref=f10e98]:
- generic [ref=f10e99]:
- text: English & Maths Grade 4+
- img "English & Maths — Grade 4+ (Standard Pass)" [ref=f10e101]: ⓘ
- generic [ref=f10e102]:
- text: 79.5%
- generic [ref=f10e103]: +28 pts
- generic [ref=f10e104]: "National avg: 51%"
- generic [ref=f10e105]:
- generic [ref=f10e106]: Attainment 8 — school vs national
- generic [ref=f10e110]: Nat avg 39.1
- generic [ref=f10e111]:
- generic [ref=f10e112]: "0"
- generic [ref=f10e113]: "20"
- generic [ref=f10e114]: "40"
- generic [ref=f10e115]: "60"
- generic [ref=f10e116]: "80"
- heading "English Baccalaureate (EBacc) EBacc Entry" [level=3] [ref=f10e117]:
- text: English Baccalaureate (EBacc)
- img "EBacc Entry" [ref=f10e119]: ⓘ
- generic [ref=f10e120]:
- generic [ref=f10e121]:
- generic [ref=f10e122]: Pupils entered for EBacc
- generic [ref=f10e123]: 30.1%
- generic [ref=f10e124]:
- generic [ref=f10e125]: EBacc Grade 4+
- generic [ref=f10e126]: 25.1%
- generic [ref=f10e127]:
- generic [ref=f10e128]: EBacc Grade 5+
- generic [ref=f10e129]: 20.5%
- generic [ref=f10e130]:
- generic [ref=f10e131]: EBacc average point score
- generic [ref=f10e132]: "4.72"
- generic [ref=f10e133]:
- heading "Admissions" [level=2] [ref=f10e134]
- generic [ref=f10e135]:
- generic [ref=f10e136]:
- generic [ref=f10e137]: Year 7 places offered
- generic [ref=f10e138]: "237"
- generic [ref=f10e139]:
- generic [ref=f10e140]: Total applications
- generic [ref=f10e141]: "707"
- generic [ref=f10e142]:
- generic [ref=f10e143]: 1st preference applications
- generic [ref=f10e144]: "336"
- generic [ref=f10e145]:
- generic [ref=f10e146]: Families who got their first choice
- generic [ref=f10e147]: 69.6%
- generic [ref=f10e148]: ⚠ Applications exceeded places last year
- paragraph [ref=f10e149]: Historical distance cut-off data is not available for this school. Contact the admissions authority for oversubscription criteria details.
- generic [ref=f10e150]:
- heading "Historical Results" [level=2] [ref=f10e151]
- heading "Results Over Time" [level=3] [ref=f10e152]
- img [ref=f10e156]
- group [ref=f10e157]:
- generic "▶ View raw year-by-year data" [ref=f10e158] [cursor=pointer]
- generic [ref=f10e159]:
- heading "Wellbeing & Context" [level=2] [ref=f10e160]
- heading "Special Educational Needs (SEN)" [level=3] [ref=f10e161]
- generic [ref=f10e162]:
- generic [ref=f10e163]:
- generic [ref=f10e164]:
- text: SEN support
- img "SEN Support" [ref=f10e166]: ⓘ
- generic [ref=f10e167]: 5.4%
- generic [ref=f10e168]: Without an EHCP
- generic [ref=f10e169]:
- generic [ref=f10e170]:
- text: Pupils with EHCP
- img "Education, Health and Care Plan (EHCP)" [ref=f10e172]: ⓘ
- generic [ref=f10e173]: 3.8%
- generic [ref=f10e174]: Education, Health and Care Plan
- generic [ref=f10e175]:
- generic [ref=f10e176]: Total pupils
- generic [ref=f10e177]: 1,207
- 'img "Gender split: 52% girls, 48% boys" [ref=f10e178]'
- generic [ref=f10e181]:
- generic [ref=f10e182]: 52% girls
- text: ·
- generic [ref=f10e183]: 48% boys
- generic [ref=f10e186]:
- generic [ref=f10e187]:
- generic [ref=f10e188]: "1"
- text: school selected
- button "Expand comparison panel" [ref=f10e189] [cursor=pointer]:
- img [ref=f10e190]
- contentinfo [ref=f10e192]:
- generic [ref=f10e193]:
- generic [ref=f10e194]:
- generic [ref=f10e195]:
- heading "SchoolCompare" [level=3] [ref=f10e196]
- paragraph [ref=f10e197]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f10e198] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f10e199]:
- heading "Product" [level=4] [ref=f10e200]
- list [ref=f10e201]:
- listitem [ref=f10e202]:
- link "Search schools" [ref=f10e203] [cursor=pointer]:
- /url: /
- listitem [ref=f10e204]:
- link "Rankings" [ref=f10e205] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f10e206]:
- link "Compare shortlist" [ref=f10e207] [cursor=pointer]:
- /url: /compare
- listitem [ref=f10e208]:
- link "Admissions guide" [ref=f10e209] [cursor=pointer]:
- /url: /admissions
- generic [ref=f10e210]:
- heading "Resources" [level=4] [ref=f10e211]
- list [ref=f10e212]:
- listitem [ref=f10e213]:
- link "School Performance Tables" [ref=f10e214] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f10e215]:
- link "Ofsted reports" [ref=f10e216] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f10e218]: © 2026 SchoolCompare.co.uk
- alert [ref=f10e219]
@@ -0,0 +1,120 @@
- generic [active] [ref=f11e1]:
- link "Skip to main content" [ref=f11e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f11e3]:
- link "SchoolCompare home" [ref=f11e5] [cursor=pointer]:
- /url: /
- img [ref=f11e7]
- generic [ref=f11e11]: SchoolCompare
- navigation "Main navigation" [ref=f11e12]:
- link "Search" [ref=f11e13] [cursor=pointer]:
- /url: /
- img [ref=f11e15]
- generic [ref=f11e18]: Search
- link "1 selected Compare" [ref=f11e19] [cursor=pointer]:
- /url: /compare
- generic [ref=f11e20]:
- img [ref=f11e21]
- generic "1 selected" [ref=f11e24]: "1"
- generic [ref=f11e25]: Compare
- link "Rankings" [ref=f11e26] [cursor=pointer]:
- /url: /rankings
- img [ref=f11e28]
- generic [ref=f11e29]: Rankings
- link "Admissions" [ref=f11e30] [cursor=pointer]:
- /url: /admissions
- img [ref=f11e32]
- generic [ref=f11e35]: Admissions
- main [ref=f11e36]:
- generic [ref=f11e37]:
- generic [ref=f11e39]:
- generic [ref=f11e40]:
- heading "Compare Schools" [level=1] [ref=f11e41]
- paragraph [ref=f11e42]: Comparing 1 school
- generic [ref=f11e43]:
- button "+ Add School" [ref=f11e44] [cursor=pointer]
- button "Share" [ref=f11e45] [cursor=pointer]:
- img [ref=f11e46]
- text: Share
- generic [ref=f11e49]:
- button "Primary (1)" [ref=f11e50] [cursor=pointer]
- button "Secondary (0)" [ref=f11e51] [cursor=pointer]
- generic [ref=f11e52]:
- generic [ref=f11e53]: "Select Metric:"
- combobox "Select Metric:" [ref=f11e54] [cursor=pointer]:
- option "Reading, Writing & Maths Combined %" [selected]
- option "Reading Expected %"
- option "Writing Expected %"
- option "Maths Expected %"
- option "GPS Expected %"
- option "Science Expected %"
- option "Reading, Writing & Maths Combined Higher %"
- option "Reading Higher %"
- option "Writing Higher %"
- option "Maths Higher %"
- option "GPS Higher %"
- option "Reading Progress"
- option "Writing Progress"
- option "Maths Progress"
- option "Reading Average Score"
- option "Maths Average Score"
- option "GPS Average Score"
- option "Reading, Writing & Maths Expected % (Boys)"
- option "Reading, Writing & Maths Expected % (Girls)"
- option "Reading, Writing & Maths Higher % (Boys)"
- option "Reading, Writing & Maths Higher % (Girls)"
- option "Reading, Writing & Maths Expected % (Disadvantaged)"
- option "Reading, Writing & Maths Expected % (Non-Disadvantaged)"
- option "Disadvantaged Gap"
- option "% Disadvantaged Pupils"
- option "% EAL Pupils"
- option "% SEN Support"
- option "% Pupil Stability"
- option "Reading Test Absence %"
- option "GPS Test Absence %"
- option "Maths Test Absence %"
- option "Writing Absence %"
- option "Science Absence %"
- paragraph [ref=f11e55]: "% meeting expected standard in reading, writing and maths"
- generic [ref=f11e58]:
- button "Remove The Castle School" [ref=f11e59] [cursor=pointer]: ×
- heading "The Castle School" [level=2] [ref=f11e60]:
- link "The Castle School" [ref=f11e61] [cursor=pointer]:
- /url: /school/136916-the-castle-school
- generic [ref=f11e62]:
- generic [ref=f11e63]: Somerset
- generic [ref=f11e64]: Academy converter
- contentinfo [ref=f11e76]:
- generic [ref=f11e77]:
- generic [ref=f11e78]:
- generic [ref=f11e79]:
- heading "SchoolCompare" [level=3] [ref=f11e80]
- paragraph [ref=f11e81]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f11e82] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f11e83]:
- heading "Product" [level=4] [ref=f11e84]
- list [ref=f11e85]:
- listitem [ref=f11e86]:
- link "Search schools" [ref=f11e87] [cursor=pointer]:
- /url: /
- listitem [ref=f11e88]:
- link "Rankings" [ref=f11e89] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f11e90]:
- link "Compare shortlist" [ref=f11e91] [cursor=pointer]:
- /url: /compare
- listitem [ref=f11e92]:
- link "Admissions guide" [ref=f11e93] [cursor=pointer]:
- /url: /admissions
- generic [ref=f11e94]:
- heading "Resources" [level=4] [ref=f11e95]
- list [ref=f11e96]:
- listitem [ref=f11e97]:
- link "School Performance Tables" [ref=f11e98] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f11e99]:
- link "Ofsted reports" [ref=f11e100] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f11e102]: © 2026 SchoolCompare.co.uk
- alert [ref=f11e103]
@@ -0,0 +1,69 @@
- generic [active] [ref=f12e1]:
- link "Skip to main content" [ref=f12e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f12e3]:
- link "SchoolCompare home" [ref=f12e5] [cursor=pointer]:
- /url: /
- img [ref=f12e7]
- generic [ref=f12e11]: SchoolCompare
- navigation "Main navigation" [ref=f12e12]:
- link "Search" [ref=f12e13] [cursor=pointer]:
- /url: /
- img [ref=f12e15]
- generic [ref=f12e18]: Search
- link "Compare" [ref=f12e19] [cursor=pointer]:
- /url: /compare
- img [ref=f12e21]
- generic [ref=f12e24]: Compare
- link "Rankings" [ref=f12e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f12e27]
- generic [ref=f12e28]: Rankings
- link "Admissions" [ref=f12e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f12e31]
- generic [ref=f12e34]: Admissions
- main [ref=f12e35]:
- generic [ref=f12e36]:
- generic [ref=f12e37]:
- heading "Compare Schools" [level=1] [ref=f12e38]
- paragraph [ref=f12e39]: Add schools to your comparison basket to see side-by-side performance data
- generic [ref=f12e40]:
- img [ref=f12e42]
- heading "No schools selected" [level=3] [ref=f12e45]
- paragraph [ref=f12e46]: Add schools from the home page or search to start comparing.
- button "+ Add Schools to Compare" [ref=f12e47] [cursor=pointer]
- contentinfo [ref=f12e48]:
- generic [ref=f12e49]:
- generic [ref=f12e50]:
- generic [ref=f12e51]:
- heading "SchoolCompare" [level=3] [ref=f12e52]
- paragraph [ref=f12e53]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f12e54] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f12e55]:
- heading "Product" [level=4] [ref=f12e56]
- list [ref=f12e57]:
- listitem [ref=f12e58]:
- link "Search schools" [ref=f12e59] [cursor=pointer]:
- /url: /
- listitem [ref=f12e60]:
- link "Rankings" [ref=f12e61] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f12e62]:
- link "Compare shortlist" [ref=f12e63] [cursor=pointer]:
- /url: /compare
- listitem [ref=f12e64]:
- link "Admissions guide" [ref=f12e65] [cursor=pointer]:
- /url: /admissions
- generic [ref=f12e66]:
- heading "Resources" [level=4] [ref=f12e67]
- list [ref=f12e68]:
- listitem [ref=f12e69]:
- link "School Performance Tables" [ref=f12e70] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f12e71]:
- link "Ofsted reports" [ref=f12e72] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f12e74]: © 2026 SchoolCompare.co.uk
- alert [ref=f12e75]
@@ -0,0 +1,76 @@
- generic [ref=f12e1]:
- link "Skip to main content" [ref=f12e2] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f12e3]:
- link "SchoolCompare home" [ref=f12e5] [cursor=pointer]:
- /url: /
- img [ref=f12e7]
- generic [ref=f12e11]: SchoolCompare
- navigation "Main navigation" [ref=f12e12]:
- link "Search" [ref=f12e13] [cursor=pointer]:
- /url: /
- img [ref=f12e15]
- generic [ref=f12e18]: Search
- link "Compare" [ref=f12e19] [cursor=pointer]:
- /url: /compare
- img [ref=f12e21]
- generic [ref=f12e24]: Compare
- link "Rankings" [ref=f12e25] [cursor=pointer]:
- /url: /rankings
- img [ref=f12e27]
- generic [ref=f12e28]: Rankings
- link "Admissions" [ref=f12e29] [cursor=pointer]:
- /url: /admissions
- img [ref=f12e31]
- generic [ref=f12e34]: Admissions
- main [ref=f12e35]:
- generic [ref=f12e36]:
- generic [ref=f12e37]:
- heading "Compare Schools" [level=1] [ref=f12e38]
- paragraph [ref=f12e39]: Add schools to your comparison basket to see side-by-side performance data
- generic [ref=f12e40]:
- img [ref=f12e42]
- heading "No schools selected" [level=3] [ref=f12e45]
- paragraph [ref=f12e46]: Add schools from the home page or search to start comparing.
- button "+ Add Schools to Compare" [ref=f12e47] [cursor=pointer]
- contentinfo [ref=f12e48]:
- generic [ref=f12e49]:
- generic [ref=f12e50]:
- generic [ref=f12e51]:
- heading "SchoolCompare" [level=3] [ref=f12e52]
- paragraph [ref=f12e53]: Compare primary and secondary schools across England.
- link "contact@schoolcompare.co.uk" [ref=f12e54] [cursor=pointer]:
- /url: mailto:contact@schoolcompare.co.uk
- generic [ref=f12e55]:
- heading "Product" [level=4] [ref=f12e56]
- list [ref=f12e57]:
- listitem [ref=f12e58]:
- link "Search schools" [ref=f12e59] [cursor=pointer]:
- /url: /
- listitem [ref=f12e60]:
- link "Rankings" [ref=f12e61] [cursor=pointer]:
- /url: /rankings
- listitem [ref=f12e62]:
- link "Compare shortlist" [ref=f12e63] [cursor=pointer]:
- /url: /compare
- listitem [ref=f12e64]:
- link "Admissions guide" [ref=f12e65] [cursor=pointer]:
- /url: /admissions
- generic [ref=f12e66]:
- heading "Resources" [level=4] [ref=f12e67]
- list [ref=f12e68]:
- listitem [ref=f12e69]:
- link "School Performance Tables" [ref=f12e70] [cursor=pointer]:
- /url: https://www.gov.uk/school-performance-tables
- listitem [ref=f12e71]:
- link "Ofsted reports" [ref=f12e72] [cursor=pointer]:
- /url: https://reports.ofsted.gov.uk/
- paragraph [ref=f12e74]: © 2026 SchoolCompare.co.uk
- alert [ref=f12e75]
- generic [ref=f12e77]:
- button "Close modal" [ref=f12e79] [cursor=pointer]:
- img [ref=f12e80]
- generic [ref=f12e84]:
- heading "Add School to Comparison" [level=2] [ref=f12e85]
- textbox "School name or postcode" [active] [ref=f12e87]
- generic [ref=f12e88]: Start typing to search for schools...

Some files were not shown because too many files have changed in this diff Show More