Extends the report-card detection fix (#62) to the list/map surface for consistency.
What was wrong
Search-result cards (buildOfstedListBadge) and map pins (buildPopupBadge) detected report cards with ofsted_framework === 'ReportCard' — but the API sets ofsted_framework to the raw event grouping ("Schools - S5"), so that never matched. 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 and card read "Outstanding · 2021" instead of "Report Card · 2026". Same root cause as #62, different surface.
Fix
Backend: expose ofsted_rc_date on the list serialization — the report-card inspection date, non-null only when the latest inspection carries report-card grades. It joins from fact_ofsted_inspection.rc_inspection_date; the fallback queries inherit it via the existing string-replacement derivation.
Frontend: both badge builders now treat a present ofsted_rc_date as winning over any grade, labelling "Report Card · {rc year}". Removed the dead framework === 'ReportCard' branches.
Tests
Unit: buildOfstedListBadge now asserts the ofsted_rc_date path and, crucially, that a report card wins over a carried-forward legacy grade (the Barclay case). 102 frontend + 52 backend green.
e2e: searching a real report-card school asserts its result card shows a "Report Card ·" badge (precondition-guarded on the list exposing ofsted_rc_date).
Note
Two full-object helpers in lib/utils.ts (buildOfstedHeroChip, buildSchoolSummary) still branch on framework === 'ReportCard', but both are dead code (no consumers) — left untouched rather than expand scope; worth deleting in a cleanup.
Extends the report-card detection fix (#62) to the list/map surface for consistency.
## What was wrong
Search-result cards (`buildOfstedListBadge`) and map pins (`buildPopupBadge`) detected report cards with `ofsted_framework === 'ReportCard'` — but the API sets `ofsted_framework` to the raw event grouping (`"Schools - S5"`), so that never matched. 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 and card read **"Outstanding · 2021"** instead of **"Report Card · 2026"**. Same root cause as #62, different surface.
## Fix
- **Backend:** expose `ofsted_rc_date` on the list serialization — the report-card inspection date, non-null only when the latest inspection carries report-card grades. It joins from `fact_ofsted_inspection.rc_inspection_date`; the fallback queries inherit it via the existing string-replacement derivation.
- **Frontend:** both badge builders now treat a present `ofsted_rc_date` as **winning over any grade**, labelling "Report Card · {rc year}". Removed the dead `framework === 'ReportCard'` branches.
## Tests
- Unit: `buildOfstedListBadge` now asserts the `ofsted_rc_date` path and, crucially, that **a report card wins over a carried-forward legacy grade** (the Barclay case). 102 frontend + 52 backend green.
- e2e: searching a real report-card school asserts its result card shows a "Report Card ·" badge (precondition-guarded on the list exposing `ofsted_rc_date`).
## Note
Two full-object helpers in `lib/utils.ts` (`buildOfstedHeroChip`, `buildSchoolSummary`) still branch on `framework === 'ReportCard'`, but both are **dead code** (no consumers) — left untouched rather than expand scope; worth deleting in a cleanup.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
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
This PR plumbs a new ofsted_rc_date field from the marts.fact_ofsted_inspection mart through the backend query/schema and into the list/map frontend, so report-card schools are badged 'Report Card · YYYY' instead of showing their stale carried-forward legacy grade. I traced the SQL, the dbt mart/staging models, and the frontend badge logic (utils.ts, LeafletMapInner.tsx) and the fix is correct and consistent with how the detail page already surfaces rc_inspection_date; only minor test-quality and doc-staleness issues remain.
🟡 Minor
e2e/tests/journeys.spec.ts: The new e2e test's precondition check (test.skip(!barclay?.ofsted_rc_date, ...)) causes the test to silently skip rather than fail if the backend ever stops exposing ofsted_rc_date for this school — masking exactly the regression the test is meant to catch.
e2e/tests/journeys.spec.ts: The precondition API call uses per_page=5, which is not a parameter the backend recognizes (it's page_size); the request silently falls back to the default page size instead of limiting results.
nextjs-app/lib/utils.ts: The docstring above buildOfstedListBadge still says report cards are detected via ofsted_framework === 'ReportCard', which is the bug this PR fixes — the comment was not updated to describe the new ofsted_rc_date-based check.
## 🤖 AI Code Review (Claude Code)
This PR plumbs a new `ofsted_rc_date` field from the `marts.fact_ofsted_inspection` mart through the backend query/schema and into the list/map frontend, so report-card schools are badged 'Report Card · YYYY' instead of showing their stale carried-forward legacy grade. I traced the SQL, the dbt mart/staging models, and the frontend badge logic (utils.ts, LeafletMapInner.tsx) and the fix is correct and consistent with how the detail page already surfaces rc_inspection_date; only minor test-quality and doc-staleness issues remain.
### 🟡 Minor
- **e2e/tests/journeys.spec.ts**: The new e2e test's precondition check (`test.skip(!barclay?.ofsted_rc_date, ...)`) causes the test to silently skip rather than fail if the backend ever stops exposing ofsted_rc_date for this school — masking exactly the regression the test is meant to catch.
- **e2e/tests/journeys.spec.ts**: The precondition API call uses `per_page=5`, which is not a parameter the backend recognizes (it's `page_size`); the request silently falls back to the default page size instead of limiting results.
- **nextjs-app/lib/utils.ts**: The docstring above buildOfstedListBadge still says report cards are detected via `ofsted_framework === 'ReportCard'`, which is the bug this PR fixes — the comment was not updated to describe the new ofsted_rc_date-based check.
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
tudor
merged commit a2c63b3cda into main2026-07-18 20:28:20 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Extends the report-card detection fix (#62) to the list/map surface for consistency.
What was wrong
Search-result cards (
buildOfstedListBadge) and map pins (buildPopupBadge) detected report cards withofsted_framework === 'ReportCard'— but the API setsofsted_frameworkto the raw event grouping ("Schools - S5"), so that never matched. 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 and card read "Outstanding · 2021" instead of "Report Card · 2026". Same root cause as #62, different surface.Fix
ofsted_rc_dateon the list serialization — the report-card inspection date, non-null only when the latest inspection carries report-card grades. It joins fromfact_ofsted_inspection.rc_inspection_date; the fallback queries inherit it via the existing string-replacement derivation.ofsted_rc_dateas winning over any grade, labelling "Report Card · {rc year}". Removed the deadframework === 'ReportCard'branches.Tests
buildOfstedListBadgenow asserts theofsted_rc_datepath and, crucially, that a report card wins over a carried-forward legacy grade (the Barclay case). 102 frontend + 52 backend green.ofsted_rc_date).Note
Two full-object helpers in
lib/utils.ts(buildOfstedHeroChip,buildSchoolSummary) still branch onframework === 'ReportCard', but both are dead code (no consumers) — left untouched rather than expand scope; worth deleting in a cleanup.🤖 Generated with Claude Code
https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
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🤖 AI Code Review (Claude Code)
This PR plumbs a new
ofsted_rc_datefield from themarts.fact_ofsted_inspectionmart through the backend query/schema and into the list/map frontend, so report-card schools are badged 'Report Card · YYYY' instead of showing their stale carried-forward legacy grade. I traced the SQL, the dbt mart/staging models, and the frontend badge logic (utils.ts, LeafletMapInner.tsx) and the fix is correct and consistent with how the detail page already surfaces rc_inspection_date; only minor test-quality and doc-staleness issues remain.🟡 Minor
test.skip(!barclay?.ofsted_rc_date, ...)) causes the test to silently skip rather than fail if the backend ever stops exposing ofsted_rc_date for this school — masking exactly the regression the test is meant to catch.per_page=5, which is not a parameter the backend recognizes (it'spage_size); the request silently falls back to the default page size instead of limiting results.ofsted_framework === 'ReportCard', which is the bug this PR fixes — the comment was not updated to describe the new ofsted_rc_date-based check.