Skip to content

[Feature] Airline and aircraft master data (mirror the Ships & Ports pattern) #189

Description

@Abrechen2

Summary

Promote airlines and aircraft types to real, seeded master data — mirroring what TravStats already does for airports, ships and ports — so imported flights show real names instead of raw codes, for every carrier rather than a curated few.

What's the problem and how can it be solved?

Bookings and boarding passes carry codes, not names (DLH, EWG, AT72). #178 made the app resolve those codes, but it resolves them against a hand-maintained 146-entry TypeScript file (backend/src/data/airlines.ts). That covers the major carriers and fixes the reported case, but it has a hard ceiling: any airline outside the list still renders its raw code, and there is no story at all for aircraft types — Flight.aircraft is free text, so AT72 never becomes "ATR 72-200".

The app already solves exactly this problem three times over, and none of those solutions were invented for it:

Entity Today
Airport real table, seeded from OurAirports (~85k rows)
Ship / Port real tables, idempotently seeded from CSV; isUserAdded rows are never overwritten by a re-seed
Admin → "Ships & Ports" (CruiseMasterData) a finished master-data management UI for exactly this
Airline ❌ free text + a 146-entry hardcoded file
Aircraft ❌ free text, no catalogue at all

The proposal is to mirror the existing pattern, not to invent a new one:

  • Airline and Aircraft become Prisma models, seeded idempotently from an open dataset (the ~2k-airline / ~250-aircraft-type range is what comparable self-hosted loggers carry), with user-added rows preserved across re-seeds — the same contract seedShipsFromCSV / seedPortsFromCSV already honour.
  • An "Airlines & Aircraft" admin section modelled on the existing "Ships & Ports" page: search, create, edit, and a re-sync action equivalent to the airport-seeding "check for updates" flow.
  • The parser and the flight-write paths resolve against the table instead of the hardcoded file, and the generated frontend mirror (frontend/src/lib/generated/airlineCatalog.ts, added in [Feature] Auto convert airline code to airline name #178 with a drift-guard test) can then be retired.

Once airlines are a table, the airline logo lookup in the flight list works for every carrier rather than only the ones that happen to be in the hand-maintained list — which is what the reporter of #178 asked about as a follow-on.

Alternatives considered

Keep growing the hardcoded file. Cheapest today, but it is a hand-maintained copy of public data that already drifted once (before #178 the frontend copy had 60 entries and zero ICAO codes while the backend had 146 with ICAO). Growing it to a few thousand rows makes that failure mode worse, not better, and it still leaves aircraft types unsolved.

Resolve codes through an external API at read time. Adds a network dependency and a per-request failure mode to a self-hosted app that is otherwise fully offline-capable. The existing seed-a-local-table pattern is deliberate and should not be abandoned for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions