fix(search): offer every filter option, not only those in the results #169

Merged
tudor merged 2 commits from fix/filter-options-not-from-results into main 2026-10-02 09:34:02 +00:00
Owner

Problem

School type, Gender and Admissions took their options from the result set, which that filter had already narrowed. Choose "Girls" and only "Girls" was offered, so switching to "Boys" meant clearing the filter first. The same applied to school types. Phase had this bug once and was fixed the same way.

Whether Gender, Sixth form and Admissions appeared also depended on the results (any secondary school among them).

Change

  • Options: School type, Gender and Admissions now offer the full lists from /api/filters. Local authority stays scoped to the results on purpose, so a postcode search offers nearby councils rather than all 153.
  • Visibility: Gender, Sixth form and Admissions now depend on the phase only. They're hidden for Primary, Nursery and Middle deemed primary, and shown otherwise, including "Any phase".
  • Choosing one of those primary phases clears all three, rather than leaving them applied with no control on screen.
  • docs/LEGACY_CODE.md: the backend's result_filters keys school_types, phases, genders and admissions_policies are no longer read. Recorded there for a later API cleanup; the backend is unchanged here.

Testing

  • Jest: new FilterBarOptions.test.tsx (11 cases). 554/554 pass, typecheck clean.
  • E2E: new journey "school type and gender switch straight to another value". Run against current staging, it fails as expected at selectOption('boys'): the option isn't offered.

🤖 Generated with Claude Code

## Problem School type, Gender and Admissions took their options from the result set, which that filter had already narrowed. Choose "Girls" and only "Girls" was offered, so switching to "Boys" meant clearing the filter first. The same applied to school types. Phase had this bug once and was fixed the same way. Whether Gender, Sixth form and Admissions **appeared** also depended on the results (any secondary school among them). ## Change - **Options:** School type, Gender and Admissions now offer the full lists from `/api/filters`. **Local authority stays scoped to the results** on purpose, so a postcode search offers nearby councils rather than all 153. - **Visibility:** Gender, Sixth form and Admissions now depend on the phase only. They're hidden for Primary, Nursery and Middle deemed primary, and shown otherwise, including "Any phase". - **Choosing one of those primary phases clears all three**, rather than leaving them applied with no control on screen. - `docs/LEGACY_CODE.md`: the backend's `result_filters` keys `school_types`, `phases`, `genders` and `admissions_policies` are no longer read. Recorded there for a later API cleanup; the backend is unchanged here. ## Testing - Jest: new `FilterBarOptions.test.tsx` (11 cases). 554/554 pass, typecheck clean. - E2E: new journey **"school type and gender switch straight to another value"**. Run against current staging, it fails as expected at `selectOption('boys')`: the option isn't offered. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tudor added 1 commit 2026-10-02 09:23:03 +00:00
fix(search): offer every filter option, not only those in the results
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m17s
PR Checks / Backend Smoke (pull_request) Successful in 9s
PR Checks / Build Backend (no push) (pull_request) Successful in 19s
PR Checks / Build Frontend (no push) (pull_request) Successful in 1m22s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 15s
0cc4f52816
School type, gender and admissions took their options from the result
set, which the filter had already narrowed: choose "Girls" and only
"Girls" was offered, so switching to "Boys" meant clearing first. They
now offer the full lists from /api/filters, as phase already did. Local
authority stays scoped to the results, so a postcode search offers the
councils nearby rather than all 153.

Whether gender, sixth form and admissions show was also decided by the
results (any secondary school in them). It is now decided by the phase
alone: hidden for Primary, Nursery and Middle deemed primary, shown
otherwise. Choosing one of those phases clears the three filters, which
would otherwise stay applied with no control showing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

🤖 AI Code Review (Claude Code)

Makes FilterBar offer full option lists for school type, gender and admissions (local authority stays scoped to results). Secondary-only filters now show based on the chosen phase rather than on result contents, and choosing a primary phase clears them. Adds unit and e2e tests plus a legacy-code doc note. The change looks healthy, with only minor concerns.

🟡 Minor

  • nextjs-app/components/FilterBar.tsx: Primary phases are matched by hard-coded lowercase strings ("primary", "nursery", "middle deemed primary"). If the API or URL uses a different phase label, such as 'Middle deemed primary' with different punctuation, the filters stay visible and are not cleared. Sharing this list with the backend phase grouping would avoid drift.
  • nextjs-app/components/FilterBar.tsx: With no phase chosen, isSecondaryMode is now true, so Gender, Sixth form and Admissions always show. If the pages pass an empty filters.genders or filters.admissions_policies (for example when /api/filters fails), the selects render with only the 'any' option. Previously they were hidden in that case.
  • e2e/tests/journeys.spec.ts: The e2e test takes the first school type option from the live list and asserts that more than 2 options remain. This depends on the seeded data holding at least 2 school types, which makes it somewhat brittle.
## 🤖 AI Code Review (Claude Code) Makes FilterBar offer full option lists for school type, gender and admissions (local authority stays scoped to results). Secondary-only filters now show based on the chosen phase rather than on result contents, and choosing a primary phase clears them. Adds unit and e2e tests plus a legacy-code doc note. The change looks healthy, with only minor concerns. ### 🟡 Minor - **nextjs-app/components/FilterBar.tsx**: Primary phases are matched by hard-coded lowercase strings ("primary", "nursery", "middle deemed primary"). If the API or URL uses a different phase label, such as 'Middle deemed primary' with different punctuation, the filters stay visible and are not cleared. Sharing this list with the backend phase grouping would avoid drift. - **nextjs-app/components/FilterBar.tsx**: With no phase chosen, isSecondaryMode is now true, so Gender, Sixth form and Admissions always show. If the pages pass an empty filters.genders or filters.admissions_policies (for example when /api/filters fails), the selects render with only the 'any' option. Previously they were hidden in that case. - **e2e/tests/journeys.spec.ts**: The e2e test takes the first school type option from the live list and asserts that more than 2 options remain. This depends on the seeded data holding at least 2 school types, which makes it somewhat brittle.
tudor added 1 commit 2026-10-02 09:28:34 +00:00
fix(search): match primary phases by their words, not exact labels
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m14s
PR Checks / Backend Smoke (pull_request) Successful in 10s
PR Checks / Build Backend (no push) (pull_request) Successful in 17s
PR Checks / Build Frontend (no push) (pull_request) Successful in 1m20s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 12s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 18s
68452681f8
The secondary-only filters were hidden for an exact set of lowercased
labels, so a change of case, hyphen or spacing in a GIAS phase label
would have left them showing. Phases are now matched on their words, as
compareGroups already reads "primary".

The E2E journey no longer counts school types: it asserts that choosing
one leaves the same list on offer, whatever the data holds. A test now
pins that a filter with no options is left out, not shown with only its
"any" option.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

🤖 AI Code Review (Claude Code)

FilterBar now takes school type, gender and admissions options from the full /api/filters lists instead of the narrowed result set, so switching from one value to another no longer needs the filter cleared first. Local authority stays scoped to the results. Secondary-only filters are now shown or hidden by the chosen phase, and choosing a primary phase clears them. The change adds unit and e2e tests and a legacy-code note. I found no correctness, security or deploy problems.

🟡 Minor

  • e2e/tests/journeys.spec.ts: The new e2e test needs the seeded data to hold a 'girls' gender value and at least two school types. It will fail on an environment with a sparse dataset rather than on a real regression. The offered.length > 1 assertion partly guards this, but the gender=girls precondition is unguarded.
## 🤖 AI Code Review (Claude Code) FilterBar now takes school type, gender and admissions options from the full `/api/filters` lists instead of the narrowed result set, so switching from one value to another no longer needs the filter cleared first. Local authority stays scoped to the results. Secondary-only filters are now shown or hidden by the chosen phase, and choosing a primary phase clears them. The change adds unit and e2e tests and a legacy-code note. I found no correctness, security or deploy problems. ### 🟡 Minor - **e2e/tests/journeys.spec.ts**: The new e2e test needs the seeded data to hold a 'girls' gender value and at least two school types. It will fail on an environment with a sparse dataset rather than on a real regression. The `offered.length > 1` assertion partly guards this, but the `gender=girls` precondition is unguarded.
tudor merged commit 99d62ef748 into main 2026-10-02 09:34:02 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tudor/school_compare#169