Specific-airports mode scans never resolved full airport names — they
stored the IATA code as destination_name. Fixed in two places:
- airports.py: add lookup_airport(iata) cached helper
- api_server.py: enrich destination_name/city on the fly in the routes
endpoint when the stored value equals the IATA code (fixes all past scans)
- scan_processor.py: resolve airport names at scan time in specific-airports
mode using lookup_airport (fixes future scans at the DB level)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Routes and individual flights are now written to the database as each
query result arrives, rather than after all queries finish. The frontend
already polls /scans/:id/routes while status=running, so routes appear
progressively with no frontend changes needed.
Changes:
- database/schema.sql: UNIQUE INDEX uq_routes_scan_dest(scan_id, destination)
- database/init_db.py: _migrate_add_routes_unique_index() migration
- scan_processor.py: _write_route_incremental() helper; progress_callback
now writes routes/flights immediately; Phase 2 bulk-write replaced with
a lightweight totals query
- searcher_v3.py: pass flights= kwarg to progress_callback on cache_hit
and api_success paths
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>