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>
29 KiB
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 forsrc/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 3–7 (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
—
MiniMap2importsUpdateMapCenter(a named helper) fromMapView2, whileMapView2importsMiniMap2as 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.tsx → features/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.tsx → features/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) andvite-env.d.tsare 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 |
0–1 |
| B3 | components/ConfirmDialog.tsx, components/DetectionClasses.tsx, auth/AuthContext.tsx, components/FlightContext.tsx, api/sse.ts |
1–2 |
| B4 | auth/ProtectedRoute.tsx, components/Header.tsx, features/login/LoginPage.tsx, features/admin/AdminPage.tsx, features/settings/SettingsPage.tsx |
2–3 |
| B5 | features/flights/{WaypointList,AltitudeChart,WindEffect,MiniMap,AltitudeDialog}.tsx |
1–2 |
| B6 | features/flights/{MapPoint,DrawControl,FlightListSidebar,JsonEditorDialog,FlightParamsPanel}.tsx |
2 |
| B7 | features/flights/FlightMap.tsx, features/annotations/{CanvasEditor,VideoPlayer,AnnotationsSidebar,MediaList}.tsx |
2–3 |
| B8 | features/flights/FlightsPage.tsx, features/annotations/AnnotationsPage.tsx, features/dataset/DatasetPage.tsx, App.tsx, main.tsx |
3–5 |
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 |
1–2 |
| MP-B4 | icons/{SidebarIcons,PhoneIcon}.tsx, flightPlanning/{WindEffect,DrawControl,LanguageSwitcher}.tsx |
2 |
| MP-B5 | flightPlanning/{AltitudeChart,AltitudeDialog,JsonEditorDialog,TotalDistance,MapPoint}.tsx |
2–3 |
| MP-B6 | flightPlanning/MapView.tsx (cycle group with MiniMap.tsx), flightPlanning/MiniMap.tsx, flightPlanning/PointsList.tsx |
3–4 |
| MP-B7 | flightPlanning/LeftBoard.tsx, flightPlanning/flightPlan.tsx |
5–6 |
| 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.
- Workspace
src/has zero tests. → Owned by/test-spec(Step 3 of autodev) and/decompose-tests+/implement(Steps 5–6). - Hardcoded API URL paths (
/api/admin/...,/api/flights/...,/api/annotations/...) inlined throughout features. → Testability fix scheduled by autodev Step 4 (workspaceREADME.md§"Local development" already calls this out). - No
.env.examplein workspace. → Same — Step 4. - Cross-layer imports (§8):
components/DetectionClasses.tsx→features/annotations/classColors.ts,features/dataset/DatasetPage.tsx→features/annotations/CanvasEditor.tsx. → Surface to autodev Step 2 (Architecture Baseline Scan); the testability refactor (Step 4) may also lift these. mission-planner/src/test/jsonImport.test.tscannot run — Jest is not installed and there is no test script. → Out of scope for the live SPA test plan; document inmission-planner/component spec but do not add Jest just to run this one legacy test.mission-planner/src/App.tsxis an unused CRA stub;main.tsxmountsFlightPlandirectly. → Note inmission-planner/component spec; deletion candidate but only after themission-planner→src/features/flights/port is complete (out of/documentscope).mission-planner/src/flightPlanning/MapView.tsx ↔ MiniMap.tsximport each other (MiniMapimports the namedUpdateMapCenterhelper fromMapView;MapViewimportsMiniMapas 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.react-i18nextis used only in workspacesrc/;mission-planner/uses its ownLanguageContext+ raw translation tables. → Capture the divergence in Step 5 (Solution Extraction) — the port tosrc/features/flights/should consumereact-i18nextinstead.- 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. - The body of
index.htmlhardcodes Tailwind arbitrary-value classes for the global background and text color rather than using theaz-bg/az-texttokens defined insrc/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).