Files
TudorandClaude Opus 5.5 0cc4f52816
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
fix(search): offer every filter option, not only those in the results
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>
2026-10-02 10:22:39 +01:00

7.7 KiB

Legacy and unused-code inventory

Reviewed 2026-09-14. This inventory records source evidence, not production usage telemetry. A command with no repository caller may still be run manually or from an external scheduler. Historical specs and prototypes are not runtime imports.

Method and scope

Searched backend imports, tests, CLI scripts, Airflow DAGs, Meltano configuration, Gitea workflows, Dockerfiles and documentation. For frontend candidates, inspected TypeScript imports, re-exports, literal dynamic imports and require calls, resolving relative and @/ paths while excluding tests, dependencies and build output. Checked candidates again with text searches including tests.

Next.js route files, generated Payload import-map entries and plugin discovery are entry points even without ordinary imports. This is why a zero-import count alone is not sufficient grounds for deletion. Computed imports and external operators are outside this static audit.

Removed in this cleanup

These names are recorded for Git-history lookup; they are no longer file links.

Removed path or symbol Evidence and replacement
backend/migration.py Imported School and SchoolResult, which no longer exist in backend/models.py. Only the legacy CSV CLI imported it. Current tables are built by dbt.
backend/version.py Only the legacy importer consumed SCHEMA_VERSION. FastAPI lifespan does not perform version-triggered imports. This is unrelated to active Payload migrations.
scripts/migrate_csv_to_db.py Imported removed init_db/set_db_schema_version helpers and the obsolete models indirectly. No runtime, DAG or workflow calls it. Use the managed pipeline for current marts.
scripts/geocode_schools.py Imported the removed School ORM model. No pipeline/workflow calls it. Coordinates now come from GIAS/PostGIS; a separate mart-aware manual utility remains under pipeline/scripts/.
backend.data_loader.haversine_distance No callers. Search uses its inline vectorised NumPy calculation.
nextjs-app/lib/api.ts: fetcher No callers; SWR is not installed. Application fetches use the named API wrappers.
nextjs-app/lib/api.ts: kmToMiles No callers. calculateDistance remains because CutoffMapPanel uses it.

The removed command files could not import successfully against the current backend. This cleanup does not run replacements, migrate data or modify databases. Their previous implementations remain recoverable from Git history.

Unused candidates retained for a separate cleanup

Candidate Evidence Recommended next step
nextjs-app/components/LoadingSkeleton.tsx and its CSS No application or test imports found. Remove together after confirming no planned use.
nextjs-app/components/Pagination.tsx and its CSS No application or test imports found; HomeView implements load-more behaviour. Remove as a pair if numbered pagination will not return.
nextjs-app/components/SchoolCard.tsx and its CSS Imported by its own tests, not application code. HomeView uses SchoolRow/SecondarySchoolRow. Decide whether to retire the card design; if removed, remove its dedicated tests as well. Passing tests do not establish runtime use.
backend/database.py: get_db, get_db_session No remaining callers after removing the importer. Current code creates SessionLocal directly. Either adopt these helpers during session-lifecycle cleanup or remove them; do not rewrite active sessions in a documentation change.
backend/schemas.py: COLUMN_MAPPINGS, NULL_VALUES, LA_CODE_TO_NAME No remaining Python consumers found after importer removal. Other constants in this module are active. Remove individual constants after checking external data utilities; retain the module.
backend/app.py: result_filters keys school_types, phases, genders, admissions_policies Since 2026-10-02 FilterBar offers these from /api/filters, because options scoped to the results left only the chosen value on offer. Only local_authorities is still read. Stop computing the four keys in a focused API change; keep local_authorities.
backend/config.py: data_dir, max_page_size, rate_limit_burst No active consumers found. default_page_size appears only in a branch that expects None, although the route supplies a concrete default. Reconcile settings with route validation in a focused API change.

Legacy/manual paths requiring operational verification

Path Status and reason to retain for now
FastAPI /, /compare, /rankings, /favicon.svg, /robots.txt, and conditional /static Old frontend-serving routes reference a frontend/ directory absent from the checkout and backend image. Next.js owns these public surfaces. Removal changes externally callable routes, so first check proxy/operator usage and define replacement responses.
scripts/fetch_real_data.py, scripts/download_data.py Historical standalone CSV utilities. The fetch script targets Wandsworth/Merton; neither is wired into the managed pipeline. Marked historical, retained pending confirmation of manual use.
pipeline/scripts/geocode_postcodes.py Mart-aware postcode fallback, not called by the current DAGs. Do not confuse it with the removed legacy ORM geocoder. Verify the target schema before manual use.
docker-compose.yml Uses unpublished :latest release tags and lacks frontend Payload DB/secret/media configuration. Retained as an old development topology, not recommended onboarding.
nextjs-app/docker-compose.yml Standalone legacy recipe with old backend port assumptions and no CMS persistence setup. Retained until its consumers are checked.
MIGRATION_SUMMARY.md, docs/superpowers/, mockups/ Historical designs and prototypes. Retain as history; do not follow as current deployment instructions.
scripts/sql/drop_fact_parent_view.sql One-off maintenance SQL. Not an application entry point; repository call-site searches cannot establish whether it is still needed operationally.

Active code that can look obsolete

  • backend/data_loader.py older-mart query fallbacks are covered by backend tests and support databases at different migration stages. Remove only after verifying the deployed schemas in every supported environment.
  • backend/gias_codes.py and pipeline/scripts/gias_codes.py are intentionally generated copies for separate runtime images. Their parity is tested.
  • nextjs-app/migrations/, payload-types.ts and the Payload import map are active CMS artifacts, not remnants of the removed school importer.
  • get_available_years, get_available_local_authorities and get_schools_count in data_loader.py are called through get_data_info, which serves the backend data-info endpoint. They are not dead functions.
  • get_supplementary_data is an intentional single-school wrapper around the batch implementation.
  • pipeline/transform models named legacy can be active data sources: annual DAG selectors explicitly include legacy KS2/KS4 lineage. Names alone do not establish obsolescence.

Suggested next passes

  1. Decide the fate of the three unused UI components and remove paired assets/tests.
  2. Consolidate backend session usage and remove abandoned settings/constants.
  3. Verify external consumers, then retire static-serving API routes and old compose recipes.
  4. Audit manual data utilities with pipeline operators before deleting them.
  5. Revisit compatibility fallbacks only after documenting supported schema versions.

Validation for this cleanup should include frontend typechecking/tests, Python syntax checks, reference searches and documentation link checks. Live database, external scheduler and deployed route usage require separate integration evidence.