Files
boarding-pass/HANDOVER.md
T
bsncubed 408fde440d Initial commit: boarding pass to AirTrail pipeline
Photograph/screenshot a boarding pass, decode its BCBP barcode (PDF417/
Aztec/QR/DataMatrix), fetch the historical flight track from FlightAware
the day after the flight, stage it for review, and write it into AirTrail
via its REST API on approval. ntfy notifications carry signed
Approve/Deny/Investigate actions.
2026-07-04 22:21:02 +10:00

2.2 KiB

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/<id>/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 <input type=file>, but worth confirming on a real device.