docs(map): define Cesium integration plan
This commit is contained in:
@@ -0,0 +1,350 @@
|
||||
# Mission Core Map Page + Cesium integration plan
|
||||
|
||||
Status: proposed for product-owner acceptance, 2026-07-29
|
||||
|
||||
## Objective
|
||||
|
||||
Replace the schematic `Control → Map` placeholder with one production map-first
|
||||
workspace that reuses the canonical NODE.DC Map Page contract, the shared
|
||||
Platform Map Gateway and its NAS TileCache.
|
||||
|
||||
The first delivery proves an operational base map in online, degraded and
|
||||
cache-only conditions. It does not introduce a new product root, copy Engine
|
||||
workflow UI, ship fake subjects or grant command authority.
|
||||
|
||||
## Sources of truth
|
||||
|
||||
- NODE.DC Design Guideline `Map Page 0.1.0`;
|
||||
- `@nodedc/page-patterns` and canonical UI package exports;
|
||||
- `docs/MAP_TEMPLATE.md`;
|
||||
- `docs/FOUNDRY_MAP_CESIUM_CANON.md`;
|
||||
- the read-only Foundry Page Library and inspected editable Map application
|
||||
manifests;
|
||||
- Mission Core product UI, component architecture and surface-extension
|
||||
canons.
|
||||
|
||||
Foundry application source is not a dependency. A reusable runtime component
|
||||
must be published through a reviewed package boundary before Mission Core
|
||||
consumes it.
|
||||
|
||||
## Product-surface decision
|
||||
|
||||
### Operator and job
|
||||
|
||||
A field operator opens `Control → Map` before or during a mission to understand
|
||||
the scanner, mission geometry and selected operational subjects relative to
|
||||
real geography, terrain and buildings. The same workspace must remain useful
|
||||
when provider egress is unavailable but the shared NAS cache is reachable.
|
||||
|
||||
### Primary entity and lifecycle
|
||||
|
||||
The primary entity is a versioned Map view:
|
||||
|
||||
- provider-neutral camera and visual settings;
|
||||
- base-layer visibility and provider readiness;
|
||||
- cache intent;
|
||||
- real geodetic subjects and selection;
|
||||
- persisted Inspector state.
|
||||
|
||||
Cesium viewer instances, provider URLs, credentials and cache files are
|
||||
runtime implementation details and are not product identities.
|
||||
|
||||
### Selected placement
|
||||
|
||||
Keep the existing `world-map` workspace under the current Control/Observation
|
||||
root. Replace only its fake composition with a full map-first stage.
|
||||
|
||||
Rejected alternatives:
|
||||
|
||||
- a new product root: the operator job already belongs to Control and has one
|
||||
admitted workspace;
|
||||
- a modal or floating map: the map is the primary task, not auxiliary content;
|
||||
- a Foundry iframe: it duplicates shell/navigation, breaks same-origin product
|
||||
ownership and couples Mission Core to Foundry session state;
|
||||
- reuse of the current generic `MapWorkspace` branch for both `world-map` and
|
||||
`Missions → Routes`: the two workspaces have different lifecycle and
|
||||
authority, so the mission-route editor remains separate.
|
||||
|
||||
This is novelty class A for the existing workspace composition, plus a shared
|
||||
runtime-package admission gate for the generic Cesium adapter.
|
||||
|
||||
## Resulting composition
|
||||
|
||||
The default `Control → Map` surface is the map. Remove from this workspace:
|
||||
|
||||
- the schematic SVG route and contour drawing;
|
||||
- the static right-side `Рабочая композиция` card;
|
||||
- the product-facing feature inventory and `Картографический модуль` roadmap
|
||||
copy;
|
||||
- all fake routes, targets, geozones, heights and readiness statuses.
|
||||
|
||||
Retain canonical Map Page interactions:
|
||||
|
||||
- draggable Map Inspector;
|
||||
- compact Layers overlay;
|
||||
- central Map Toolbar;
|
||||
- map expand/restore behavior owned by the existing workspace shell;
|
||||
- provider-neutral selection and elevated target presentation when real data
|
||||
exists.
|
||||
|
||||
The Layers overlay contains only imagery, terrain, 3D buildings, grid and
|
||||
TileCache health in the first slice. Engine/Data Product layer menus are not
|
||||
copied. Future Mission Core layers appear only after a real typed binding
|
||||
exists.
|
||||
|
||||
## Settings retained from Foundry
|
||||
|
||||
The Inspector keeps:
|
||||
|
||||
1. Underlay and terrain.
|
||||
2. Atmosphere and lighting.
|
||||
3. 3D buildings.
|
||||
4. Mission Core target presentation.
|
||||
5. Grid and LOD.
|
||||
6. Camera animation.
|
||||
7. TileCache intent and safe health.
|
||||
8. Selected entity details when a real selection exists.
|
||||
|
||||
Do not copy:
|
||||
|
||||
- `Классы состояния`;
|
||||
- `HGeoZone`;
|
||||
- `Метро`;
|
||||
- `Вокзалы`;
|
||||
- `Станции РЖД`;
|
||||
- Foundry fleet bindings, provider-specific subjects or Engine execution
|
||||
controls.
|
||||
|
||||
Canonical controls are `Inspector`, `ControlRow`, `InspectorSelectField`,
|
||||
`Checker`, `RangeControl`, `ColorField`, `IconButton`, `Icon`,
|
||||
`MapGlassSurface`, `Toolbar` and `WorkspaceWindow`. Mission Core does not
|
||||
reimplement their geometry or interaction states.
|
||||
|
||||
## Runtime and dependency boundaries
|
||||
|
||||
```text
|
||||
Mission Core browser on :8000
|
||||
│ same-origin /api/v1/map/*
|
||||
▼
|
||||
Mission Core Map BFF
|
||||
│ server-configured internal Gateway route
|
||||
│ trusted server-side subject, no provider credential
|
||||
▼
|
||||
Shared Platform Map Gateway
|
||||
├─ warm hit → shared NAS live TileCache
|
||||
└─ cold miss / explicit refresh → approved platform egress → provider
|
||||
```
|
||||
|
||||
The browser never connects directly to Cesium, Map Gateway, AMD Proxy or a NAS
|
||||
address. The Gateway address is server configuration and is never hard-coded in
|
||||
the frontend, map layout or router settings.
|
||||
|
||||
Mission Core reuses the existing shared cache. It must not create a local
|
||||
browser cache, per-application TileCache, Docker volume or a second Gateway.
|
||||
|
||||
### Shared renderer gate
|
||||
|
||||
`@nodedc/page-patterns` already publishes the runtime-neutral Map Page
|
||||
definition, but the Cesium adapter is not a published package. Production reuse
|
||||
requires a shared reviewed package for:
|
||||
|
||||
- provider startup and independent imagery/terrain/buildings readiness;
|
||||
- Gateway-proxied Cesium resource creation;
|
||||
- render-loop recovery;
|
||||
- provider-neutral scene/selection adapters;
|
||||
- elevated target and label presentation;
|
||||
- camera and cache-intent application.
|
||||
|
||||
Foundry and Mission Core must consume the same package revision. Copying the
|
||||
Foundry application renderer into Mission Core is rejected. Cesium remains a
|
||||
lazy chunk loaded only when the map workspace opens.
|
||||
|
||||
## Credential and control-plane decision
|
||||
|
||||
Mission Core does not need to receive a Cesium token to render the map. The
|
||||
existing platform token remains owned by Platform Map Gateway, and Mission Core
|
||||
uses it only after Gateway reports a configured/verified state. The current
|
||||
network check did not independently verify that state.
|
||||
|
||||
The proposed `API и ключи` settings section is a write-only Platform
|
||||
control-plane client:
|
||||
|
||||
1. The input is a password field, exists only in transient form state and is
|
||||
cleared immediately after submit or cancel.
|
||||
2. Browser submits the candidate through a same-origin authenticated request.
|
||||
3. Mission Core revalidates an explicit admin authority.
|
||||
4. The backend forwards the candidate through the canonical signed Gateway
|
||||
admin route.
|
||||
5. Gateway verifies assets `1`, `2` and `96188` before atomic replacement.
|
||||
6. The response contains only `configured`, verification state, update time and
|
||||
actor; the token is never returned.
|
||||
7. A failed candidate preserves the previous working token.
|
||||
|
||||
The token is not stored in Mission Core environment settings, `.env`, browser
|
||||
storage, logs, Git or Ops. The authoritative private file remains owned by
|
||||
Platform Map Gateway.
|
||||
|
||||
Mission Core currently has no Launcher/Authentik role boundary. Therefore the
|
||||
token-entry mutation is blocked until an authenticated admin control plane is
|
||||
present. A hidden local button or loopback-only server is not sufficient
|
||||
production authorization. Data-plane map work can proceed independently once
|
||||
the existing Gateway is reachable and reports a configured state.
|
||||
|
||||
## Map state contract
|
||||
|
||||
Add a versioned Mission Core map document outside operator environment media,
|
||||
for example `missioncore.map-view/v1`, with optimistic revision:
|
||||
|
||||
- camera: longitude, latitude, height, heading, pitch and roll;
|
||||
- provider-neutral visual settings compatible with Map Page;
|
||||
- map height;
|
||||
- `inspectorOpenSections`;
|
||||
- cache intent (`enabled`, `noOverwrite`), never server-level cache mode;
|
||||
- selected stable subject id, or `null`;
|
||||
- layer visibility;
|
||||
- no credentials, upstream URLs, cache objects or transient Cesium ids.
|
||||
|
||||
Resolution order:
|
||||
|
||||
```text
|
||||
canonical Map Page defaults
|
||||
→ Mission Core persisted map view
|
||||
→ transient operator changes
|
||||
→ bounded runtime-only recovery overrides
|
||||
```
|
||||
|
||||
Provider root failures are independent. Imagery failure must not blank terrain;
|
||||
buildings failure must not stop the rest of the scene.
|
||||
|
||||
## Target and selection contract
|
||||
|
||||
The renderer supports canonical `elevated-spike` targets and
|
||||
`map.moving_object` / `map.place_target` semantics from the start, but the
|
||||
product renders no target without real geodetic evidence.
|
||||
|
||||
The current K1 acquisition contract exposes local `map_enu` trajectory and
|
||||
`gnss_mode=none`; it does not expose a proved longitude/latitude/altitude
|
||||
anchor. Local scan coordinates must not be plotted as world coordinates.
|
||||
|
||||
A real Mission Core map subject requires:
|
||||
|
||||
- stable `sourceId`;
|
||||
- semantic type;
|
||||
- longitude and latitude;
|
||||
- optional altitude with an explicit height datum;
|
||||
- observed/received timestamps;
|
||||
- availability and motion states derived from real contracts;
|
||||
- optional heading and trace;
|
||||
- provenance linking the position to a session/device/mission.
|
||||
|
||||
Until that contract exists, the basemap remains valid with an honest empty
|
||||
subject state and the selected-entity section remains absent.
|
||||
|
||||
## State grammar
|
||||
|
||||
The UI must distinguish:
|
||||
|
||||
- `loading`: runtime config and providers are being prepared;
|
||||
- `ready`: selected providers are available;
|
||||
- `degraded`: one or more providers failed while the scene remains useful;
|
||||
- `empty`: basemap works but no real Mission Core subjects are bound;
|
||||
- `offline-cache`: Gateway is reachable and the requested objects are served
|
||||
without egress;
|
||||
- `cache-miss`: requested offline object is absent;
|
||||
- `gateway-unavailable`: Mission Core cannot reach the shared Gateway;
|
||||
- `render-error`: browser/GPU/Cesium failure after one bounded recovery;
|
||||
- `stale-health`: last-known-good cache statistics retained after a failed
|
||||
poll.
|
||||
|
||||
Safe error codes remain visible to diagnostics. The UI must not collapse all
|
||||
layers into a generic `502`, erase last-known-good cache state or perform
|
||||
unbounded reconnect loops.
|
||||
|
||||
## Implementation slices
|
||||
|
||||
### M0 — shared contract and reachability gate
|
||||
|
||||
- approve the shared Cesium adapter package boundary;
|
||||
- pin `Map Page 0.1.0`, Cesium `1.143.0` and Gateway route contracts;
|
||||
- configure the Mission Core backend Gateway endpoint without hard-coded LAN
|
||||
addresses;
|
||||
- define a reviewed server-owned subject policy for the loopback-only
|
||||
single-operator contour; require Launcher/Authentik identity before any
|
||||
non-loopback or multi-user deployment;
|
||||
- prove safe runtime-config and health reads from the intended field LAN;
|
||||
- add credential-leak and route-allowlist tests.
|
||||
|
||||
### M1 — Mission Core Map BFF
|
||||
|
||||
- add bounded streaming GET/HEAD proxy routes for runtime config, asset
|
||||
endpoints, cache resources and safe health;
|
||||
- preserve Range, ETag, conditional headers, content type, abort and body
|
||||
progress semantics;
|
||||
- reject arbitrary target URLs and browser-supplied trusted identity;
|
||||
- implement independent timeouts and safe error mapping;
|
||||
- do not implement token rotation yet.
|
||||
|
||||
### M2 — real map-first workspace
|
||||
|
||||
- add isolated `core/map`, `components/map`, `workspaces/map` and
|
||||
`styles/map.css` modules;
|
||||
- consume `@nodedc/page-patterns`;
|
||||
- lazy-load the shared Cesium adapter;
|
||||
- replace the fake `world-map` branch only;
|
||||
- remove the old map placeholder CSS from generic `workspaces.css`;
|
||||
- keep `Missions → Routes` outside this change.
|
||||
|
||||
### M3 — Inspector, Layers and persisted view
|
||||
|
||||
- connect canonical Inspector controls to the versioned map view;
|
||||
- add base provider visibility/readiness and cache health to Layers;
|
||||
- persist camera, settings, cache intent and Inspector sections;
|
||||
- implement bounded renderer recreation for explicit viewport refresh;
|
||||
- keep provider credits available for any non-sandbox release.
|
||||
|
||||
### M4 — secure API/key control plane
|
||||
|
||||
- add authenticated Mission Core admin authority;
|
||||
- add `API и ключи` to the existing `FeatureSettingsWindow`;
|
||||
- implement write-only candidate rotation through the canonical Gateway admin
|
||||
route;
|
||||
- prove no secret appears in API responses, bundle, storage, logs or tests.
|
||||
|
||||
### M5 — real Mission Core targets
|
||||
|
||||
- admit a geodetic position/mission-target contract;
|
||||
- adapt real subjects to the shared target presentation;
|
||||
- implement selection and selected-entity details;
|
||||
- add traces/routes only when their coordinate frame and authority are proved.
|
||||
|
||||
### M6 — operational acceptance
|
||||
|
||||
- cold online viewport streams while the Gateway commits objects;
|
||||
- repeated viewport increases cache hits without repeating egress for the same
|
||||
keys;
|
||||
- provider egress/VPN loss does not break a warm viewport;
|
||||
- uncached offline area produces a precise cache-miss state;
|
||||
- explicit refresh failure preserves the previous cached object;
|
||||
- reload restores camera, layers and Inspector state;
|
||||
- each provider can fail independently;
|
||||
- no fake entities survive scene changes;
|
||||
- keyboard, Escape, normal/expanded map and responsive behavior pass browser
|
||||
QA;
|
||||
- all heavy validation remains sequential on the 18 GB Mac and the canonical
|
||||
service stays on port `8000`.
|
||||
|
||||
## Current blockers and evidence
|
||||
|
||||
1. The Cesium adapter is not currently available through a published shared
|
||||
package; exact code reuse is blocked until that boundary exists.
|
||||
2. Mission Core lacks authenticated admin authority, so platform token rotation
|
||||
cannot be exposed safely yet.
|
||||
3. K1 currently has no admitted geodetic anchor, so live scanner targets are a
|
||||
later data-contract slice.
|
||||
4. From the current Mac network, direct safe probes to the expected private
|
||||
Synology Map Gateway/Platform/AMD health endpoints timed out. End-to-end
|
||||
acceptance requires the intended LAN route; no address will be hard-coded to
|
||||
hide this condition.
|
||||
|
||||
None of these blockers requires a new product window, Engine embedding,
|
||||
Ontology mutation, fake target or duplicate TileCache.
|
||||
Reference in New Issue
Block a user