feat(admissions): publish the latest cut-off only, holding history back #104

Merged
tudor merged 1 commits from feat/latest-cutoff-only into main 2026-08-20 17:51:18 +00:00
Owner

Earlier cut-off years are to become a paid feature, so they stop being published.

The part that matters: this is an API change, not a UI change

/api/schools/{urn} is public and unauthenticated. I checked before starting:

admission_distance_history: [{year: 2023, distance_m: 3933.24, ...}, ...]
-> readable by anyone hitting the API directly

Withholding the history in the page while still sending it in the payload would have been decoration — the whole record would sit in the network tab of the thing you intend to sell. It is withheld at the source, and the page follows.

Nothing changes upstream. The tap, the plausibility band and fact_admission_distance are untouched and still load every published year. Restoring history for entitled callers is a change to one function in data_loader, not a re-collection — I've said so in a comment there so the next person doesn't go looking for a pipeline change.

What a reader gets now

The latest figure on the Admissions tile, and a Distance section that answers what the number alone cannot: whether their own address falls inside it.

Retitled to "How far away are you?" — the old title described a record that is no longer there.

Removed with the history: the trend chart, the year table, the per-year verdict strip, the trend summary, the coverage note, and their CSS. Section height 743px → 417px.

A consequence worth naming

A run of years used to soften a single close call — a home just outside one year's cut-off was usually inside another. With one year published, the "too close to call" band is the entire safety margin between a parent and a place they do not have.

So the verdict now names its year (0.07 miles away — inside the September 2026 cut-off of 0.17 miles), and the three outcomes are tinted apart rather than distinguished by wording alone:

verdict treatment
inside green tint
beyond red tint
too close to call neutral — "we cannot tell" is not a bad outcome, and tinting it like one would push a reader toward a conclusion the data does not support

The explanation of why we can't call it is now supporting text rather than welded into the bold verdict line, where it was running three lines at headline weight.

The stylesheet test earned its keep

I referenced cutoffResultInside/Outside/TooClose before writing them. schoolStyles.test.ts caught it:

+   "cutoffResultInside",
+   "cutoffResultOutside",
+   "cutoffResultTooClose",

Unstyled, a "beyond the cut-off" result would have been pixel-identical to an "inside" one — the exact failure the longhand class map in CutoffMapPanel exists to prevent. Worth knowing that guard works, given how much of this feature turns on outcomes being visually distinct.

Verification

  • tsc clean; next build green
  • 205 frontend tests, 54 backend — including a render-side guard that no table, chart or per-year text can reappear in the section, so a future component cannot put the history back without the API
  • New e2e journey asserts the API itself carries no admission_distance_history
  • Rendered offline against the real compiled CSS in both themes; all three verdicts confirmed visually distinct by computed background, not by eye

Against staging, the public API serves the latest cut-off only fails — correctly. Staging still serves the history; that test is the guard for this change and should go green on deploy. 7 passed, 3 skipped, 1 failed in the distance group.

Worth a decision later

The page currently says nothing about history existing. If you want the premium feature discovered rather than stumbled upon, a line like "We hold N earlier years for this school" would seed it — but that needs the accounts system this codebase deliberately does not have, so I have not built toward it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE

Earlier cut-off years are to become a paid feature, so they stop being published. ## The part that matters: this is an API change, not a UI change `/api/schools/{urn}` is public and unauthenticated. I checked before starting: ``` admission_distance_history: [{year: 2023, distance_m: 3933.24, ...}, ...] -> readable by anyone hitting the API directly ``` Withholding the history in the page while still sending it in the payload would have been decoration — the whole record would sit in the network tab of the thing you intend to sell. **It is withheld at the source, and the page follows.** **Nothing changes upstream.** The tap, the plausibility band and `fact_admission_distance` are untouched and still load every published year. Restoring history for entitled callers is a change to one function in `data_loader`, not a re-collection — I've said so in a comment there so the next person doesn't go looking for a pipeline change. ## What a reader gets now The latest figure on the Admissions tile, and a Distance section that answers what the number alone cannot: whether their own address falls inside it. Retitled to **"How far away are you?"** — the old title described a record that is no longer there. Removed with the history: the trend chart, the year table, the per-year verdict strip, the trend summary, the coverage note, and their CSS. **Section height 743px → 417px.** ## A consequence worth naming A run of years used to soften a single close call — a home just outside one year's cut-off was usually inside another. With one year published, the **"too close to call" band is the entire safety margin** between a parent and a place they do not have. So the verdict now names its year (`0.07 miles away — inside the September 2026 cut-off of 0.17 miles`), and the three outcomes are tinted apart rather than distinguished by wording alone: | verdict | treatment | |---|---| | inside | green tint | | beyond | red tint | | too close to call | neutral — "we cannot tell" is not a bad outcome, and tinting it like one would push a reader toward a conclusion the data does not support | The explanation of *why* we can't call it is now supporting text rather than welded into the bold verdict line, where it was running three lines at headline weight. ## The stylesheet test earned its keep I referenced `cutoffResultInside/Outside/TooClose` before writing them. `schoolStyles.test.ts` caught it: ``` + "cutoffResultInside", + "cutoffResultOutside", + "cutoffResultTooClose", ``` Unstyled, a "beyond the cut-off" result would have been pixel-identical to an "inside" one — the exact failure the longhand class map in `CutoffMapPanel` exists to prevent. Worth knowing that guard works, given how much of this feature turns on outcomes being visually distinct. ## Verification - `tsc` clean; `next build` green - **205 frontend tests**, **54 backend** — including a render-side guard that no table, chart or per-year text can reappear in the section, so a future component cannot put the history back without the API - New e2e journey asserts the API itself carries no `admission_distance_history` - Rendered offline against the real compiled CSS in both themes; all three verdicts confirmed visually distinct by computed background, not by eye **Against staging, `the public API serves the latest cut-off only` fails — correctly.** Staging still serves the history; that test is the guard for this change and should go green on deploy. 7 passed, 3 skipped, 1 failed in the distance group. ## Worth a decision later The page currently says nothing about history existing. If you want the premium feature discovered rather than stumbled upon, a line like *"We hold N earlier years for this school"* would seed it — but that needs the accounts system this codebase deliberately does not have, so I have not built toward it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE
tudor added 1 commit 2026-08-20 17:45:25 +00:00
feat(admissions): publish the latest cut-off only, holding history back
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 16s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 3m17s
c9a1892bfb
Earlier years are to become a paid feature, so they stop being published.

The load-bearing part is that this is a change to the API, not only to the
page. /api/schools/{urn} is public and unauthenticated: leaving
admission_distance_history in the payload while declining to render it would
have handed the whole record to anyone who opened the network tab. It is
withheld at the source, and the page follows.

Nothing changes upstream. The tap, the plausibility band and
fact_admission_distance are untouched and still load every published year, so
restoring history for entitled callers is a change to one function in
data_loader rather than a re-collection.

What the reader now gets is the latest figure on the Admissions tile, and a
Distance section that answers the question the number alone cannot: whether
their own address falls inside it. Retitled to "How far away are you?", which
is what it now does — the previous title described a record that is no longer
there.

Removed with the history: the trend chart, the year-by-year table, the
per-year verdict strip, the trend summary and the coverage note, along with
their CSS. The section goes from 743px to 417px.

One consequence worth naming. A run of years used to soften a single close
call — a home just outside one year's cut-off was usually inside another. With
one year published, the "too close to call" band is the entire safety margin
between a parent and a place they do not have, so the verdict now names its
year, and the three outcomes are tinted apart rather than distinguished by
wording alone.

The existing stylesheet test earned its keep here: the three verdict classes
were referenced before they were written, and it caught them. Unstyled, a
"beyond the cut-off" result would have been indistinguishable from an "inside"
one — the exact failure the longhand class map was written to prevent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WDvkyqqHABm4bmth2kjAxE
tudor merged commit ffe7e04951 into main 2026-08-20 17:51:18 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tudor/school_compare#104