Forráskód Böngészése

fix(cockpit): follow backend auto coordinate admission outside primary area (#47)

Kazerin 1 hete
szülő
commit
bf8d21b

+ 13 - 7
.scratch/cockpit-shell-panel-layout/verify/t07-coordinate.mjs

@@ -6,7 +6,7 @@
  *
  * 分八段:
  *   A 唯一准入判据(只认后端 renderable;前端不纠偏、不查范围、不用默认坐标)
- *   B 原因文案(后端六个 reason 逐一命中;「缺失」与「非法」分开;认不出的不泄露原因码)
+ *   B 原因文案(后端各 reason 逐一命中;「缺失」与「非法」分开;认不出的不泄露原因码)
  *   C 切分不静默丢对象(不上图 ≠ 不存在,两堆都要交出去)
  *   D 两个口径分开(后端全量 vs 前端已加载,不混成一个数)
  *   E 后端汇总进领域批次(票 05 遗留的漏读;且不得跨页累加)
@@ -14,8 +14,12 @@
  *   G 静态守卫(domain 不重算坐标范围;界面零原因码;不上图清单由领域层供货)
  *   H 「已上图」措辞不再把被拦下的对象算进去
  *
- * 契约依据是**后端实现**:`CockpitCoordinateValidator`(六种 reason、state 三态、
- * renderable 是结论)与 `CockpitMapSnapshotService`(汇总按整份快照算、三桶分法)。
+ * 契约依据是**后端实现**:`CockpitCoordinateValidator`(state 三态、renderable 是结论)
+ * 与 `CockpitMapSnapshotService`(汇总按整份快照算、三桶分法)。
+ *
+ * 2026-10-12 后端裁定:取消无入口的人工校核前置,改为「结构合法 + 落在主场景区内」自动准入。
+ * 后端 reason 因此增为七个(新增 `OUTSIDE_PRIMARY_AREA`);`UNVERIFIED_COORDINATE` 仍在词表里,
+ * 供历史快照与「后端未给校验段」的防御路径使用,但不再是新数据的常态结论。
  */
 import { readFileSync } from 'node:fs'
 import { createPinia, setActivePinia } from 'pinia'
@@ -65,7 +69,7 @@ function object({ code = 'X', kind = 'monitoring-point', name = '', longitude =
     }
 }
 
-/** 后端校验段的六种取值(照抄 `CockpitCoordinateValidator`)。 */
+/** 后端校验段的取值(照抄 `CockpitCoordinateValidator`;2026-10-12 起含区外原因)。 */
 const BACKEND_CASES = [
     { state: 'VALID', reason: null, renderable: true },
     { state: 'UNVERIFIED', reason: 'UNVERIFIED_COORDINATE', renderable: false },
@@ -74,6 +78,7 @@ const BACKEND_CASES = [
     { state: 'INVALID', reason: 'LONGITUDE_OUT_OF_RANGE', renderable: false },
     { state: 'INVALID', reason: 'LATITUDE_OUT_OF_RANGE', renderable: false },
     { state: 'INVALID', reason: 'ZERO_COORDINATE', renderable: false },
+    { state: 'INVALID', reason: 'OUTSIDE_PRIMARY_AREA', renderable: false },
 ]
 
 /** 后端载荷里的对象 → 领域对象(走真实的适配层,不手搓 coordinate 段)。 */
@@ -150,13 +155,14 @@ function rawToObject(raw, kind = 'monitoring-point') {
         ),
     )
     check(
-        'B1-six-reasons-have-text',
-        texts.length === 6 && texts.every((item) => item.text && item.text !== NO_MAP_LOCATION_TEXT && item.text !== UNVALIDATED_TEXT),
+        'B1-every-reason-has-text',
+        texts.length === BACKEND_CASES.filter((item) => item.reason).length &&
+            texts.every((item) => item.text && item.text !== NO_MAP_LOCATION_TEXT && item.text !== UNVALIDATED_TEXT),
         JSON.stringify(texts.map((item) => `${item.code}→${item.text}`)),
     )
     check(
         'B2-reason-dictionary-covers-backend',
-        Object.keys(COORDINATE_REASON_TEXT).length === 6 &&
+        Object.keys(COORDINATE_REASON_TEXT).length === 7 &&
             BACKEND_CASES.filter((item) => item.reason).every((item) => !!COORDINATE_REASON_TEXT[item.reason]),
         JSON.stringify(Object.keys(COORDINATE_REASON_TEXT)),
     )

+ 7 - 2
src/modules/cockpit/domain/coordinate.js

@@ -24,8 +24,12 @@ export const COORDINATE_STATE = {
 }
 
 /**
- * 后端 reason 原码 → 中文文案。六个取值就是后端 `CockpitCoordinateValidator` 的全部返回值。
- * 这里是「具体坐标原因」的唯一来源,做到词表与后端同步即可。
+ * 后端 reason 原码 → 中文文案。词表与后端 `CockpitCoordinateValidator` 一一对应。
+ *
+ * 2026-10-12:后端取消无入口的人工校核前置,改为「结构合法 + 落在主场景区内」自动准入,
+ * 因此新增 `OUTSIDE_PRIMARY_AREA`(区外不上图,但坐标保留、对象仍在清单里)。
+ * `UNVERIFIED_COORDINATE` 保留在词表中:它是历史快照与「后端未给校验段」防御路径的文案,
+ * 不再是新数据的常态结论。
  */
 export const COORDINATE_REASON_TEXT = {
     UNVERIFIED_COORDINATE: '坐标未经校验',
@@ -34,6 +38,7 @@ export const COORDINATE_REASON_TEXT = {
     LONGITUDE_OUT_OF_RANGE: '经度超出合法范围',
     LATITUDE_OUT_OF_RANGE: '纬度超出合法范围',
     ZERO_COORDINATE: '零坐标(经纬度均为 0)',
+    OUTSIDE_PRIMARY_AREA: '不在主场景区范围内',
 }
 
 /** 认不出原因时的统一文案(票 07 验收原句点名的那一个)。 */