fix(api): blank-name GIAS sentinel codes map to empty string, not Unknown(n) #27

Merged
tudor merged 1 commits from fix/gias-blank-name-codes into main 2026-07-09 21:21:08 +00:00
Owner

Staging logged Unknown GIAS code 99 (not in dictionary). Root cause: GIAS carries codes whose (name) column is blank — ReligiousCharacter 99 (3,975 schools), AdmissionsPolicy 9 (5,643), OfficialSixthForm 9 (9) — and the dictionary generator skipped blank-name pairs, so those codes fell into the Unknown (<code>) path. Regression: religious_denomination: "Unknown (99)" wrongly triggers the Faith-priority tag heuristic on ~4k schools and pollutes filter lists (old pipeline served an empty string for these).

Fix (TDD): the generator now maps blank-only codes to "" — byte-identical to the old name pipeline and falsy for UI heuristics — keeping Unknown (<code>) for genuinely new codes. Dictionaries + seed regenerated from today's live CSV; accepted_values lists extended (99 / 9). Sixth-form mart logic unchanged (code 9 already fell through to the statutory-age fallback, matching old blank behaviour). 21/21 backend tests.

🤖 Generated with Claude Code

Staging logged `Unknown GIAS code 99 (not in dictionary)`. Root cause: GIAS carries codes whose `(name)` column is blank — ReligiousCharacter 99 (3,975 schools), AdmissionsPolicy 9 (5,643), OfficialSixthForm 9 (9) — and the dictionary generator skipped blank-name pairs, so those codes fell into the `Unknown (<code>)` path. Regression: `religious_denomination: "Unknown (99)"` wrongly triggers the Faith-priority tag heuristic on ~4k schools and pollutes filter lists (old pipeline served an empty string for these). Fix (TDD): the generator now maps blank-only codes to `""` — byte-identical to the old name pipeline and falsy for UI heuristics — keeping `Unknown (<code>)` for genuinely new codes. Dictionaries + seed regenerated from today's live CSV; `accepted_values` lists extended (99 / 9). Sixth-form mart logic unchanged (code 9 already fell through to the statutory-age fallback, matching old blank behaviour). 21/21 backend tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tudor added 1 commit 2026-07-09 21:05:21 +00:00
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
3710529e49
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>

🤖 AI Code Review (Claude Code)

This PR fixes a regression where GIAS 'not recorded' sentinel codes (OfficialSixthForm 9, ReligiousCharacter 99, AdmissionsPolicy 9) were falling through to the 'Unknown ()' path instead of the blank string the old name-based pipeline produced. The generator script, both dictionary copies (kept byte-identical, enforced by an existing test), the dbt seed CSV, and the accepted_values tests are all updated consistently, and a new regression test locks in the blank-string behavior. The change is well-scoped and internally consistent; I found no correctness, security, or deploy/CI issues.

🟡 Minor

  • backend/tests/test_gias_codes.py: test_blank_name_sentinel_codes_map_to_empty_string only asserts the ReligiousCharacter(99) and AdmissionsPolicy(9) sentinels; it doesn't assert OFFICIAL_SIXTH_FORM[9] == "" even though that dictionary/seed also gained a blank-name code 9 in this diff, leaving that sentinel's regression-proofing weaker than the other two.
## 🤖 AI Code Review (Claude Code) This PR fixes a regression where GIAS 'not recorded' sentinel codes (OfficialSixthForm 9, ReligiousCharacter 99, AdmissionsPolicy 9) were falling through to the 'Unknown (<code>)' path instead of the blank string the old name-based pipeline produced. The generator script, both dictionary copies (kept byte-identical, enforced by an existing test), the dbt seed CSV, and the accepted_values tests are all updated consistently, and a new regression test locks in the blank-string behavior. The change is well-scoped and internally consistent; I found no correctness, security, or deploy/CI issues. ### 🟡 Minor - **backend/tests/test_gias_codes.py**: test_blank_name_sentinel_codes_map_to_empty_string only asserts the ReligiousCharacter(99) and AdmissionsPolicy(9) sentinels; it doesn't assert OFFICIAL_SIXTH_FORM[9] == "" even though that dictionary/seed also gained a blank-name code 9 in this diff, leaving that sentinel's regression-proofing weaker than the other two.
tudor merged commit 58e90fef61 into main 2026-07-09 21:21:08 +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#27