- Rewrite SettingsPage to 5-panel v2 layout: Tenant, Directories,
Aircrafts, Language, Session — corner-bracket panels, sticky footer
pinned to viewport bottom (Cancel + Save Changes), live dirty-state
indicator.
- Wire try/catch/finally + role="alert" in save handler so AZ-477's
three it.fails contract tests flip to passing; remove the obsolete
v1-drift control test and its unhandledRejection harness.
- Add EN/UA language toggle; persist to localStorage('azaion.lang')
and read on i18n init. Export LANG_STORAGE_KEY from src/i18n.
- Add Add-Aircraft flow (reuses admin Modal) and view-only star
default toggle.
- Extend the v2 design system with .btn-danger-ghost, .star,
.path-wrap/.browse classes. Scope settings.html-spec button
proportions (padding 7px 14px, weight 400, letter-spacing 0.10em,
line-height 1.5) under .settings-page so the admin spec is unaffected.
- Restore module-scoped bootstrapInflight declaration in
src/auth/AuthContext.tsx (deleted in 2a62415 while references
remained — every test using tests/setup.ts was throwing
ReferenceError).
- Design system: v2 CSS variables (surface-0/1/2, border-hair, accent-amber/cyan/red/green/blue)
and utility classes (.btn, .inp, .pill, .chip, .bracket, .panel, .seg, .swatch,
.type-sq, .grid-bg, .ibtn, .checkbox, .tab); v1 az-* names aliased to v2 vars
so other pages still render. Google Fonts (IBM Plex Sans + JetBrains Mono)
loaded via <link> in index.html <head> to avoid FOUT.
- Header rebuilt to v2: amber wordmark + // divider, amber-bordered flight pill
with cyan live dot, tab-style nav with amber underline on active, LINK status
pill, cog + sign-out icon buttons.
- AdminPage rewritten to 3-column layout (340 / flex / 280):
- Detection Classes: search + ADD button, table with #/Name/Hex/Ops columns,
name-only inline edit with ringed swatch, sibling-row error alert.
- AI Recognition Engine + GPS Device Link panels with corner-bracket borders,
number steppers, segmented protocol control, dashed telemetry footers.
Hooks (useAiSettings, useGpsSettings) seed factory defaults so the UI is
interactive when GET fails (no backend).
- Default Aircrafts: P/C/F type chips, isDefault star toggle, + ADD AIRCRAFT
modal with model/type/resolution/maxMinutes/default fields.
- Co-located components: Modal (backdrop + ESC + body-scroll-lock),
NumberStepper (▲▼ with clamp on click but not on typing), ClassEditRow.
- Types: Aircraft extended with FixedWing + optional resolution/maxMinutes;
new AiRecognitionSettings/Telemetry, GpsDeviceSettings/Telemetry, GpsProtocol.
- Endpoints: /api/admin/ai-settings, /api/admin/gps-settings (+ /ping, /reconnect).
POST /api/flights/aircrafts (plural REST collection).
- MSW: stateful admin-settings handler with resetAdminSettingsSeed() wired into
tests/setup.ts. Aircraft seed expanded to 6 entries matching the mockup.
- i18n: full admin.{classes,aiEngine,gpsDevice,aircrafts} key sets in en+ua;
nav.dataset shortened to "Dataset"; obsolete users-management keys removed.
- Tests: new AdminPage AI/GPS/aircraft test suites; admin_class_edit selectors
updated for the name-only inline editor and the modal-based add flow.
Move src/features/annotations/classColors.ts to its own component directory
src/class-colors/ with a proper barrel; update the 4 consumer imports to go
through the barrel; remove the F3-pending exemption from STC-ARCH-01 and from
the architecture test fixture; clean up the 5 coupled doc/script touchpoints.
Closes baseline finding F3 and retires the 5-coupled-places carry-over surface
logged in LESSONS.md 2026-05-12.
- Add `class-colors` to scripts/check-arch-imports.mjs COMPONENT_DIRS so deep
imports past the new barrel are caught symmetric to every other component.
- Replace the architecture test "exemption WORKS" fixture with the stronger
"deep import into class-colors NOW FAILS" assertion (Risk 4 mitigation).
- module-layout.md: Layout Rules + Per-Component Mapping (11_class-colors,
06_annotations, 03_shared-ui) + Verification Needed #1 + shared/class-colors
block all updated to reflect the new home.
- 11_class-colors/description.md: Caveats §7 + Module Inventory updated.
- architecture_compliance_baseline.md: F3 marked CLOSED with full pre-resolution
context preserved (mirrors AZ-485/F4 + AZ-486/F7 pattern); F4 carry-forward
exemption note retired.
- 04_verification_log.md: open questions #1 + #8 marked RESOLVED.
- Build passes with no circular-import warnings (AC-4); fast suite 231/13
skipped green (AC-5); static profile green (AC-3 — zero exemptions remain).
Batch report: _docs/03_implementation/batch_14_cycle3_report.md
Co-authored-by: Cursor <cursoragent@cursor.com>
AZ-498 — self-hosted satellite tiles + drop classic/satellite toggle:
- Single TILE_URL via getTileUrl() (mirrors getOwmBaseUrl/getApiBase
pattern from AZ-449/AZ-450); env-var VITE_SATELLITE_TILE_URL with
dev default http://localhost:5100/tiles/{z}/{x}/{y}.
- FlightMap + MiniMap render one TileLayer with
crossOrigin="use-credentials" so Leaflet's <img> tile fetcher
attaches the same-origin satellite-provider auth cookie.
- ImportMetaEnv + .env.example collapse the prior OSM/Esri pair into
one var. The flights.planner.satellite i18n key is removed in
lockstep across en.json + ua.json (parity preserved).
- E2E harness wired end-to-end: compose passes the new var to
azaion-ui; tile-stub serves /tiles/{z}/{x}/{y} with
Content-Type=image/jpeg + Cache-Control + ETag matching the
contract; infrastructure.e2e.ts AC-2 asserts the new path; dead
OSM defenses removed from EXTERNAL_HOSTS route guard.
- Fast-profile MSW handlers rewritten for the cookie-auth path shape.
- 8 colocated fast tests under src/features/flights/__tests__/.
AZ-499 — mission-planner OWM env-var hardening + AZ-482 source-scan
gap close:
- WeatherService.ts reads VITE_OWM_API_KEY + VITE_OWM_BASE_URL;
fail-soft null when key unset (mirrors AZ-448 main-SPA contract).
Public signature getWeatherData(lat, lon) preserved.
- mission-planner/.env.example + vite-env.d.ts declare both vars.
- New owm_key_in_source banned-deps kind scans src/ AND
mission-planner/ for the rotated literal; STC-SEC1C row added to
scripts/run-tests.sh; check-banned-deps.mjs dispatch extended.
- 7 fast tests under tests/mission_planner_weather.test.ts cover
AC-1..AC-4 + trailing-slash + happy path + network-error fail-soft.
Spec drift (recorded in batch_11_report.md, user-approved Choose B
on 2026-05-12):
- AZ-498 AC-8 dropped (named tile_split_zoom* files belong to AZ-474
image-annotation surface, not map tiles).
- 4 missing files added in-scope (msw tiles handler, tile-stub
server, compose env, dead VITE_TILE_BASE_URL replaced).
- AZ-499 STC-S6 ID conflict resolved by using STC-SEC1C.
Pending USER ACTION (BLOCKING for AZ-499 close):
- Revoke OpenWeatherMap key 335799082893fad97fa36118b131f919 at
home.openweathermap.org/api_keys; capture evidence on AZ-499.
Cross-workspace deploy gate (handled at autodev Step 16, not a
Step-10 blocker for AZ-498):
- satellite-provider cookie-auth on GET /tiles/{z}/{x}/{y}
(separate AZAION ticket on the satellite-provider workspace).
Reports: _docs/03_implementation/batch_11_report.md and
_docs/03_implementation/reviews/batch_11_review.md (verdict
PASS_WITH_WARNINGS — 1 Low, pre-existing trim-trailing-slash
duplication across vite roots).
Static gates: STC-ARCH-01, STC-ARCH-02, STC-T1, STC-FP22, STC-FP23,
STC-SEC1C all PASS post-refactor. +15 fast tests; +1 STC-SEC1C row.
Co-authored-by: Cursor <cursoragent@cursor.com>
Closes architecture baseline finding F4. Every component now exposes
its Public API through `src/<component>/index.ts`; cross-component
imports go through the barrel. `scripts/check-arch-imports.mjs` plus
`STC-ARCH-01` in the static profile enforce the rule; tests in
`tests/architecture_imports.test.ts` cover AC-4/AC-5 + 2 exemption
cases. One F3-pending exemption (`classColors`) is documented in 5
places (barrel, consumer, script, doc, test) to avoid a circular
import.
Phase B cycle 1 batch 1 of 2 (epic AZ-447). Batch 2 is AZ-486
(endpoint builders) — blocked on this commit landing.
Co-authored-by: Cursor <cursoragent@cursor.com>
- AZ-474 tile-split + YOLO parser + auto-zoom + indicator +
malformed (FT-P-51..55, FT-N-10): 13 fast (6 it.fails for
AC-1..6 + 7 controls) + 2 e2e (test.fail for FT-P-51 +
FT-P-53). The split surface is QUARANTINED today (D11) —
no Split-tile button, no parser, no <TileViewer>; all 6
ACs are documented drift, every it.fails paired with a
control PASS pinning current behaviour.
- AZ-480 prod image + nginx routing + RAM (NFT-RES-LIM-02
/03/08/09/10): 4 new static checks promoted into the
per-commit profile (STC-RES02 500M cap, STC-RES03
Dockerfile final-stage nginx:alpine no Node, STC-RES09
exactly 9 /api/* location blocks, STC-RES10 prefix-strip
on every route). 3 e2e (docker-no-Node probe, runtime
prefix-strip, long-running RAM soak — all gated on docker
availability + image build; RAM soak also on
RUN_LONG_RUNNING=1).
Phase A — One-time baseline setup is now COMPLETE. The
todo/ directory is empty after this batch's archival.
Cumulative review for batches 07-08 is the next autodev
action; after that, Step 7 (Run Tests) auto-chains.
Code review: PASS (0 findings). Fast: 26/26 files, 163
passed / 13 skipped. Static: 29/29 PASS (incl. 4 new
STC-RES* gates).
Co-authored-by: Cursor <cursoragent@cursor.com>
Implements 4 blackbox-test tasks for AZ-455 Phase A baseline:
- AZ-458 SSE lifecycle + bearer rotation: 9 fast tests (8 pass, 1
QUARANTINE for annotation-status); 4 e2e scenarios (gated by suite
stack). Uses tests/helpers/sse-mock.ts with globalThis.EventSource
monkey-patch per AC-3 (no stub of src/api/sse.ts). AC-2 bearer
rotation captured as documented drift via it.fails() — FlightsPage
useEffect deps do not include the token today.
- AZ-467 ProtectedRoute spinner + timeout + RBAC: 9 new fast tests
extending the AZ-457 file (6 pass, 3 QUARANTINE), plus 3 e2e
scenarios. FT-P-32 spinner a11y is it.fails() drift; FT-P-33 timeout
and FT-N-03/05 RBAC redirects are it.skip QUARANTINE (no production
behavior today). Positive control: admin_carol reaches /admin.
- AZ-468 Header flight-dropdown a11y: 6 fast tests (5 pass, 1
QUARANTINE). FT-P-30/31 are it.fails() drift (aria-expanded /
role=listbox / aria-activedescendant currently missing); FT-N-09
is it.skip QUARANTINE (no document keydown handler exists).
- AZ-482 Secrets + banned-libs + AC-N1 anti-criterion: 3 new static
checks (STC-SEC13 legacy integrations, STC-SEC14 concurrent-edit,
STC-SEC1B dist/ OWM key) plus refactor of 4 existing checks
(STC-N2/N4/S13/S6) to read from tests/security/banned-deps.json
via scripts/check-banned-deps.mjs per AZ-482 constraint
("deny-list lives in tests/security/banned-deps.json so additions
are visible in code review"). All 22 static checks PASS.
Totals: 57 fast tests pass + 9 skipped; 22/22 static checks pass.
Self-review verdict PASS_WITH_WARNINGS — all five findings are
documented drifts captured by it.fails() / it.skip QUARANTINE +
control tests. See _docs/03_implementation/batch_03_report.md
for the per-task / per-AC matrix and recommended Phase B follow-up
production tasks (Header a11y; ProtectedRoute spinner/timeout/RBAC;
SSE bearer-rotation reconnect; AnnotationsPage SSE).
Co-authored-by: Cursor <cursoragent@cursor.com>