Batch 2 of testability refactor under epic AZ-447. All three changes are
minimal-surgical and preserve production behavior.
AZ-448 (C01) — Externalize OWM API key
- src/features/flights/flightPlanUtils.ts: read VITE_OWM_API_KEY at call
time; if unset, getWeatherData returns null (matches the existing
try/catch fallback contract, AC-3).
- Hardcoded literal removed; grep src/ for the old key returns no hits
(AC-2 / NFT-SEC-09 static-string check now green).
- AC-1 honored: when the key is set, the outbound URL contains
appid=<key>.
AZ-449 (C02) — Externalize OWM base URL
- Same call site reads VITE_OWM_BASE_URL with trim-trailing-slash
normalization; falls back to the public api.openweathermap.org/data/2.5
endpoint when unset (AC-1).
- Stub-friendly: VITE_OWM_BASE_URL=http://owm-stub:8081/data/2.5
redirects every call to the e2e stub (AC-2).
AZ-453 (C06) — Wrap login redirect in setNavigateToLogin accessor
- src/api/client.ts: navigateToLoginImpl module-level fn defaults to the
existing window.location.href = '/login' write; setNavigateToLogin(fn)
lets tests assert "redirect invoked" without globally stubbing
window.location.
- request() now calls navigateToLoginImpl() instead of writing
window.location directly.
Batch 1 task specs (AZ-450/451/452/454) moved from
_docs/02_tasks/todo/ to _docs/02_tasks/done/.
State pointer advanced to refactor Phase 4 (implement, batch 2 of 2).
Static checks:
- bun run tsc --noEmit: 0 errors
- grep '335799082893fad97fa36118b131f919' src/: 0 hits
- grep 'window.location.href' src/: 2 hits, both inside the
navigateToLoginImpl default (jsdoc + the default impl body) — no
caller writes window.location directly.
Co-authored-by: Cursor <cursoragent@cursor.com>
Refactor batch 1 of 2 for the 01-testability-refactoring epic
(AZ-447). Minimal-surgical edits to make the UI's external
dependencies overridable for the test profiles in
_docs/02_document/tests/environment.md.
- AZ-450 (C03): tile URLs externalized to VITE_OSM_TILE_URL and
VITE_ESRI_TILE_URL with the production strings as defaults.
Fixes the AC-N3 / NFT-RES-03 air-gap regression and lets the
e2e profile's tile-stub serve tiles deterministically.
- AZ-451 (C04): Leaflet marker icon imported from the pinned
leaflet package as a Vite asset; removes the unpkg.com CDN
reference (also fixes the leaflet@1.7.1 vs ^1.9.4 mismatch).
- AZ-452 (C05): getApiBase() accessor reading
VITE_API_BASE_URL. request(), refreshToken(), and createSSE()
prepend the prefix. Default '' preserves every call site.
- AZ-454 (C07): JSDoc on setToken/getToken documenting the
test-override intent so future cleanup doesn't delete them.
Also: .env.example documents every VITE_* var; vite-env.d.ts
declares ImportMetaEnv; .gitignore now excludes /dist and
*.tsbuildinfo (tracked-by-mistake cache file removed).
Build verification: `bunx tsc -b --noEmit` passes. No tests in
this run (testability-run exemption per refactor SKILL — tests
land in autodev Step 6).
Co-authored-by: Cursor <cursoragent@cursor.com>
- Port mission-planner flight planning to main app (Tailwind, react-leaflet v5, react-i18next)
- Add FlightMap with click-to-add waypoints, draggable markers, polyline with arrows
- Add FlightParamsPanel with action modes, waypoint list (drag-reorder), altitude chart, wind, JSON import/export
- Add FlightListSidebar with create/delete and telemetry date
- Add collapsible left panel with quick action mode shortcuts
- Add work area / no-go zone drawing via manual mouse events (L.rectangle)
- Add AltitudeDialog and JsonEditorDialog (Tailwind modals)
- Add battery/time/distance calculations per waypoint segment
- Add satellite/classic map toggle and mini-map on point drag
- Add Camera FOV and Communication Addr fields
- Add current position display under location search
- Merge mission-planner translations under flights.planner.*
- Gitignore .superpowers session data