Status: accepted · Date: 2026-11-13 · Implements: product ADR-04 · Deviates from: product ADR-03 (PostGIS)
Enforcement: [test] packages/api/src/features/atlas/atlas.fog.test.ts (grid size ≈ 1,000 hexes, every European City on or next to land, fog for 1,000 hexes in < 50 ms) · [convention] no tile provider in apps/*/package.json.
The fog map is the product's signature (RF05) and must open in ≤ 1.5 s with 1,000 hexes on a mid-range phone (RNF03), offline, without third-party tiles that cost money and leak usage. The ARD assumed PostGIS for route–academy distances. Neon supports the postgis extension, but the questions v1 asks are coarse: "which Cities are within 25/75 km of the route" and "which academies are within an alert radius of 50–600 km". Both are answerable with City centroids and a haversine distance; nothing in v1 needs polygons, streets or spatial joins over millions of rows.
Decision
- Geometry is a leaf module, not a database feature.
atlas.hex.tsdefines pointy-top axial hexes over an equirectangular projection with longitude scaled by cos 50° (≈ 47 km per hex).atlas.grid.tsships the ~905 land hexes of Europe (lon −11…31, lat 35.5…61.5) as an 813-byte run-length string generated once from Natural Earth 1:50m land (public domain) byscripts/generate-atlas-grid.mjs. - Cities are a static catalog (
atlas.cities.ts): id, names in PT/EN/DE, country, centroid. Distances are haversine indistanceKm. The database stores City ids only. - Fog is computed on the client from two id lists (visited, network) by
atlas.fog.ts; the server never sends hex geometry. Web and mobile draw the same data (mobile with Skia, web with SVG/canvas). - No PostGIS in v1. If a later feature needs real spatial queries, enable
postgison Neon in a migration and record it here.
Consequences
- The map works offline and costs nothing per view; no usage leaves the device.
- Little geographic detail: no streets, coasts are hex-coarse. Accepted in product ADR-04.
- Adding a City is a code change, reviewed like any other (the catalog is small and curated, with PT/EN/DE names).