fix(map): complete live Cesium provider path

This commit is contained in:
DCCONSTRUCTIONS
2026-07-29 17:25:07 +03:00
parent f2a4dfe863
commit 5a06194962
3 changed files with 66 additions and 16 deletions
@@ -1,6 +1,7 @@
# Mission Core Map Page + Cesium integration plan
Status: proposed for product-owner acceptance, 2026-07-29
Status: M0M3 implemented for the local operator contour; operational
acceptance in progress, 2026-07-29
## Objective
@@ -144,9 +145,9 @@ 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:
`@nodedc/page-patterns` publishes the runtime-neutral Map Page definition and
`@nodedc/map-cesium-react@0.1.0` now owns the shared Cesium adapter consumed by
Mission Core. The package boundary covers:
- provider startup and independent imagery/terrain/buildings readiness;
- Gateway-proxied Cesium resource creation;
@@ -155,16 +156,17 @@ requires a shared reviewed package for:
- 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.
Foundry and Mission Core must remain on the same reviewed package revision.
Copying the Foundry application renderer into Mission Core remains rejected.
Cesium is 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.
uses it only after Gateway reports a configured/verified state. The connected
local Gateway reports `ionConfigured=true` and serves the canonical assets
without exposing credentials.
The proposed `API и ключи` settings section is a write-only Platform
control-plane client:
@@ -335,15 +337,23 @@ unbounded reconnect loops.
## 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
1. The shared Cesium adapter, Mission Core BFF and real map-first workspace are
admitted. Browser acceptance on `127.0.0.1:8000` reports `Карта готова`;
imagery, terrain and 3D buildings each report `Готов`, with no blocking map
error.
2. The connected Gateway is configured with assets `1`, `2` and `96188`.
Rendering the acceptance viewport increased the persistent live-cache count
from 3270 to 3282 without a browser credential or direct provider route.
3. 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
4. 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
5. 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
NAS/cache-only acceptance still requires the intended LAN route. The
currently connected development Gateway uses a persistent local Docker
volume, so it proves the browser/BFF/Gateway/provider contract but not the
final Synology failover path. No address is hard-coded in frontend state to
hide this condition.
None of these blockers requires a new product window, Engine embedding,
+6 -1
View File
@@ -22,6 +22,7 @@ ALLOWED_ION_ASSET_IDS: Final = frozenset({1, 2, 96188})
SAFE_ERROR_CODE = re.compile(r"^[a-z][a-z0-9_]{0,95}$")
MAX_JSON_RESPONSE_BYTES: Final = 1024 * 1024
MAX_CACHE_TARGET_LENGTH: Final = 8192
BING_GATEWAY_KEY_MARKER: Final = "nodedc-gateway"
REQUEST_HEADER_ALLOWLIST: Final = frozenset(
{
@@ -325,7 +326,11 @@ def _validate_cache_target(target_url: str) -> None:
)
if any(
key.lower() in CREDENTIAL_QUERY_KEYS
for key, _ in parse_qsl(parsed.query, keep_blank_values=True)
and not (
key.lower() == "key"
and value == BING_GATEWAY_KEY_MARKER
)
for key, value in parse_qsl(parsed.query, keep_blank_values=True)
):
raise HTTPException(
status_code=422,
+35
View File
@@ -250,6 +250,41 @@ def test_cache_rejects_credentials_non_https_and_non_loopback_clients() -> None:
assert not requests
def test_cache_accepts_only_the_public_bing_gateway_key_marker() -> None:
service, requests = _service(
lambda request: httpx.Response(
200,
headers={"content-type": "application/json"},
content=b"{}",
)
)
accepted = asyncio.run(
service.proxy_cache(
_request("/api/v1/map/gateway/cache"),
target_url=(
"https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial"
"?key=nodedc-gateway"
),
)
)
assert isinstance(accepted, StreamingResponse)
assert requests[0].url.params["url"].endswith("key=nodedc-gateway")
with pytest.raises(HTTPException) as exc_info:
asyncio.run(
service.proxy_cache(
_request("/api/v1/map/gateway/cache"),
target_url=(
"https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial"
"?key=browser-secret"
),
)
)
assert exc_info.value.status_code == 422
def test_asset_route_is_a_fixed_allowlist() -> None:
service, requests = _service(
lambda request: httpx.Response(