mirror of
https://github.com/MeshCore-Beacon/beacon-docs.git
synced 2026-09-17 03:24:17 +00:00
document map page architecture (#3)
This commit is contained in:
@@ -17,4 +17,5 @@ It is meant for documents that help future code review, implementation planning,
|
||||
|
||||
- [Initial baseline thoughts and suggestions](initial-baseline-thoughts.md)
|
||||
- [Initial tower-server baseline thoughts](initial-server-baseline-thoughts.md)
|
||||
- [Map page architecture](map-page-architecture/README.md)
|
||||
- [PR and commit commenting operating model](pr-commenting-operating-model.md)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# MeshCore Tower Map Page Architecture
|
||||
|
||||
This folder tracks the staged map-page implementation plan for MeshCore Tower.
|
||||
The target is MC-CartoLive feature parity where it fits Tower, but with Tower's
|
||||
own backend contracts, privacy boundaries, IATA scoping, and path-confidence
|
||||
rules.
|
||||
|
||||
The first implementation slice is intentionally small:
|
||||
|
||||
- MapLibre GL JS renders the browser map.
|
||||
- OpenFreeMap provides the default basemap style and tiles.
|
||||
- `tower-server` owns all mesh state through Tower-native API contracts.
|
||||
- Live traffic overlays stay behind a master Live toggle and default off.
|
||||
- Routes remain empty until ordered per-hop path confidence is complete.
|
||||
|
||||
## Documents
|
||||
|
||||
- `cartolive-parity-inventory.md` lists CartoLive behaviors and their Tower status.
|
||||
- `tower-map-architecture.md` describes the Tower map shape and boundaries.
|
||||
- `staged-roadmap.md` breaks parity into safe implementation stages.
|
||||
- `api-contract-deltas.md` records map-specific backend contract additions.
|
||||
- `live-layer-policy.md` captures the Live toggle and animation safety rules.
|
||||
@@ -0,0 +1,57 @@
|
||||
# API Contract Deltas
|
||||
|
||||
This file records map-specific API additions that extend the existing Tower API
|
||||
without copying MC-CartoLive's public-state contract.
|
||||
|
||||
## `GET /api/v1/map/state`
|
||||
|
||||
Query parameters:
|
||||
|
||||
- `iata=YOW`: restrict map state to one IATA.
|
||||
- `regionId=1`: expand the region to its member IATAs.
|
||||
- Omitting both returns all mappable public state.
|
||||
|
||||
`iata` and `regionId` are mutually exclusive.
|
||||
|
||||
Response shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"serverTime": 1760000000000,
|
||||
"scope": { "iatas": ["YOW"], "regionId": 1 },
|
||||
"metadata": {
|
||||
"basemap": "openfreemap",
|
||||
"routesComplete": false,
|
||||
"routesStatus": "blocked_by_ordered_path_confidence",
|
||||
"liveDefaultEnabled": false
|
||||
},
|
||||
"nodes": [],
|
||||
"observers": [],
|
||||
"routes": [],
|
||||
"activitySummary": {
|
||||
"packets24h": 0,
|
||||
"observations24h": 0,
|
||||
"activeObservers24h": 0,
|
||||
"activeIatas24h": 0,
|
||||
"lastHeardAt": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Route Contract Requirement
|
||||
|
||||
Routes must not be populated until path resolution returns one item per hop:
|
||||
|
||||
- hop order preserved from packet path bytes
|
||||
- `confidence = high | ambiguous | none`
|
||||
- candidates retained for ambiguous detail UI
|
||||
- raw bytes and full public keys excluded from public map responses
|
||||
|
||||
Only all-high observations may produce map route edges.
|
||||
|
||||
## Live Contract Direction
|
||||
|
||||
The existing WebSocket remains the primary live channel. If the current
|
||||
`packetObservation` event remains too slim for map animation, add a map-safe
|
||||
event shape rather than exposing packet internals. REST remains authoritative;
|
||||
WebSocket events update freshness and optional animation only.
|
||||
@@ -0,0 +1,47 @@
|
||||
# MC-CartoLive Parity Inventory
|
||||
|
||||
This inventory treats MC-CartoLive as the behavior reference, not as an API or
|
||||
code structure to copy directly. Tower must keep its own server contracts,
|
||||
schema, privacy rules, and UI conventions.
|
||||
|
||||
## Stage 1: Map Foundation
|
||||
|
||||
- OpenFreeMap basemap rendered through MapLibre GL JS.
|
||||
- Full-viewport operational map inside the existing Tower shell.
|
||||
- Mappable nodes from Tower server only.
|
||||
- Mappable observers from Tower server only.
|
||||
- Initial fit to data once per selected region or IATA.
|
||||
- No auto-zoom on new packet traffic.
|
||||
|
||||
## Stage 2: Static Topology
|
||||
|
||||
- Low-zoom node clustering.
|
||||
- High-zoom node and observer points.
|
||||
- Node and observer hover/click inspection.
|
||||
- Role/type filters.
|
||||
- Stale or offline visual states.
|
||||
- Passive route lines only when Tower can prove every hop is high confidence.
|
||||
|
||||
## Stage 3: Operational Panels
|
||||
|
||||
- Busy Pathways summary.
|
||||
- Reachable-node phonebook.
|
||||
- Route highlighting from a selected node.
|
||||
- Plot routes between node endpoints or map points.
|
||||
- Compact panel restore behavior for mobile and dense desktop use.
|
||||
|
||||
## Stage 4: Live Layer
|
||||
|
||||
- Master Live toggle defaults off.
|
||||
- Packet comets, route glows, observer auras, and message bubbles render only
|
||||
when Live is enabled.
|
||||
- Payload and channel filters apply before animation.
|
||||
- Events may be dropped or throttled under load.
|
||||
- VCR playback, scrubbing, and replay are intentionally excluded from Tower.
|
||||
|
||||
## Not Directly Portable
|
||||
|
||||
- CartoLive's `/api/v1/public/state` contract.
|
||||
- Public hash and path shortcuts that do not match Tower privacy policy.
|
||||
- Any route rendering that relies on guessed, ambiguous, or unordered paths.
|
||||
- VCR state and history playback UI.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Live Layer Policy
|
||||
|
||||
The Tower map treats live traffic as an explicit overlay, not as the default map
|
||||
state.
|
||||
|
||||
## Defaults
|
||||
|
||||
- Live is off on first load.
|
||||
- Static nodes, observers, and high-confidence routes may render without Live.
|
||||
- Packet comets, route glows, observer auras, message bubbles, and live-follow
|
||||
movement require Live to be on.
|
||||
|
||||
## Safety Rules
|
||||
|
||||
- Do not animate ambiguous or unresolved paths.
|
||||
- Do not animate stale events outside the accepted live window.
|
||||
- Do not zoom or pan the map in response to packet traffic.
|
||||
- Prefer frame drops over UI jank under load.
|
||||
- Keep live visuals separate from route and node source truth.
|
||||
|
||||
## Subscription Rules
|
||||
|
||||
The map should attach live handlers only while Live is enabled. Turning Live off
|
||||
must clear transient overlays and detach map-specific listeners without affecting
|
||||
the packet list's WebSocket behavior.
|
||||
|
||||
## Future Controls
|
||||
|
||||
- Payload type filters.
|
||||
- Channel filters when channel visibility exists.
|
||||
- Optional observer-only activity aura.
|
||||
- Optional message bubbles for sanitized decoded public messages.
|
||||
|
||||
VCR playback and scrub controls stay out of scope.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Staged Roadmap
|
||||
|
||||
The map should reach parity in small PRs because the server and frontend are
|
||||
changing quickly and multiple people are working in the repos.
|
||||
|
||||
## Stage 1: Static Map Foundation
|
||||
|
||||
- Add `GET /api/v1/map/state`.
|
||||
- Add MapLibre GL JS and OpenFreeMap to `tower-web`.
|
||||
- Render nodes, observers, and empty routes from Tower state.
|
||||
- Fit to visible data once when the selected IATA changes.
|
||||
- Add compact layer toggles.
|
||||
- Keep Live off by default.
|
||||
|
||||
## Stage 2: Confidence-Correct Routes
|
||||
|
||||
- Replace flattened path resolution with ordered per-hop results.
|
||||
- Store or derive route-safe observations only from all-high paths.
|
||||
- Add route edges to `/api/v1/map/state`.
|
||||
- Render passive route lines with no click-stealing.
|
||||
- Add route-focused tests for ambiguous and unresolved paths.
|
||||
|
||||
## Stage 3: Inspection And Topology Tools
|
||||
|
||||
- Add node/observer detail drawer.
|
||||
- Add route and neighbor highlighting.
|
||||
- Add searchable reachable-node phonebook.
|
||||
- Add Busy Pathways from recent high-confidence route activity.
|
||||
- Add route plotting by selected endpoints or map corners.
|
||||
|
||||
## Stage 4: Live Layer
|
||||
|
||||
- Add map-safe live event payloads if the existing WebSocket packet event stays
|
||||
too slim.
|
||||
- Convert high-confidence live observations into packet comets and route glows.
|
||||
- Convert observer-only observations into observer auras.
|
||||
- Add payload/channel filters.
|
||||
- Throttle and drop frames under load.
|
||||
|
||||
## Excluded
|
||||
|
||||
VCR playback, scrub bars, replay mode, and historical animation are not part of
|
||||
Tower map parity.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Tower Map Architecture
|
||||
|
||||
The Tower map is a Tower-native feature. It should reuse CartoLive's proven
|
||||
interaction model where appropriate, but all data must flow from `tower-server`
|
||||
and all UI must follow the compact Tower shell.
|
||||
|
||||
## Rendering Stack
|
||||
|
||||
- Renderer: MapLibre GL JS.
|
||||
- Basemap: OpenFreeMap style URL, defaulting to Liberty unless configured.
|
||||
- Overlay data: GeoJSON sources owned by `src/features/map`.
|
||||
- Live effects: a separate source/layer or canvas overlay, controlled by the
|
||||
Live toggle.
|
||||
|
||||
## Frontend Boundaries
|
||||
|
||||
The map feature should stay under `tower-web/src/features/map`:
|
||||
|
||||
- `api.ts`: fetches Tower map state.
|
||||
- `types.ts`: map-specific frontend contract types.
|
||||
- `geojson.ts`: pure source builders for nodes, observers, routes, and live
|
||||
overlays.
|
||||
- `layers.ts`: MapLibre source and layer declarations.
|
||||
- `live.ts`: safe conversion from Tower live events to map pulses.
|
||||
- `MapView.tsx`: React lifecycle and controls.
|
||||
|
||||
The feature should not require packet-list internals. It may listen to the
|
||||
shared WebSocket manager only when the Live toggle is on.
|
||||
|
||||
## Backend Boundaries
|
||||
|
||||
The map API should expose sanitized, mappable records only:
|
||||
|
||||
- Node UUIDs, labels, roles, coordinates, IATAs, last seen, and counts.
|
||||
- Observer UUIDs, labels, type, IATA, coordinates, online state, and counts.
|
||||
- Route edges only after ordered path confidence exists.
|
||||
- Aggregate activity counts for panels and status.
|
||||
|
||||
The API must not expose full public keys, raw path bytes, packet hashes, owner
|
||||
metadata, broker secrets, channel keys, or resolver debug internals.
|
||||
|
||||
## Route Rule
|
||||
|
||||
Map routes are allowed only when every hop resolves in order with confidence
|
||||
`high`. Any `ambiguous` or `none` hop blocks route drawing for that observation.
|
||||
The UI may show ambiguity in details later, but must not promote it into a map
|
||||
edge.
|
||||
Reference in New Issue
Block a user