mirror of
https://github.com/azaion/ui.git
synced 2026-06-21 22:51:11 +00:00
b016fd8207
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>
124 lines
11 KiB
Markdown
124 lines
11 KiB
Markdown
# Module group: `mission-planner/`
|
|
|
|
> **Single consolidated doc** for the entire `mission-planner/` sub-project (37 modules across `services/`, `flightPlanning/`, `icons/`, `constants/`, `types/`, `utils.ts`, `config.ts`, `main.tsx`, `App.tsx`).
|
|
>
|
|
> **Why a single doc**: `mission-planner/` is **port-source, not deployed product** (per workspace `README.md` + `00_discovery.md §1`). The Dockerfile builds only the workspace `src/`. Documenting each of the 37 files at the same fidelity as the production SPA would burn context for code that exists only as a reference for the React-19 port. Future deletion of `mission-planner/` is a Step 8 / autodev follow-up once `src/features/flights/` reaches feature-parity.
|
|
|
|
## Role in the codebase
|
|
|
|
| Aspect | Status |
|
|
|---|---|
|
|
| Purpose | Reference implementation of the flight-mission planner UI being mechanically translated into `src/features/flights/`. Stand-alone CRA-flavoured Vite + React 18 + MUI 5 app. |
|
|
| Build | Has its own `vite.config.ts`, `tsconfig`, `index.html`, `package.json`. No alias path. |
|
|
| Deployment | None — workspace `Dockerfile` does NOT build it; `nginx.conf` does NOT serve it. |
|
|
| Tests | `src/test/jsonImport.test.ts` uses `describe/it/expect` style; **Jest is not installed** and there is no `test` script — the test cannot run as-is. Documented gap, no fix planned (out of scope per `00_discovery.md §11.5`). |
|
|
| Lifecycle | Will be deleted once `src/features/flights/` covers all mission-planner features. Not before. |
|
|
|
|
## Directory map
|
|
|
|
```
|
|
mission-planner/src/
|
|
├── main.tsx → mounts <LanguageProvider><FlightPlan /> into #root
|
|
├── App.tsx UNUSED — empty CRA stub; main.tsx mounts FlightPlan directly
|
|
├── config.ts COORDINATE_PRECISION, downang, upang, defaults
|
|
├── utils.ts newGuid (Math.random v4)
|
|
├── types/index.ts FlightPoint, CalculatedPointInfo, MapRectangle, AircraftParams,
|
|
│ WeatherData, MovingPointInfo, ActionMode, MapType, large
|
|
│ TranslationStrings interface tree
|
|
├── constants/
|
|
│ ├── actionModes.ts points / workArea / prohibitedArea
|
|
│ ├── maptypes.ts classic / satellite
|
|
│ ├── tileUrls.ts OSM + Esri ArcGIS tile URLs
|
|
│ ├── translations.ts English + Ukrainian dictionaries (raw, no i18next)
|
|
│ ├── languages.ts ISO codes + flag codes for LanguageSwitcher
|
|
│ └── purposes.ts tank, artillery
|
|
├── services/
|
|
│ ├── calculateDistance.ts Haversine + plane climb/cruise/descend
|
|
│ ├── AircraftService.ts mockGetAirplaneParams (returns hardcoded fixed-wing)
|
|
│ ├── WeatherService.ts OpenWeatherMap fetch (env-vars: VITE_OWM_API_KEY + VITE_OWM_BASE_URL; fail-soft `null` when key unset, AZ-499)
|
|
│ └── calculateBatteryUsage.ts Drag + thrust lookup; same algorithm as src/features/flights/flightPlanUtils.calculateBatteryPercentUsed
|
|
├── icons/
|
|
│ ├── MapIcons.tsx Leaflet icon factories
|
|
│ ├── PointIcons.tsx Per-purpose marker icons
|
|
│ ├── SidebarIcons.tsx MUI-styled side-panel SVGs
|
|
│ └── PhoneIcon.tsx Rotate-phone overlay (mobile orientation hint)
|
|
└── flightPlanning/
|
|
├── flightPlan.tsx Top-level page (369 lines) — owns state, dialogs, JSON I/O
|
|
├── MapView.tsx MapContainer + draw handlers + click-to-add (414 lines)
|
|
├── MiniMap.tsx Floating thumbnail; cyclic edge with MapView
|
|
├── MapPoint.tsx Draggable waypoint + popup
|
|
├── DrawControl.tsx Rectangle draw tool
|
|
├── PointsList.tsx Reorderable waypoint list
|
|
├── LeftBoard.tsx Side panel composing list + chart + totals + lang switcher
|
|
├── AltitudeChart.tsx Chart.js altitude visualizer
|
|
├── AltitudeDialog.tsx Add/Edit waypoint modal
|
|
├── JsonEditorDialog.tsx Edit-as-JSON modal
|
|
├── TotalDistance.tsx Total distance + time + battery readout
|
|
├── LanguageContext.tsx React Context for current locale (NOT i18next)
|
|
├── LanguageSwitcher.tsx Locale dropdown
|
|
├── WindEffect.tsx Wind heading / speed inputs + arrow preview
|
|
└── Aircraft.ts Aircraft helper (filename casing odd — TypeScript file, capitalised)
|
|
```
|
|
|
|
## Mapping `mission-planner/` ↔ `src/features/flights/`
|
|
|
|
The React 19 port translates module-for-module wherever possible. Status as of this commit:
|
|
|
|
| `mission-planner/src/...` | Ported to `src/features/flights/...` | Status |
|
|
|---|---|---|
|
|
| `flightPlanning/flightPlan.tsx` | `FlightsPage.tsx` | Ported with backend wiring (Flights API + SSE). MP-side has none. |
|
|
| `flightPlanning/MapView.tsx` | `FlightMap.tsx` | Ported. |
|
|
| `flightPlanning/MiniMap.tsx` | `MiniMap.tsx` | Ported. |
|
|
| `flightPlanning/MapPoint.tsx` | `MapPoint.tsx` | Ported. |
|
|
| `flightPlanning/DrawControl.tsx` | `DrawControl.tsx` | Ported. |
|
|
| `flightPlanning/PointsList.tsx` | `WaypointList.tsx` | Ported (renamed for parity with backend `Waypoint` entity). |
|
|
| `flightPlanning/LeftBoard.tsx` | `FlightParamsPanel.tsx` | Partial — MP-side hosts `LanguageSwitcher`, the SPA delegates language to global `Header` + `react-i18next`. |
|
|
| `flightPlanning/AltitudeChart.tsx` | `AltitudeChart.tsx` | Ported. |
|
|
| `flightPlanning/AltitudeDialog.tsx` | `AltitudeDialog.tsx` | Ported (file name kept; should be `WaypointDialog`). |
|
|
| `flightPlanning/JsonEditorDialog.tsx` | `JsonEditorDialog.tsx` | Ported. |
|
|
| `flightPlanning/WindEffect.tsx` | `WindEffect.tsx` | Ported. |
|
|
| `flightPlanning/TotalDistance.tsx` | (inlined into `FlightParamsPanel`) | Ported as a `<div>` strip in the params panel; no separate module. |
|
|
| `flightPlanning/LanguageContext.tsx` + `LanguageSwitcher.tsx` | (replaced by `react-i18next`) | Not ported as such — language is global via i18next. |
|
|
| `flightPlanning/Aircraft.ts` | (no equivalent) | Aircraft is server-side; the SPA fetches `/api/flights/aircrafts`. |
|
|
| `services/calculateDistance.ts` | `flightPlanUtils.calculateDistance` | Ported. |
|
|
| `services/calculateBatteryUsage.ts` | `flightPlanUtils.calculateBatteryPercentUsed` + `calculateAllPoints` | Ported. |
|
|
| `services/WeatherService.ts` | `flightPlanUtils.getWeatherData` | Ported. Env-vars `VITE_OWM_API_KEY` + `VITE_OWM_BASE_URL` since AZ-499 (mirrors AZ-448 / AZ-449); same fail-soft `null` contract. |
|
|
| `services/AircraftService.ts` | `flightPlanUtils.getMockAircraftParams` (mock only) | Real fetch is `/api/flights/aircrafts` in `FlightsPage`. |
|
|
| `constants/translations.ts` + `LanguageContext.tsx` | `src/i18n/{en,ua}.json` + `i18n/i18n.ts` | Migrated to i18next. |
|
|
| `constants/{actionModes,maptypes,tileUrls,purposes,languages}.ts` | `features/flights/types.ts` (`PURPOSES`, `TILE_URL`, `ActionMode`) | Consolidated into one file. `TILE_URL` collapsed from the prior classic/satellite pair to a single self-hosted satellite URL by AZ-498. |
|
|
| `icons/{MapIcons,PointIcons,SidebarIcons,PhoneIcon}.tsx` | `features/flights/mapIcons.ts` | Only the marker icons survived; SidebarIcons + PhoneIcon dropped (no rotate-phone overlay in the SPA today). |
|
|
| `utils.ts` (`newGuid`) | `flightPlanUtils.newGuid` | Ported. |
|
|
| `config.ts` | `features/flights/types.COORDINATE_PRECISION` | Single constant migrated. |
|
|
| `App.tsx` | (none) | Was already an unused CRA stub in MP; nothing to port. |
|
|
| `main.tsx` | (none) | Replaced by the workspace `src/main.tsx`. |
|
|
| `setupTests.ts`, `test/jsonImport.test.ts` | (none) | Cannot run; not migrated. |
|
|
|
|
## Things still in MP that are NOT in the SPA port
|
|
|
|
- **Rotate-phone overlay** (`icons/PhoneIcon.tsx`): MP shows a rotate-phone hint when held in portrait. The SPA does not.
|
|
- **Per-purpose marker icons** (`icons/PointIcons.tsx`): MP draws a different marker per `meta` purpose. The SPA uses three colour-coded icons (start / mid / end).
|
|
- **`Aircraft.ts` helper class**: never used in the SPA — aircraft state is fetched and treated as a plain DTO.
|
|
- **OpenWeather call directly from `WeatherService.ts`**: same flaw as the SPA port (no proxy). Hardcoded key fixed by AZ-499 (env-vars + fail-soft); proxy story still owned by the broader F1 mission-planner deduplication track.
|
|
- **MUI 5**: MP uses MUI for dialogs / inputs / icons. The SPA replaced everything with hand-rolled Tailwind components matching `_docs/ui_design/README.md`. MUI is not a dep of the workspace.
|
|
|
|
## Findings carried into Step 4 / 6 / 8
|
|
|
|
1. **`mission-planner/src/App.tsx` is an unused CRA stub** — `main.tsx` mounts `FlightPlan` directly. Deletion candidate but only after the port is complete (per `00_discovery.md §11.6`). Step 8.
|
|
2. **`mission-planner/src/test/jsonImport.test.ts` cannot run** (Jest not installed; no test script). Out of scope. Step 8 deletion or migration to the suite-level e2e harness.
|
|
3. **`flightPlanning/MapView.tsx ↔ MiniMap.tsx`** import each other (`MiniMap` imports the *named* `UpdateMapCenter` helper from `MapView`; `MapView` imports `MiniMap` as a JSX child). Module-level execution is non-circular because each side only uses the type/handle exposed at call time. Ported to `src/features/flights/FlightMap.tsx + MiniMap.tsx` without the cycle.
|
|
4. **MP uses raw translation tables** keyed by ISO code, not i18next. The SPA correctly migrated to `react-i18next`; the legacy Russian-language references (if any in `translations.ts`) are out of scope.
|
|
5. **`mission-planner/.env.example`** declares `VITE_SATELLITE_TILE_URL` — same env-driven pattern that the workspace `src/` should adopt for the Esri tile URL (currently hardcoded). Carry idea to Step 4.
|
|
6. **`mission-planner/package.json`** lockfile is uncommitted (`bun.lock` is workspace-only; MP uses npm without a committed lock). Reproducibility risk if anyone runs MP. Step 8 — when MP is deleted this becomes moot.
|
|
7. **Dependency divergence**: MP uses `react-leaflet` 4.2 vs workspace 5.x; `@hello-pangea/dnd` 16 vs 18; `chart.js` shared. None of this affects the deployed bundle. Step 8 — delete MP.
|
|
|
|
## Tests
|
|
|
|
The single `jsonImport.test.ts` cannot run. None of the other 36 modules have tests.
|
|
|
|
## Cross-doc references
|
|
|
|
- `_docs/02_document/00_discovery.md §1, §2b, §7b, §10, §11` — discovery-level facts about MP.
|
|
- Workspace `README.md` — declares MP as not-deployed.
|
|
- `mission-planner/README.md` — stale CRA boilerplate, do not trust.
|
|
- The 14 `src/features/flights/` modules — see consolidated `src__features__flights.md`.
|