CREATE TABLE IF NOT EXISTS does not add new columns to existing tables.
Use ALTER TABLE to migrate databases that predate this change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- races table: name, date, description, is_active
- stations table: ordered checkpoints with GPS per race
- New /api/races and /api/races/{id}/stations endpoints
- Upload now requires race + station selection; uses station GPS
so images without GPS EXIF are accepted
- passages filtered by active race throughout
- RacePage: create races, manage stations (add/edit/delete checkpoints)
- Navbar shows active race name
- Start and finish stations created automatically per race
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- POST /api/upload saves files to /depot/ for ingest processing
- Batches of 10 files per request
- Drag-and-drop zone + file picker, per-file status feedback
- New 'Last opp'-tab in navbar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- passage_images table stores every image in a burst sequence
- Passage timestamp = last image (chronologically) in the burst
- Review UI: image slider to browse all burst images, slider ends
at the official passage time (rightmost = last image)
- API: GET /api/passages/{id}/images
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Within a burst sequence from the same station, the image where the athlete
is physically closest to the camera gives the most accurate passage timestamp.
Proximity is measured by bib bounding box area (larger = closer).
When a duplicate is detected:
- New image closer: update timestamp + image path, delete old image
- Existing image closer: discard new image
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>