Files
ui/_docs/02_document/00_discovery.md
T
Oleksandr Bezdieniezhnykh 510df68bcf [AZ-447] autodev Steps 1-4 baseline: docs, tests, refactor specs
Captures the full output of autodev existing-code Phase A through
Step 4 (Code Testability Revision) for the Azaion UI workspace:

- Step 1 Document: _docs/02_document/ (FINAL_report, architecture,
  glossary, components/, modules/, diagrams/, system-flows,
  module-layout) plus _docs/00_problem/ + _docs/01_solution/ +
  _docs/legacy/ + _docs/how_to_test + README.
- Step 2 Architecture Baseline: architecture_compliance_baseline.md.
- Step 3 Test Spec: _docs/02_document/tests/ (environment,
  test-data, blackbox/performance/resilience/security/
  resource-limit tests, traceability-matrix), enum_spec_snapshot,
  expected_results/results_report.md (98 rows), plus the
  run-tests.sh + run-performance-tests.sh runners.
- Step 4 Code Testability Revision: 01-testability-refactoring/
  run dir (list-of-changes C01-C07, deferred_to_refactor,
  analysis/research_findings + refactoring_roadmap) and the 7
  child task specs AZ-448..AZ-454 under _docs/02_tasks/todo/
  plus _dependencies_table.md.
- _docs/_autodev_state.md pins the cursor at Step 4 / refactor
  Phase 4 entry so /autodev resumes cleanly.

Epic AZ-447 (UI testability gates) tracks the 7 child tasks that
will land in subsequent commits.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:38:49 +03:00

29 KiB
Raw Blame History

00 — Codebase Discovery

Step 0 output for /document. Read by Step 1 (per-module docs) to drive processing order, by Step 2 (component assembly) to seed groupings, and by Step 3 (system synthesis) for the tech-stack table.

Scope (chosen at the autodev gate, 2026-05-10):

  • src/ — Azaion UI (React 19 SPA, the live front-end of the suite).
  • mission-planner/ — embedded React 18 + MUI sub-project (port-source for src/features/flights/). Documented as a separate component group.
  • _docs/ already contained user-curated reference content (legacy/wpf-era.md, ui_design/, _autodev_state.md); the document skill writes alongside, not over.

Out of scope: node_modules/, dist/, bun.lock, package-lock.json, .git/, .cursor/, _docs/ (read-only inputs), .idea/, .claude/, .superpowers/, mission-planner/public/ static assets.


1. Workspace at a glance

suite/ui/                              ← Cursor workspace root
├── src/                               ← Azaion UI (React 19, the live SPA)
├── mission-planner/                   ← embedded port-source (React 18 + MUI)
├── _docs/                             ← user-curated + autodev artifacts
│   ├── legacy/wpf-era.md              read-only reference (WPF predecessor)
│   ├── ui_design/                     read-only reference (HTML wireframes)
│   ├── _autodev_state.md              autodev state pointer
│   └── 02_document/                   ← this folder (autodev outputs)
├── .cursor/                           skills/rules/agents
├── .woodpecker/build-arm.yml          CI: arm64 Docker build → Harbor
├── Dockerfile                         multi-stage: bun build → nginx static
├── nginx.conf                         /api/* reverse proxy → suite services
├── index.html                         SPA shell (mounts /src/main.tsx)
├── package.json                       react 19, bun 1.3.11, vite 6, tw 4
├── tsconfig.json                      strict ESM, `@/*` → `src/*`
├── vite.config.ts                     react + tailwind plugin, /api proxy
├── README.md                          repo overview + maturation plan
└── .gitignore                         node_modules, .env.*, playwright-report/

src/ and mission-planner/ are disjoint — no file in one imports from the other. The Vite alias @ → src is defined only in the workspace vite.config.ts; mission-planner/vite.config.ts has no aliases. Each has its own package.json, tsconfig, index.html, and entry point. The production bundle (Dockerfile) builds only the workspace, not mission-planner/.

mission-planner/ ships a (mostly) functional flight-mission UI that the src/features/flights/* files are mechanically translating into the new SPA. Per the workspace README.md, mission-planner/ is not part of the deployed product.

2. Tech stack

2a. Workspace src/ (Azaion UI)

Concern Choice Source
Language TypeScript 5.7 (strict: true) tsconfig.json
UI framework React 19 (react-dom/client) package.json
Bundler Vite 6 package.json, vite.config.ts
Pkg manager Bun 1.3.11 (declared via packageManager) package.json
Styling Tailwind CSS 4 (@tailwindcss/vite) + custom az-* tokens in src/index.css package.json, vite.config.ts
Routing react-router-dom 7 src/App.tsx
i18n i18next + react-i18next (UA / EN) src/i18n/i18n.ts
Map leaflet 1.9 + react-leaflet 5 + leaflet-draw + leaflet-polylinedecorator package.json, src/features/flights/*
Charts chart.js 4 + react-chartjs-2 package.json
DnD @hello-pangea/dnd 18 package.json
File upload react-dropzone package.json
Icon set react-icons package.json
HTTP transport native fetch (custom thin wrapper) src/api/client.ts
Realtime native EventSource (SSE) src/api/sse.ts
State mgmt React Context only — AuthContext, FlightContext. No Redux / Zustand / TanStack Query. src/auth/, src/components/FlightContext.tsx
Tests none (no test framework configured) (verified via Glob)
Build target static bundle → nginx (multi-stage Dockerfile) Dockerfile, nginx.conf
Runtime nginx in container, ARM64 image .woodpecker/build-arm.yml

2b. mission-planner/ (port-source)

Concern Choice Source
Language TypeScript 5.7 (strict: true) mission-planner/tsconfig.app.json
UI framework React 18 mission-planner/package.json
Bundler Vite 6 mission-planner/vite.config.ts
Pkg manager npm (lockfile not committed) (no bun.lock in mission-planner/)
UI library MUI 5 (@mui/material + @mui/icons-material + @emotion/*) mission-planner/package.json
Map leaflet 1.9 + react-leaflet 4.2 + leaflet-draw + leaflet-polylinedecorator mission-planner/package.json
Charts chart.js 4 + react-chartjs-2 mission-planner/package.json
DnD @hello-pangea/dnd 16 mission-planner/package.json
Flags react-world-flags mission-planner/package.json
Tests Jest implied (@testing-library/jest-dom import in setupTests.ts, describe/it/expect in src/test/jsonImport.test.ts) but no Jest dep nor config in package.json — test currently cannot run as-is. mission-planner/package.json, src/setupTests.ts, src/test/jsonImport.test.ts
Env config .env.example declares VITE_SATELLITE_TILE_URL mission-planner/.env.example
Build target not built or shipped by the suite (Dockerfile copies only workspace src/)

3. Configuration & infrastructure files

Path Role
package.json (workspace) scripts: dev, build (tsc -b && vite build), preview. No test.
tsconfig.json strict: true, noUnusedLocals/Parameters: false (lax), paths: {"@/*": ["./src/*"]}.
vite.config.ts @vitejs/plugin-react + @tailwindcss/vite. Dev proxy /api → http://localhost:8080.
index.html <div id="root"></div> + <script type="module" src="/src/main.tsx">. Body class hardcodes bg-[#1e1e1e] text-[#adb5bd].
Dockerfile Stage 1: oven/bun:1.3.11-alpine, bun install --frozen-lockfile, bun run build. Stage 2: nginx:alpine, copies dist/ to /usr/share/nginx/html, exposes 80. ENV AZAION_REVISION=$CI_COMMIT_SHA.
nginx.conf Reverse-proxies 9 /api/<service>/ paths → http://<service>:8080/. Enumerates: annotations, flights, admin, resource, detect, loader, gps-denied-desktop, gps-denied-onboard, autopilot. SPA fallback /index.html. client_max_body_size 500M.
.woodpecker/build-arm.yml Triggers on push to dev/stage/main. Builds + pushes ${REGISTRY_HOST}/azaion/ui:${branch}-arm with OCI labels (revision, created, source).
.gitignore node_modules/, .env.local, .env.development.local, .env.test.local, .env.production.local, package-lock.json, yarn.lock, /test-results/, /playwright-report/, /blob-report/, /playwright/.cache/, /playwright/.auth/. (Playwright entries are aspirational — no Playwright installed.)
.env.example (workspace) absent — README §"Local development" notes this as a testability fix scheduled for Step 4. API base URL is currently hardcoded via the dev proxy + nginx routing.
mission-planner/package.json scripts: dev, build, preview. No test script despite the test file.
mission-planner/tsconfig.app.json exclude: ["src/**/*.test.ts", "src/**/*.test.tsx", "src/setupTests.ts"].
mission-planner/.env.example VITE_SATELLITE_TILE_URL only.
mission-planner/public/manifest.json PWA manifest (vestigial CRA scaffolding).

4. Entry points

Project File Mounts
src/ src/main.tsx <StrictMode><BrowserRouter><App /></BrowserRouter></StrictMode> into #root. Imports ./i18n/i18n for side effects (i18next init) and ./index.css.
src/ src/App.tsx Top-level Routes. /login is public; everything under /* is wrapped in AuthProvider → ProtectedRoute → FlightProvider → Header + nested Routes (/flights, /annotations, /dataset, /admin, /settings, */flights).
mission-planner/ mission-planner/src/main.tsx <StrictMode><LanguageProvider><FlightPlan /></LanguageProvider></StrictMode> into #root. Imports leaflet/dist/leaflet.css and leaflet-draw/dist/leaflet.draw.css.
mission-planner/ mission-planner/src/App.tsx Empty CRA stub — not used by main.tsx. (Vestigial.)

5. Test structure

Project Test file(s) Framework Status
src/ none n/a Zero test coverage. Confirmed via Glob over src/**/*.{test,spec}.*.
mission-planner/ mission-planner/src/test/jsonImport.test.ts Jest (implied — uses describe/it/expect) Cannot run — Jest is not in package.json; only @testing-library/jest-dom is imported in setupTests.ts.
mission-planner/ mission-planner/src/setupTests.ts - One-line import '@testing-library/jest-dom'.

This vacancy is the explicit input for autodev Steps 37 (test-spec, testability revision, decompose tests, implement tests, run tests).

6. Existing documentation

Path Status Owner / used by
README.md (workspace) maintained Single source of truth for repo intent + maturation plan.
_docs/legacy/wpf-era.md reference Captures WPF predecessor (Azaion.Annotator, Azaion.Dataset, Cython sidecars) at commit 22529c2. Authoritative for §10 "What survived into the new world" and §11 "What is intentionally NOT being ported".
_docs/ui_design/README.md reference Authoritative UX spec: pages, breakpoints, panel layouts, keyboard shortcuts, color tokens, affiliation icons, combat readiness, annotation row gradient, video time-window display, confirmation dialogs.
_docs/ui_design/{flights,annotations,dataset_explorer,admin,settings}.html reference HTML wireframes for each page (inherited from WPF UI mockups).
_docs/_autodev_state.md maintained autodev state pointer (this document is being produced under it).
mission-planner/README.md stale CRA boilerplate; does not describe the actual app.
Suite-level ../_docs/ external Suite-wide architecture, schema, deployment topology. Not owned by this workspace; consulted as needed during Step 3.

7. Dependency graph

src/ and mission-planner/ are independent dependency islands. Each is acyclic by inspection (verified by following the import chains in §8 and §9 from leaves outward).

7a. Workspace src/ (intra-repo edges only; React/leaflet/etc. omitted)

graph LR
  main[main.tsx] --> App[App.tsx]
  main --> i18n_init[i18n/i18n.ts]
  i18n_init --> en[i18n/en.json]
  i18n_init --> ua[i18n/ua.json]

  App --> AuthProvider[auth/AuthContext.tsx]
  App --> FlightProvider[components/FlightContext.tsx]
  App --> ProtectedRoute[auth/ProtectedRoute.tsx]
  App --> Header[components/Header.tsx]
  App --> LoginPage[features/login/LoginPage.tsx]
  App --> FlightsPage[features/flights/FlightsPage.tsx]
  App --> AnnotationsPage[features/annotations/AnnotationsPage.tsx]
  App --> DatasetPage[features/dataset/DatasetPage.tsx]
  App --> AdminPage[features/admin/AdminPage.tsx]
  App --> SettingsPage[features/settings/SettingsPage.tsx]

  AuthProvider --> apiClient[api/client.ts]
  AuthProvider --> typesIdx[types/index.ts]
  ProtectedRoute --> AuthProvider
  FlightProvider --> apiClient
  FlightProvider --> typesIdx

  Header --> AuthProvider
  Header --> FlightProvider
  Header --> HelpModal[components/HelpModal.tsx]
  Header --> typesIdx

  sse[api/sse.ts] --> apiClient

  ConfirmDialog[components/ConfirmDialog.tsx]
  DetectionClasses[components/DetectionClasses.tsx] --> apiClient
  DetectionClasses --> classColors[features/annotations/classColors.ts]
  DetectionClasses --> typesIdx

  LoginPage --> AuthProvider

  AdminPage --> apiClient
  AdminPage --> ConfirmDialog
  AdminPage --> typesIdx

  SettingsPage --> apiClient
  SettingsPage --> typesIdx

  classColors
  flightsTypes[features/flights/types.ts]
  flightPlanUtils[features/flights/flightPlanUtils.ts] --> flightsTypes
  mapIcons[features/flights/mapIcons.ts]

  WaypointList[features/flights/WaypointList.tsx] --> flightsTypes
  AltitudeChart[features/flights/AltitudeChart.tsx] --> flightsTypes
  WindEffect[features/flights/WindEffect.tsx] --> flightsTypes
  MiniMap[features/flights/MiniMap.tsx] --> flightsTypes
  MapPoint[features/flights/MapPoint.tsx] --> flightsTypes
  MapPoint --> mapIcons
  DrawControl[features/flights/DrawControl.tsx] --> flightsTypes
  DrawControl --> flightPlanUtils
  AltitudeDialog[features/flights/AltitudeDialog.tsx] --> flightsTypes
  FlightListSidebar[features/flights/FlightListSidebar.tsx] --> typesIdx
  JsonEditorDialog[features/flights/JsonEditorDialog.tsx]

  FlightParamsPanel[features/flights/FlightParamsPanel.tsx] --> WaypointList
  FlightParamsPanel --> AltitudeChart
  FlightParamsPanel --> WindEffect
  FlightParamsPanel --> flightsTypes
  FlightParamsPanel --> typesIdx
  FlightMap[features/flights/FlightMap.tsx] --> DrawControl
  FlightMap --> MapPoint
  FlightMap --> MiniMap
  FlightMap --> mapIcons
  FlightMap --> flightsTypes
  FlightsPage --> FlightProvider
  FlightsPage --> apiClient
  FlightsPage --> sse
  FlightsPage --> ConfirmDialog
  FlightsPage --> FlightListSidebar
  FlightsPage --> FlightParamsPanel
  FlightsPage --> FlightMap
  FlightsPage --> AltitudeDialog
  FlightsPage --> JsonEditorDialog
  FlightsPage --> flightPlanUtils
  FlightsPage --> flightsTypes
  FlightsPage --> typesIdx

  CanvasEditor[features/annotations/CanvasEditor.tsx] --> typesIdx
  CanvasEditor --> classColors
  VideoPlayer[features/annotations/VideoPlayer.tsx] --> typesIdx
  AnnotationsSidebar[features/annotations/AnnotationsSidebar.tsx] --> apiClient
  AnnotationsSidebar --> sse
  AnnotationsSidebar --> classColors
  AnnotationsSidebar --> typesIdx
  MediaList[features/annotations/MediaList.tsx] --> FlightProvider
  MediaList --> apiClient
  MediaList --> useDebounce[hooks/useDebounce.ts]
  MediaList --> ConfirmDialog
  MediaList --> typesIdx
  AnnotationsPage --> useResizablePanel[hooks/useResizablePanel.ts]
  AnnotationsPage --> apiClient
  AnnotationsPage --> MediaList
  AnnotationsPage --> VideoPlayer
  AnnotationsPage --> CanvasEditor
  AnnotationsPage --> AnnotationsSidebar
  AnnotationsPage --> DetectionClasses
  AnnotationsPage --> classColors
  AnnotationsPage --> typesIdx

  DatasetPage --> apiClient
  DatasetPage --> useDebounce
  DatasetPage --> useResizablePanel
  DatasetPage --> FlightProvider
  DatasetPage --> DetectionClasses
  DatasetPage --> ConfirmDialog
  DatasetPage --> CanvasEditor
  DatasetPage --> typesIdx

7b. mission-planner/src/

graph LR
  mp_main[main.tsx] --> flightPlan[flightPlanning/flightPlan.tsx]
  mp_main --> LanguageProvider[flightPlanning/LanguageContext.tsx]

  mp_types[types/index.ts]
  mp_config[config.ts]
  mp_utils[utils.ts]

  translations[constants/translations.ts] --> mp_types
  languages[constants/languages.ts] --> mp_types
  purposes[constants/purposes.ts] --> mp_types
  actionModes[constants/actionModes.ts]
  maptypes[constants/maptypes.ts]
  tileUrls[constants/tileUrls.ts]

  mapIcons[icons/MapIcons.tsx]
  pointIcons[icons/PointIcons.tsx]
  sidebarIcons[icons/SidebarIcons.tsx]
  phoneIcon[icons/PhoneIcon.tsx]

  calcDistance[services/calculateDistance.ts] --> mp_types
  AircraftService[services/AircraftService.ts] --> mp_types
  WeatherService[services/WeatherService.ts] --> mp_types
  calcBattery[services/calculateBatteryUsage.ts] --> AircraftService
  calcBattery --> WeatherService
  calcBattery --> mp_types

  Aircraft[flightPlanning/Aircraft.ts] --> mp_utils
  WindEffect2[flightPlanning/WindEffect.tsx] --> LanguageProvider
  WindEffect2 --> translations
  AltitudeChart2[flightPlanning/AltitudeChart.tsx] --> LanguageProvider
  AltitudeChart2 --> translations
  AltitudeChart2 --> mp_types
  AltitudeDialog2[flightPlanning/AltitudeDialog.tsx] --> LanguageProvider
  AltitudeDialog2 --> mp_config
  AltitudeDialog2 --> translations
  AltitudeDialog2 --> purposes
  DrawControl2[flightPlanning/DrawControl.tsx] --> mp_types
  JsonEditorDialog2[flightPlanning/JsonEditorDialog.tsx] --> LanguageProvider
  JsonEditorDialog2 --> translations
  TotalDistance[flightPlanning/TotalDistance.tsx] --> LanguageProvider
  TotalDistance --> calcDistance
  TotalDistance --> translations
  TotalDistance --> mp_types
  LanguageSwitcher[flightPlanning/LanguageSwitcher.tsx] --> LanguageProvider
  LanguageSwitcher --> languages
  LanguageSwitcher --> translations
  MapPoint2[flightPlanning/MapPoint.tsx] --> LanguageProvider
  MapPoint2 --> purposes
  MapPoint2 --> translations
  MapPoint2 --> pointIcons
  MapPoint2 --> mp_types
  MiniMap2[flightPlanning/MiniMap.tsx] --> MapView2
  MiniMap2 --> maptypes
  MiniMap2 --> tileUrls
  MiniMap2 --> mp_types
  PointsList[flightPlanning/PointsList.tsx] --> AltitudeDialog2
  PointsList --> mp_utils
  PointsList --> LanguageProvider
  PointsList --> translations
  PointsList --> calcBattery
  PointsList --> calcDistance
  PointsList --> mp_types
  MapView2[flightPlanning/MapView.tsx] --> DrawControl2
  MapView2 --> mp_utils
  MapView2 --> AltitudeDialog2
  MapView2 --> LanguageProvider
  MapView2 --> pointIcons
  MapView2 --> translations
  MapView2 --> actionModes
  MapView2 --> MiniMap2
  MapView2 --> MapPoint2
  MapView2 --> mapIcons
  MapView2 --> maptypes
  MapView2 --> purposes
  MapView2 --> tileUrls
  MapView2 --> mp_types
  LeftBoard[flightPlanning/LeftBoard.tsx] --> LanguageProvider
  LeftBoard --> PointsList
  LeftBoard --> AltitudeChart2
  LeftBoard --> TotalDistance
  LeftBoard --> LanguageSwitcher
  LeftBoard --> translations
  LeftBoard --> actionModes
  LeftBoard --> sidebarIcons
  LeftBoard --> mp_config
  LeftBoard --> mp_types
  flightPlan --> mp_utils
  flightPlan --> MapView2
  flightPlan --> AltitudeDialog2
  flightPlan --> JsonEditorDialog2
  flightPlan --> LeftBoard
  flightPlan --> mp_config
  flightPlan --> actionModes
  flightPlan --> AircraftService
  flightPlan --> phoneIcon
  flightPlan --> purposes
  flightPlan --> mp_types

Note

MiniMap2 imports UpdateMapCenter (a named helper) from MapView2, while MapView2 imports MiniMap2 as a child component. They import in opposite directions, which would normally form a dependency cycle, but module-level execution is non-circular because each side only uses the type/handle exposed by the other at call time. Flagged for Step 1 (will document the named export contract precisely) and surfaced in §11 below as a structural caveat.

8. Cross-feature edges in src/ (architectural caveats)

These are edges where a "lower-layer" module imports from a "higher-layer" sibling. Surfaced now so Step 2 (Component Assembly) and Step 2.5 (module-layout.md) can decide whether to formalise them in the layering table or flag them for the architecture baseline scan (Step 2 of autodev).

Edge Direction Comment
components/DetectionClasses.tsxfeatures/annotations/classColors.ts shared ← feature-specific A shared/ component depends on features/annotations/. The shared layer should not know about a specific feature. Likely candidate for refactor: extract classColors.ts into a feature-neutral location (e.g. src/components/detection/classColors.ts) or into a shared/ module.
features/dataset/DatasetPage.tsxfeatures/annotations/CanvasEditor.tsx feature ← sibling feature Cross-feature import, but consistent with the legacy WPF design where Azaion.Dataset reused CanvasEditor from Azaion.Common.Controls (see _docs/legacy/wpf-era.md §5). The proper fix is to lift CanvasEditor out of features/annotations/ into a shared location.
(none observed) back-edge from App to main -

Also: every page calls api/client.ts directly with string-literal URLs (/api/admin/auth/login, /api/flights?..., /api/annotations/settings/user, etc.). There is no per-service API client module. This is the testability issue the workspace README.md calls out for Step 4 — but since it does not yet break compilation or layering, it is recorded here, not blocked.

9. Topological processing order — src/ (40 modules, 8 batches)

Layer = max distance from leaves. Step 1 of /document MUST process modules in this order (leaves first), batched by ~5 with a session-break heuristic between batches.

JSON files (i18n/en.json, i18n/ua.json) and vite-env.d.ts are inputs, not modules — they are not separately documented; their content is summarised inside the consumers (i18n/i18n.ts, the global TS env). Counted modules: 40.

Batch Modules Layer
B1 types/index.ts, hooks/useDebounce.ts, hooks/useResizablePanel.ts, features/flights/types.ts, features/annotations/classColors.ts 0
B2 features/flights/mapIcons.ts, features/flights/flightPlanUtils.ts, api/client.ts, i18n/i18n.ts, components/HelpModal.tsx 01
B3 components/ConfirmDialog.tsx, components/DetectionClasses.tsx, auth/AuthContext.tsx, components/FlightContext.tsx, api/sse.ts 12
B4 auth/ProtectedRoute.tsx, components/Header.tsx, features/login/LoginPage.tsx, features/admin/AdminPage.tsx, features/settings/SettingsPage.tsx 23
B5 features/flights/{WaypointList,AltitudeChart,WindEffect,MiniMap,AltitudeDialog}.tsx 12
B6 features/flights/{MapPoint,DrawControl,FlightListSidebar,JsonEditorDialog,FlightParamsPanel}.tsx 2
B7 features/flights/FlightMap.tsx, features/annotations/{CanvasEditor,VideoPlayer,AnnotationsSidebar,MediaList}.tsx 23
B8 features/flights/FlightsPage.tsx, features/annotations/AnnotationsPage.tsx, features/dataset/DatasetPage.tsx, App.tsx, main.tsx 35

10. Topological processing order — mission-planner/ (37 modules, 8 batches)

Excluded from analysis: vite-env.d.ts, types/leaflet-polylinedecorator.d.ts, types/react-world-flags.d.ts (type shims for external libs), setupTests.ts, App.tsx (vestigial CRA stub — flagged for delete in §11), and index.css, *.css files. The Jest test (src/test/jsonImport.test.ts) is documented inline with flightPlanning/flightPlan.tsx (its target), not as a standalone module. Counted modules: 37.

Batch Modules Layer
MP-B1 types/index.ts, utils.ts, config.ts, constants/{actionModes,maptypes,tileUrls}.ts 0
MP-B2 constants/{translations,languages,purposes}.ts, services/{calculateDistance,AircraftService,WeatherService}.ts 1
MP-B3 services/calculateBatteryUsage.ts, flightPlanning/Aircraft.ts, flightPlanning/LanguageContext.tsx, icons/{MapIcons,PointIcons}.tsx 12
MP-B4 icons/{SidebarIcons,PhoneIcon}.tsx, flightPlanning/{WindEffect,DrawControl,LanguageSwitcher}.tsx 2
MP-B5 flightPlanning/{AltitudeChart,AltitudeDialog,JsonEditorDialog,TotalDistance,MapPoint}.tsx 23
MP-B6 flightPlanning/MapView.tsx (cycle group with MiniMap.tsx), flightPlanning/MiniMap.tsx, flightPlanning/PointsList.tsx 34
MP-B7 flightPlanning/LeftBoard.tsx, flightPlanning/flightPlan.tsx 56
MP-B8 main.tsx, test/jsonImport.test.ts (analysis only — covered by flightPlan.tsx doc) 7

11. Discovery findings to carry forward

The following observations are not documentation gaps; they are inputs for downstream steps. Each lists the step that owns the follow-up.

  1. Workspace src/ has zero tests. → Owned by /test-spec (Step 3 of autodev) and /decompose-tests + /implement (Steps 56).
  2. Hardcoded API URL paths (/api/admin/..., /api/flights/..., /api/annotations/...) inlined throughout features. → Testability fix scheduled by autodev Step 4 (workspace README.md §"Local development" already calls this out).
  3. No .env.example in workspace. → Same — Step 4.
  4. Cross-layer imports (§8): components/DetectionClasses.tsxfeatures/annotations/classColors.ts, features/dataset/DatasetPage.tsxfeatures/annotations/CanvasEditor.tsx. → Surface to autodev Step 2 (Architecture Baseline Scan); the testability refactor (Step 4) may also lift these.
  5. mission-planner/src/test/jsonImport.test.ts cannot run — Jest is not installed and there is no test script. → Out of scope for the live SPA test plan; document in mission-planner/ component spec but do not add Jest just to run this one legacy test.
  6. mission-planner/src/App.tsx is an unused CRA stub; main.tsx mounts FlightPlan directly. → Note in mission-planner/ component spec; deletion candidate but only after the mission-plannersrc/features/flights/ port is complete (out of /document scope).
  7. mission-planner/src/flightPlanning/MapView.tsx ↔ MiniMap.tsx import each other (MiniMap imports the named UpdateMapCenter helper from MapView; MapView imports MiniMap as a JSX child). → Document the contract precisely in Step 1; analyse together as a 2-module group in MP-B6 per the Step 1 cycle-handling rule.
  8. react-i18next is used only in workspace src/; mission-planner/ uses its own LanguageContext + raw translation tables. → Capture the divergence in Step 5 (Solution Extraction) — the port to src/features/flights/ should consume react-i18next instead.
  9. No CI test step in .woodpecker/build-arm.yml — only build + push. → To be added by autodev Step 7 (Run Tests) once the test suite exists.
  10. The body of index.html hardcodes Tailwind arbitrary-value classes for the global background and text color rather than using the az-bg / az-text tokens defined in src/index.css. → Cosmetic; record in the workspace component spec but no action required.

Step 0 status: complete. Proceeding to Step 1 (per-module documentation, batch B1).