Files
Flight-Ops/CHANGELOG.md
T

8.5 KiB

Changelog

v0.2.8 — 2026-09-16 23:53

  • data/airports_eu.csv: reduced the dataset to only large_airport rows (dropped all 731 medium_airport + 54 seaplane_base) — the map now shows just the 260 biggest EU airports; /api/airports and the circle layer pick it up with no code changes
  • e2e/map.spec.ts: marker-click test repointed from ESSV Visby Airport (a medium_airport, now removed) to UKBB Boryspil International Airport — with only large_airport rows left it is the most isolated marker inside the initial zoom-4 viewport: its nearest surviving airport is Chişinău (LUKK), ~126 px away at the initial zoom (Kyiv Zhuliany, geographically closer, was a medium and got cut)
  • Verified: unit suite 12/12; tsc --noEmit clean; e2e suite 3/3 green against the rebuilt compose instance (/api/airports serves 260 features)

v0.2.7 — 2026-09-16 23:39

  • data/airports_eu.csv: removed all 6400 small_airport rows from the OurAirports EU export — the map now shows only the 1045 bigger airports (260 large + 731 medium + 54 seaplane_base); /api/airports and the circle layer pick it up with no code changes
  • e2e/map.spec.ts: marker-click test repointed from EKRN Bornholm Airport (a small_airport, now removed) to ESSV Visby Airport on Gotland — its nearest remaining airport is Stockholm Skavsta across the Baltic Sea (~59 px away at the initial zoom), so its marker cannot be overlapped by a neighbouring circle
  • Verified: unit suite 12/12; e2e suite 3/3 green against the rebuilt compose instance (/api/airports serves 1045 features)

v0.2.6 — 2026-09-16 22:41

  • Dockerfile: install stages switched from npm to bun (oven/bun:1.4.2-alpine, bun install --frozen-lockfile); package-lock.json replaced by bun.lock; no BuildKit type=cache mounts — they don't persist across builds on this daemon, and bun install is fast enough (~3 s cold) that cross-build caching isn't worth it
  • Dockerfile: new prod-deps stage (bun install --production) so the runtime image carries prod-only node_modules — devDeps (typescript, vitest, @types) are no longer shipped; build and runtime stages otherwise unchanged (still node:22-alpine, full .next, no standalone output)
  • .dockerignore: excludes docs/deployment files (*.md, Dockerfile*, docker-compose*) from the build context so changelog-only commits don't invalidate the COPY layer and re-run next build
  • Verified: full cold build 77 s → 58 s; e2e suite 3/3 green against the rebuilt compose instance

v0.2.5 — 2026-09-16 21:22

  • AGENTS.md: new "E2E tests (mandatory)" section codifies the e2e workflow — the compose instance behind Traefik (https://flight.dev.kkhost.pl) is always the app under test, never a local next dev on :3000; deploy current code first with docker compose up -d --build; browsers run through the shared remote Playwright server at 192.168.1.4:3000, and plain npx playwright test handles deploy + readiness + remote connect
  • playwright.config.ts: dropped the E2E_LOCAL=1 local-dev path accordingly — no more local :3000 dev instance for e2e; the default (and only) mode is browsers on the shared remote Playwright server against the prod build behind Traefik, with webServer running docker compose up -d --build; E2E_REMOTE=1 and explicit PW_TEST_CONNECT_WS_ENDPOINT/E2E_BASE_URL overrides are unchanged

v0.2.4 — 2026-09-16 21:06

  • playwright.config.ts: default e2e mode now targets the prod build behind Traefik (https://flight.dev.kkhost.pl) — baseURL defaults to that URL and webServer runs docker compose up -d --build (300 s timeout) instead of npm run dev, because next dev does not render for non-loopback clients: Turbopack's HMR WebSocket fails from the remote browsers, so the page loads blank
  • E2E_LOCAL=1 keeps the local iteration path (browsers on this box, webServer auto-starts npm run dev, baseURL localhost:3000) as a fallback when the proxy or compose stack is down; E2E_REMOTE=1 and explicit PW_TEST_CONNECT_WS_ENDPOINT/E2E_BASE_URL overrides are unchanged

v0.2.3 — 2026-09-16 20:30

  • playwright.config.ts: e2e now launches browsers on the shared remote Playwright server (Docker, ws://192.168.1.4:3000/) by default — when no env vars are set it exports PW_TEST_CONNECT_WS_ENDPOINT pointing at that box; in this mode baseURL defaults to this box's LAN IP (http://192.168.1.26:3000) because pages load from the remote browser's perspective, while the local webServer still auto-starts npm run dev
  • E2E_LOCAL=1 restores fully-local runs (browsers on this box, localhost:3000 baseURL) as a fallback when the remote server is down; E2E_REMOTE=1 keeps its previous behavior for runners on other machines — skips webServer entirely and pairs with E2E_BASE_URL; an explicit PW_TEST_CONNECT_WS_ENDPOINT always wins over the default

v0.2.2 — 2026-09-16 20:05

  • playwright.config.ts: e2e suite can now run on a different machine than the app — with E2E_REMOTE=1 the local webServer block is skipped entirely and baseURL defaults to http://flight.dev.kkhost.pl; E2E_BASE_URL overrides baseURL in both modes; with no env vars set behavior is unchanged (local webServer auto-starts npm run dev)

v0.2.1 — 2026-09-16 19:49

  • Clamp map zoom to the useful gameplay range: minZoom: 3 / maxZoom: 14 on the MapLibre options in components/Map.tsx (exported as MIN_ZOOM/MAX_ZOOM) — wheel travel from the Europe overview is now ~10 levels instead of ~16, and street-level zoom past the z12 pitch transition no longer exists
  • e2e: new test that wheels well past both limits via page.mouse.wheel (basemap tile fetches blocked for speed/determinism; clamping is pure camera behavior) and asserts via expect.poll on the map instance that getZoom() settles at 14 / 3, i.e. clamped within [3, 14]

v0.2.0 — 2026-09-16 18:32

  • Docker deployment: multi-stage Dockerfile (node:22-alpine; deps → build → runtime) running next start on port 3000; no output: 'standalone' — the runtime stage keeps full node_modules because /api/mlworker/[file] reads maplibre-gl dist files from disk at runtime (and /api/airports reads data/*.csv)
  • .dockerignore: node_modules, .next, data/*.db, test-results, *.tsbuildinfo, plus .git/.env/.codenomad and the e2e harness (@playwright/test is a host-global install, not a project dependency — Next's build-time type check would fail on it inside the image)
  • docker-compose.yml: single service flight, no published ports, joins external network dev_net with Traefik labels routing Host(flight.dev.kkhost.pl) → port 3000 (plain HTTP entrypoint web; TLS terminated upstream)
  • Verified: container builds and runs; router registered in dev_traefik rawdata; curl -H "Host: flight.dev.kkhost.pl" http://localhost/ → 200, /api/airports → 200 GeoJSON (7445 features), mlworker .mjs files served from node_modules inside the container; unit suite 12/12 and e2e suite 2/2 still green

v0.1.0 — 2026-09-16 18:24

  • Scaffolded Next.js (App Router) + TypeScript project; dev server on port 3000 (npm run dev)
  • Full-viewport MapLibre GL map with OpenFreeMap "liberty" vector basemap (attribution included via style)
  • Zoom-driven camera controller: top-down at zoom ≤ 6, smoothstep tilt to 45° pitch by zoom ≥ 12; pitch is a pure function of zoom so it never fights pan/zoom gestures
  • Lite 3D terrain from AWS terrarium raster-DEM tiles (map.setTerrain); toggleable off via ?terrain=0 or NEXT_PUBLIC_TERRAIN=0 (off in e2e for deterministic headless rendering)
  • EU airport seed data: OurAirports CSV (official mirror at davidmegginson.github.io/ourairports-data — the legacy ourairports.com/data URL now 404s) filtered to continent=EU with types small/medium/large_airport + seaplane_base → committed as data/airports_eu.csv (7445 airports; heliports, closed and balloon sites excluded — rationale documented in lib/airports.ts)
  • GET /api/airports: server-side CSV parse with in-memory cache, returns GeoJSON FeatureCollection (properties: name, icao, lat, lon)
  • Client renders airports as a GeoJSON circle layer (no DOM markers); click → popup with name + ICAO; header shows loaded airport count (data-testid="airport-count")
  • MapLibre worker served from node_modules via /api/mlworker/* route — bundlers break the URL MapLibre derives for its worker, which silently hangs GeoJSON source updates
  • Tests: vitest unit suite (CSV parse/filter, GeoJSON build, pitch curve, API handler) + self-contained Playwright e2e suite (webServer auto-starts npm run dev; page load + airport count + marker click popup)