# Status: build complete All 13 tasks are done. This file is now just a pointer, not a live handover - see `README.md` for setup/deploy instructions and `/home/ben/.claude/plans/glittery-weaving-moth.md` for the original design rationale (AirTrail REST API choice, FlightAware two-step scrape, schema). ## What was verified, inside a real Docker build - Built the image (`docker build .`) and ran it standalone. - Uploaded a synthetic PDF417 boarding pass photo through `/upload` → decoded → parsed → correctly staged as `queued` with ICAO codes resolved (SYD→YSSY, SIN→WSSS, QF→QFA). - A photo with no barcode correctly landed on `decode_failed` with an error message, not a crash. - `/flights//requery` hit real FlightAware for a real past flight (QFA1, 2026-06-22) and got back the same 1834-point track verified earlier in the session — end-to-end scrape confirmed working from inside the container. - The review detail page renders the track into a Leaflet map via `data-track`. - ntfy notifications fire with correctly signed Approve/Deny URLs; both wrong and missing tokens are correctly rejected with 403. - Approve, with no AirTrail configured, failed gracefully and pushed a distinct "Approve failed" ntfy notification rather than crashing or silently losing the flight — matches the design in `airtrail_client.py`. - Reject works and is idempotent. - The edit form re-resolves ICAO codes and `process_after` when IATA codes/date are corrected. ## What's NOT verified (no live AirTrail instance available here) - An actual `POST /api/flight/save` against a real AirTrail instance has never been exercised. The payload shape matches AirTrail's source (`build_save_payload` in `airtrail_client.py`), but the `seat`/`seatNumber`/`seatClass` field semantics are a best-effort mapping, not confirmed against real AirTrail behavior. **First real approve should be checked against the AirTrail UI** to confirm the flight, seat, and track show up as expected. - HEIC photos from iPhones weren't tested (only a synthetic JPEG barcode was used here). Should be fine since browsers typically convert to JPEG on ``, but worth confirming on a real device.