# Development and validation ## Prerequisites and environment boundaries Use a feature branch. The deployed stack is the integration environment; do not assume a local server can run from a fresh checkout. This cleanup did not start local servers or provision databases. Unit tests use fixtures and mocks. The current versions are not yet aligned: | Component | Container | PR checks | |---|---|---| | Backend | Python 3.11 | Python 3.12 | | Frontend | Node 24 | Node 22 | | Pipeline | Python 3.13 | Pipeline image build | Use the component's container version when reproducing deployment behaviour. The backend dependency pins predate Python 3.14; do not assume the system Python can install or run them. Version alignment is a separate maintenance task. ## Frontend checks ```sh cd nextjs-app npm ci npm run typecheck npm test -- --runInBand ``` `npm run build` is the production build check. There is no `lint` script. Tests live in `__tests__/` and use Jest/React Testing Library. These checks do not prove that live PostgreSQL queries, Typesense or a deployed proxy work. The frontend `.env.example` documents runtime variables. Browser traffic normally uses `/api`; `FASTAPI_URL` is an absolute server-side URL ending in `/api`. Payload additionally needs `DATABASE_URL` and `PAYLOAD_SECRET` when used at runtime. Never commit credentials or real `.env` files. ## Backend checks From the repository root, using an available Python 3.11 or 3.12 interpreter: ```sh python3.11 -m venv /tmp/schoolcompare-backend-venv /tmp/schoolcompare-backend-venv/bin/python -m pip install -r requirements.txt pytest 'httpx<0.28' /tmp/schoolcompare-backend-venv/bin/python -m pytest backend/tests -q ``` Substitute `python3.12` if matching PR CI. The test dependencies above match the current workflow; they are not yet captured in a dedicated development lockfile. Backend configuration is defined in `backend/config.py`; `.env.example` documents commonly used values. `ALLOWED_ORIGINS` uses a JSON array, not a comma-separated string. ## Data and pipeline work The app needs populated `marts.*` tables. A new Postgres instance alone is not a working school-data environment. Use the existing managed pipeline or an approved snapshot; the removed CSV importer cannot build the current schema. The pipeline container includes Meltano, dbt/Postgres, Airflow and the custom taps. Airflow commands/selectors live in `pipeline/dags/`. Schema tests live in `pipeline/transform/tests/` and model YAML files. Run the relevant `dbt build` selector in an isolated data environment for model changes; it writes tables and is not a read-only smoke test. Prefer `python -m dbt.cli.main` as the DAGs do. GIAS dictionaries are generated together by `pipeline/scripts/generate_gias_codes.py`. The backend and pipeline copies are intentional; `backend/tests/test_gias_codes.py` checks that they stay identical. For Payload collection/editor changes, run `npm run generate:importmap` in `nextjs-app/` and include the generated map. Preserve CMS migrations and the separate `payload` schema. See [publishing](../nextjs-app/docs/PUBLISHING.md). ## End-to-end checks Against an existing, authorised test environment: ```sh cd e2e npm ci npx playwright install chromium BASE_URL=https://your-test-environment.example npx playwright test ``` The suite does not start a web server. CI installs Chromium with system dependencies and runs against staging. Use the configured staging target: `docs/DEPLOY.md` records the public staging proxy limitation. User-visible behaviour changes should update the corresponding journeys. ## Before requesting review Run checks relevant to the change, inspect `git diff --check`, and report checks that could not run. Do not publish or promote as part of local validation. [DEPLOY.md](DEPLOY.md) documents the PR and human promotion gates.