3.7 KiB
3.7 KiB
Changelog
v0.2.2 — 2026-09-16 20:05
playwright.config.ts: e2e suite can now run on a different machine than the app — withE2E_REMOTE=1the localwebServerblock is skipped entirely andbaseURLdefaults tohttp://flight.dev.kkhost.pl;E2E_BASE_URLoverridesbaseURLin both modes; with no env vars set behavior is unchanged (localwebServerauto-startsnpm run dev)
v0.2.1 — 2026-09-16 19:49
- Clamp map zoom to the useful gameplay range:
minZoom: 3/maxZoom: 14on the MapLibre options incomponents/Map.tsx(exported asMIN_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 viaexpect.pollon the map instance thatgetZoom()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) runningnext starton port 3000; nooutput: 'standalone'— the runtime stage keeps fullnode_modulesbecause/api/mlworker/[file]reads maplibre-gl dist files from disk at runtime (and/api/airportsreadsdata/*.csv) .dockerignore: node_modules, .next, data/*.db, test-results, *.tsbuildinfo, plus .git/.env/.codenomad and the e2e harness (@playwright/testis 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 serviceflight, no published ports, joins external networkdev_netwith Traefik labels routingHost(flight.dev.kkhost.pl)→ port 3000 (plain HTTP entrypointweb; 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=0orNEXT_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 inlib/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 (
webServerauto-startsnpm run dev; page load + airport count + marker click popup)