docs(monitor): record province aggregation release
This commit is contained in:
@@ -70,7 +70,11 @@ GET /api/v2/monitor/map?zoom=13&bounds=113,22,114,24&status=online
|
||||
GET /api/v2/monitor/workspace?zoom=13&bounds=113,22,114,24&railLimit=200
|
||||
```
|
||||
|
||||
`summary` and `map` share keyword, protocol and `online|offline|driving|idle` status semantics. `map` accepts `bounds=minLongitude,minLatitude,maxLongitude,maxLatitude`; malformed, non-finite, reversed or out-of-world bounds return `MONITOR_BOUNDS_INVALID`. Below zoom 11 the response remains clustered or mixed. At zoom 11 and above it returns lightweight MassMarks only when the visible point set is at most 2,000; otherwise it adaptively coarsens cells until no more than 2,000 clusters remain. It never returns full telemetry JSON in a point. The browser keeps the normal list at 200 rows, requests map data independently, waits 300ms after `moveend/zoomend`, and drops stale viewport bounds when a direct vehicle search must locate and focus its unique result.
|
||||
`summary` and `map` share keyword, protocol and `online|offline|driving|idle` status semantics. `map` accepts `bounds=minLongitude,minLatitude,maxLongitude,maxLatitude`; malformed, non-finite, reversed or out-of-world bounds return `MONITOR_BOUNDS_INVALID`.
|
||||
|
||||
At zoom 5 and below, `map.mode=provinces`. The response includes `provincePoints`, a compact identity-free array containing only WGS-84 longitude, latitude and normalized status for every located vehicle in the filtered and authorized fleet. Nationwide province counts intentionally ignore the current slippy-map bounds; the browser converts the seeds to GCJ-02 and groups them against AMapUI `DistrictExplorer`'s official nationwide AreaNode. `clusters` remains populated as a visible fallback if that external administrative-boundary resource fails. No VIN, plate, terminal or full telemetry is present in a province seed.
|
||||
|
||||
From zoom 6 through 10 the response remains clustered or mixed. At zoom 11 and above it returns lightweight MassMarks only when the visible point set is at most 2,000; otherwise it adaptively coarsens cells until no more than 2,000 clusters remain. It never returns full telemetry JSON in a point. The browser keeps the normal list at 200 rows, requests map data independently, waits 300ms after `moveend/zoomend`, and drops stale viewport bounds when a direct vehicle search must locate and focus its unique result.
|
||||
|
||||
`workspace` is the production map-screen BFF response. It executes one bounded realtime snapshot read, then derives `summary`, the first `railLimit` realtime vehicle rows (hard-capped at 200), and the viewport-aware `map` payload from that same snapshot. The standalone `summary`, `map`, and realtime-vehicle APIs remain available for list mode and external compatibility, but the browser must not fan them out concurrently for one map refresh.
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ The history-export gate must verify owner-bound listing and authenticated Blob d
|
||||
|
||||
Track smoke must also select the final playback event and verify synchronized SOC/direction/alarm availability plus a resolved current address. For high-frequency sources, confirm positive subsecond samples do not become alternating zero-second `数据间隔` segments; only non-increasing timestamps or intervals over ten minutes are gaps. Access smoke should exercise `model`/`provider` and one paired first/latest receive-time range, then confirm the filter survives a shareable URL and every returned row remains in scope.
|
||||
|
||||
Global-monitor smoke must verify `zoom=5` returns clusters, a city `bounds` at `zoom=13` returns at most 2,000 lightweight points, and invalid/reversed bounds return HTTP 400. In the browser, the rail renders at most 200 vehicle rows while the legend reports the independent map mode. Selecting `driving` or `idle` must constrain both the server-side count and every loaded row. A unique keyword result must discard the previous viewport and focus at point zoom. The synthetic release gate is `go test ./internal/platform -run TestMonitorMapTenThousandVehicles -count=1` plus `go test ./internal/platform -run '^$' -bench BenchmarkMonitorMapTenThousandVehicles -benchtime=30x -benchmem`.
|
||||
Global-monitor smoke must verify `zoom=5` returns `mode=provinces`, `provincePoints` equals the number of authorized/filtered vehicles with valid locations, and no province seed contains VIN, plate or terminal identity. A city `bounds` at `zoom=13` must return at most 2,000 lightweight points, and invalid/reversed bounds must return HTTP 400. In the browser, AMapUI `DistrictExplorer` must load the nationwide AreaNode, render only nonempty provinces with exact counts, and click through to zoom 7 where the existing grid aggregation resumes. Test desktop at DPR 1.5 and mobile at DPR 2 for overlap, clipping and crisp DOM labels. If AMapUI or the AreaNode fails, the backend-provided grid clusters must remain visible instead of producing a blank map. The rail renders at most 200 vehicle rows while the legend reports the independent map mode. Selecting `driving` or `idle` must constrain both the server-side count and every loaded row. A unique keyword result must discard the previous viewport and focus at point zoom. The synthetic release gate is `go test ./internal/platform -run TestMonitorMapTenThousandVehicles -count=1` plus `go test ./internal/platform -run '^$' -bench BenchmarkMonitorMapTenThousandVehicles -benchtime=30x -benchmem`.
|
||||
|
||||
Source-evidence smoke must use a vehicle with at least two protocols and a vehicle with more than one JT808 terminal. Verify that the response returns every actual location/mileage candidate, exactly one current recommendation, protocol-internal selection, availability/quality state and cross-source differences. Raw `source_key`, source IP, endpoint, phone and device identifiers must not appear; terminal labels must remain masked. The browser must not call this endpoint before the operator expands coordinates or mileage. Production baseline for `沪A35898F` on 2026-07-16 returned two JT808 terminals with one recommendation; 20 sequential requests had a 26.6ms median and 29.1ms P95.
|
||||
|
||||
|
||||
@@ -2,6 +2,23 @@
|
||||
|
||||
This document records verified risks, the production controls that address them, and the next evidence to collect. It is intentionally operational: a passing build alone is not proof that the browser application is production-ready.
|
||||
|
||||
## 2026-07-16: nationwide province aggregation
|
||||
|
||||
The nationwide monitor previously reused arbitrary pixel-grid clusters. At country scale that made the count labels visually dense and did not answer the operational question “how many authorized vehicles are in each province.” The production API now enters `provinces` mode at zoom 5 and below and returns a compact, identity-free location/status seed for every filtered vehicle with a valid position. Nationwide counts deliberately cover the complete filtered fleet rather than the current map rectangle; normal viewport filtering resumes after drill-down.
|
||||
|
||||
The browser loads AMapUI `DistrictExplorer` once, uses the official nationwide AreaNode and its pure-geometry `groupByPosition` operation, and converts the platform's WGS-84 coordinates to GCJ-02 before classification. Empty provinces are omitted. Province markers are DOM surfaces with exact vehicle count, online count and online ratio; mobile uses a compact form. A deterministic pixel-space collision pass, center connector and viewport constraint preserve the true province anchor while preventing labels from overlapping or clipping. Clicking a province moves to zoom 7, where the existing grid aggregation resumes. Timed data refresh never changes zoom or center.
|
||||
|
||||
AMapUI is an optional rendering dependency rather than the only map payload. The server still includes bounded grid clusters in nationwide responses. If the script, module or AreaNode fails, those clusters remain visible and the legend explicitly reports the fallback instead of leaving a blank map.
|
||||
|
||||
Production evidence for release `province-map-mobile-20260716182939`:
|
||||
|
||||
- 730 located vehicles were classified into 15 nonempty provinces against the real nationwide AreaNode; unlocated count was zero.
|
||||
- `GET /api/v2/monitor/map?zoom=5` returned approximately 50 KB in about 61 ms on the ECS loopback, with `provincePoints=730` and no truncation.
|
||||
- The final 10,000-point backend benchmark completed in approximately 2.23 ms/op.
|
||||
- Automated rendered checks at 1440×900/DPR 1.5 and 390×844/DPR 2 found 15 markers, no pairwise overlap, no map-bound clipping and no relevant console error.
|
||||
- Clicking a real province changed the monitor response to zoom 7/mixed mode and retained the same 730-vehicle filtered total.
|
||||
- Go tests, 49 frontend files/258 tests, TypeScript and the verified Vite production build passed.
|
||||
|
||||
## 2026-07-16: pre-React boot recovery
|
||||
|
||||
Route Suspense and error boundaries can recover failures only after the React entry has loaded and committed. The production HTML previously contained an empty `#root`, so an entry-script fetch failure, synchronous initialization exception, unhandled startup rejection or permanently stalled module graph could leave a completely blank page with no operator action. React documents error boundaries as protection for errors in their descendant component tree; the browser `error` event separately reports resources that fail to load or scripts that cannot execute: <https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary>, <https://developer.mozilla.org/en-US/docs/Web/API/Window/error_event>.
|
||||
|
||||
@@ -375,7 +375,18 @@
|
||||
|
||||
### P1-03 全国视角省级聚合
|
||||
|
||||
状态:`待开发`
|
||||
状态:`已完成`
|
||||
|
||||
已上线结果(release `province-map-mobile-20260716182939`):
|
||||
|
||||
- 全国视角 `zoom <= 5` 使用省级聚合模式;后端在当前认证车辆 Scope、关键词、协议和状态筛选后返回身份无关的轻量坐标种子,省级数量不会泄露未授权 VIN、车牌或终端信息。
|
||||
- 浏览器使用高德 AMapUI `DistrictExplorer` 的全国行政区矢量边界和 `groupByPosition` 做纯几何归属,只渲染实际有车的省份;WGS-84 坐标先转为 GCJ-02 后再归属,生产 730 辆有有效位置车辆全部归入 15 个非空省级区域,未归属为 0。
|
||||
- 省级卡片显示省名、精确车辆数、在线数及在线占比,移动端使用紧凑省名和精确数量;确定性的像素碰撞规避、中心连接线和视窗边缘约束避免密集省份标签重叠或被裁切。
|
||||
- 点击省级卡片平滑下钻到 `zoom 7`,恢复现有网格聚合;`zoom 11` 及以上继续使用车辆明细点。定时数据刷新只更新数量和标记内容,不调用缩放或居中,不与用户平移、缩放操作争抢控制权。
|
||||
- 高德行政区资源加载失败时保留后端网格聚合作为可见降级,不会出现空白地图;全国模式仍返回网格后备数据,进入非全国 Zoom 后恢复正常边界过滤。
|
||||
- 省级标记使用 DOM/矢量样式而非低分辨率位图。1440×900、DPR 1.5 与 390×844、DPR 2 的真实生产页面均显示 15 个标记,自动检查无重叠、无越界、无相关控制台错误。
|
||||
- 生产接口 `GET /api/v2/monitor/map?zoom=5` 返回 `mode=provinces`、`total=730`、`provincePoints=730`,响应约 50 KB、ECS 回环约 61 ms;最终门禁的 10,000 点后端基准约 2.23 ms/op。
|
||||
- Go 全量测试、前端 49 个文件/258 项测试、TypeScript/Vite 生产构建和 `git diff --check` 通过;ECS 平台服务及两个告警评估器均为 active。
|
||||
|
||||
目标:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user