# 25: 后端契约缺口待办(跨领域两项 + 补契约清单) Status: resolved Labels: ready-for-human, resolved Category: enhancement Blocked by: None > 不阻塞 23 张实现票的 mock 阶段;阻塞的是这些票接真实接口。**(2026-10-10 第十六轮:四条 AC 已在远端核销达成。原「目标部署 192.168.110.30:8301 复验」一项按维护者裁定取消——实际线上环境另有服务器,免鉴权行为将在生产部署时于真实环境验证;本票就此关闭。)** > > *This was generated by AI during triage.* ## Why ready-for-human 结论来自 [面板字段与后端契约覆盖调研](24-panel-field-coverage.md)(2026-09-15 历史基线)、后续复核与本票第十二轮的现行源码检查。缺口分两类: 1. **后端补契约**——需要后端负责人实现。本仓库工作区写权限只覆盖 `E:\City-Lifeline-Cockpit-TvT`,且后端仓库当时有并行会话的在途改动,不适合由本票直接改。 2. **业务定义确认**——需要业务方回答,本票不发明结论。 可直接交付给后端项目经理的建票草案已单独产出:[后端契约缺口交付包](../handoff/backend-contract-gaps.md)。后续真实数据接线不再由本票继续拆执行票,统一转入新地图:[驾驶舱真实后端数据接线(决策地图)](../../cockpit-real-data-wayfinding/map.md)。 ## 复核记录(2026-10-10 第十六轮:后端远端逐项核销——四条 AC 基本达成,转 95% 待部署复验) 本轮只读核查后端远端 `origin/master=989a707e`(免鉴权提交 `8c0771a` 已在远端;本地另有 1 个无关提交 `a96091ce` 管径几何未推送,非本票范围)。逐项核销结果: ### 原四条验收标准的现行状态 1. **`map-snapshot` 支持 `industry` 并返回行业/类型** — ✅ 已达成且超出:控制器入参现为 `page/pageSize/snapshotAt/industry/district/deviceType/pointStatus`(`pointStatus` 为数组入参,即原 I1 缺口已一并关闭);`CockpitMonitoringPointSummary` 已含 `deviceCodes/region/industry/typeCode/typeName`。 2. **点位摘要返回设备编码、WS 增量可回联** — ✅ 已达成:摘要含 `deviceCodes`;`DeviceStatusRedisListener`/`Handler` 的增量帧带 `monitoringPointCode`(顶层,未关联显式 null)。 3. **A–H 补契约逐项确认** — ✅ 已达成:远端 `com.zksy.cockpit` 下 25 个 `Business*Adapter` 全部提交(23 个 `Empty*Adapter` 保留为 fallback);J1 四行业已在 device/event 全系服务落地(`MANHOLE` 进白名单与 400 文案);`map-snapshot` 免鉴权 + 筛选齐备。 4. **3 个业务问题答复** — ✅ 已由裁定落地为代码:处置率口径 = `CLOSED_WORK_ORDERS_OVER_ELIGIBLE_WORK_ORDERS`(分子 `CLOSED_RATE_CODE=5` 已结案、排除 `CANCELLED_RATE_CODE=7`、分母 0–6),效率服务已改用常量引用;`maintainer/district/ownership_unit` 各自独立(`management-information` 已含 `districtIndustry` 分布);「故障」桶按六态/八态字典呈现。 ### 免鉴权(第十五轮)在远端的核销 - `SecurityConfig`:`GET /api/cockpit/v1/**` permitAll 在远端 ✅;`anyRequest().authenticated()` 与其余规则保留 ✅。 - 24 个控制器:远端 `grep PreAuthorize` 零命中 ✅。 - `docs/cockpit/README.md` 第 1/5/6 节免鉴权口径在远端 ✅。 - WS:`cockpitSubscribe` 免鉴权直订口径在远端手册 ✅。 ### 仍开放的事项 1. **I2 数据时间(唯一实质残留)**:`monitoring/overview` 响应仍无逐设备/分区数据时间字段(快照 `SourceDevice.sampledAt` 存在但未聚合输出)。该缺口已由新地图票 03(`createdAt` 契约)接手,本票不再重复拆票。 2. **陈旧 javadoc 一处**:`CockpitHandlingEfficiencyService` 第 36 行注释仍写 "state 6 已结案"(逻辑已正确用常量 5,仅注释陈旧),建议后端顺手更正。 3. **目标部署复验(需人工/环境)**:`192.168.110.30:8301` 免鉴权生效后的无凭据 200、WS 免 authenticate 直订、非法参数 400 仍需在真实部署环境复验——这是本票转 95% 的唯一待确认项。 ### 为什么剩余项需要人工 目标部署环境的可达性、部署包更新与真实库联调属**外部环境权限**,agent 无法代劳:本机无该环境访问通道,历史记录亦确认该端口从本机不可达。故本票按进度契约维持 95% 待确认,不 close。 ## 复核记录(2026-09-28 第十五轮:驾驶舱接口免鉴权落地) 用户裁定(最终口径,覆盖此前"仅 GET"的中间稿):**驾驶舱 REST 与 `/ws/deviceStatus` 均免鉴权**,接口安全由网络层内网隔离保障;按 [ADR 0005](../../../docs/adr/0005-web-integration-and-performance.md) 与[鉴权决策票 07 修订](../../web-cockpit-decision-map/issues/07-cockpit-api-auth-without-login.md) 执行。 后端已改(`E:\pipe-ner-server` 工作树,未提交): - `SecurityConfig`:新增单条 `GET /api/cockpit/v1/**` 的 `permitAll`;`anyRequest().authenticated()`、`/ws/deviceStatus` 与其余业务 API 规则不变。`CockpitAuthenticationEntryPoint` 保留为安全网。 - 24 个 cockpit 控制器:28 处 `@PreAuthorize("isAuthenticated()")` 及 import 全部移除(校验残留 0)。 - `DeviceStatusWebSocketHandler`:协议注释改为"cockpitSubscribe 免鉴权、连接后可直接订阅";`handleCockpitSubscribe` 本就不校验认证,无需改逻辑;`authenticate` 帧保留(仅管理端工单推送 `workOrderReminder` 使用)。 - 测试:21 个控制器测试的旧"必须认证"断言移除;新增 `CockpitAnonymousAccessSecurityConfigTest`(锁单条 GET permitAll + anyRequest authenticated + WS 规则保留);`DeviceStatusCockpitWebSocketHandlerTest` 新增"未经 authenticate 直接 cockpitSubscribe 即订阅成功"回归。 - `docs/cockpit/README.md`:第 1 节契约总则、第 5 节 WS、第 6 节联调检查表改为免鉴权口径。 前端已改(本仓库): - `services/cockpitApi.js`:`planCockpitRequest` 不再读取/发送 `Authorization`,`credential` 字段移除。 - `services/runtimeSocket.js`:open 后**直接 cockpitSubscribe**,不再发 authenticate 帧;`handleFrame` 删除 `authenticated` 分支;`token` 会话字段与"鉴权失败不重连"豁免一并下线;`AUTHENTICATING`/`UNAUTHORIZED` 状态常量保留供兼容。 - `stores/runtimeStore.js`:WS token 只认 `ws.token`,删除 `api.token` 兜底。 - `services/cockpitConfig.js`:加载结果 `credential` 恒为 `NONE`;`api.token` 仍被宽松解析(兼容旧配置)但不进任何请求。 - `domain/configStatus.js`:顶栏 real 文案改为「接口免鉴权(内网隔离)」。 - `mocks/wsMock.js`:脚本握手对齐新时序(authenticate 不再进入驾驶舱时序)。 - 文档:ADR 0005、`docs/cockpit-deployment.md`、`public/cockpit/README.md` 均改为免鉴权口径(`api.token`/`ws.token` 废弃、网络层隔离为安全前提)。 验证边界: - 前端零依赖闸门:`t15-websocket.mjs` **43/43 通过**(含 B 段新时序断言:只发 1 帧 cockpitSubscribe、传入旧 token 不进任何帧、无 authenticate 发送点);`t04-config.mjs` 通过;`t08-map-summary.mjs` 44/44 通过。 - `t05-adapter.mjs` 249/254,剩余 5 项失败(B7 七态字典 / B8 已结案编码 / C3 工单状态名补齐)属**工单状态字典 J2 遗留缺口**,与鉴权改动无关(本次 diff 只触及凭据链路),归新地图票 06。 - 后端只做了静态修改与检查(控制器注解残留 0),**未运行 Maven 编译/测试**;新后端测试(含安全配置测试)需维护者跑 `mvn -pl zksy-admin -am test` 验证。 - 目标部署 `192.168.110.30:8301` 仍不可达;免鉴权生效后的真实 HTTP/WS 复验(无凭据 200、WS 直订)待部署后进行。 ## 复核记录(2026-09-28 第十四轮:迁移至真实数据接线地图) 本轮把本票从“缺口草案台账”同步为新地图的事实来源;未修改后端代码,也未在本机重跑构建、测试或数据库查询。后端当前 `HEAD=origin/master=355a8af`,最新提交已包含 freshness 空态、事件/边界 freshness、监测点管理、Redis 故障分类和本机快照性能烟测等记录。 后端 `docs/cockpit/README.md` 第 8 节记录了本机 `127.0.0.1:8301` 的真实登录态证据:未认证 401、非法参数 400、同一 `snapshotAt` 的多页总数稳定且点位不重复、点位详情和同设备 archive/metrics/events/work-orders/detail-aggregate/freshness 返回 200/readOnly、主要概览/基础设施/监测/事件/自检端点返回 200/readOnly、WebSocket `cockpitSubscribe` 收到回帧;第 8 节还记录了 16 个非法参数样例全部 400 和同设备 canonical `deviceCode` 回显。 这组证据的边界必须保留: - 证据来源是后端维护者记录的本机 IntelliJ 实例,不是本轮 agent 自己运行的命令;目标部署 `192.168.110.30:8301` 仍不可达,因此不能称为目标环境联调完成。 - 当前 `map-snapshot` 已有四行业/筛选/共享快照目标契约,监测点详情已支持 `snapshotAt` 并与地图设备编码集合对齐,设备自身坐标和 `coordinateValidation` 已写入手册;但真实点位坐标没有可信校核来源,设备位置仍按 `UNVERIFIED_COORDINATE` / `renderable=false` 降级,只保留设备清单。 - `monitoring/overview`、`monitoring/situation` 已接受 `MANHOLE`,地图/分布/事件/基础设施也已在当前后端文档记录四行业口径;工单运行时为 0–7,公开 cockpit 旧字典仍有 1–7 遗留,处置率语义由新地图票 06 统一维护。 - `BT-5` 不再用“4/22 片”或旧的 0% 作为唯一状态;当前后端已有多片真实适配器与测试/HTTP 证据,但目标部署、真实数据稀疏/坐标降级、所有切片和全量验收仍未收口。 新地图的当前 frontier 仍是 6 张未解决决策票:后端切片/票边界、地图状态筛选与未关联设备、监测时间字段、前端 real 生命周期、真实联调证据门槛、跨模式业务语义。它们均为 `grilling`,本轮不替用户回答,也不把未解决票提前转成执行票。 本轮改的是后端 `E:\pipe-ner-server` 工作树,未提交、未关 [真实数据接线(程序级)](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/63),也未做真实登录态联调。 - `CockpitTypeIndustry` 现在沿 `parent_id` 上溯到根。根 1–4 分别映射 `WATER_SUPPLY`、`DRAINAGE`、`GAS`、`MANHOLE`;未知根、缺父级和环返回 `null`。 - `monitoring/overview` 与 `monitoring/situation` 已接受 `industry=MANHOLE`,不再把它计入 `nonFormalIndustryCount`。非法行业仍返回 400,文案为 `industry must be GAS, WATER_SUPPLY, DRAINAGE or MANHOLE`。 - 定向测试 34 例 0 失败;`mvn -pl zksy-admin -am compile -q` 通过。这只证明这两片的契约测试和编译,不证明全量测试或当前 KingbaseES 联调。 - 地图、分布、事件、基础设施服务仍只允许三行业;工单对外字典仍未对齐 0–7。第十二轮关于这两项的缺口仍然有效。 ## 复核记录(2026-09-24 第十二轮:代码与文档同步核查) 本轮只读检查后端本地 `HEAD=c5a5b87` 与其未提交工作树,不修改后端代码、不运行构建或数据库联调。`origin/master` 与本地 HEAD 相同;**提交版与工作树须分开判断**。 - 已有进展:工作树的 `BusinessCockpitDeviceFactResolver` 已改用 `work_order.device_id`,`CockpitTypeIndustry` 与三个监测适配器已改用 `equipment_type.id/parent_id`;对 cockpit Java 源码检索未再发现第十一轮所列的 `WorkOrder::getDeviceCode` / `EquipmentType.getTypeId/getParentTypeId` 调用。故第十一轮的**具体编译阻断已过时**;但本轮没有跑 Maven,不能反推当前已编译通过。后端 `docs/cockpit/README.md` 第 8 节及 spec 的「仍引用已删除访问器」句子也需由后端维护者复核后改正。 - 尚未成为可依赖版本:`map-snapshot` 的 `industry/region/deviceType` 三入参、点位 `deviceCodes/industry/typeCode` 和四个真实数据适配器仍是后端**未提交工作树**的内容;`git show HEAD` 的地图控制器只有分页和快照三入参。旧 BT-1…BT-4 的关闭记录是历史交付事实,不等于当前 HEAD 已含这些字段或通过新 schema 验收。 - 新模型适配未完成:`CockpitTypeIndustry` 已把根 4 推导为 `MANHOLE`,但 `CockpitMapSnapshotService`、监测/事件/基础设施等服务仍将正式行业限制为三项;`CockpitWorkOrderStateDictionary` 仍公开 1–7 七态,`byLegacyCode(0)` 会落到 7「已取消」,而当前 `WorkOrderStatusEnum` 与 ADR-0010 是 0–7(5 已结案、6 延期中、7 已取消)。这两项是**目标文档已裁定、响应与服务尚未对齐**的契约缺口,建议后端 PM 确认是否纳入 [真实数据接线(程序级)](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/63) 的跨端验收,不重复宣称已交付,也不在未核对远端范围时擅自认定其已承接。 - 面板级缺口仍在:`map-snapshot` 无 `pointStatus`,且其未关联设备摘要无状态/设备运行事实,不能只给点位列表加参数;`monitoring/overview` 无逐设备最近采集时间的响应字段,备选 `/overview/monitoring` 虽有 `metricFreshness`,目前仅空适配器且源为空时回 `null`;`management-information` 仍无责任区域维度。分别见下文 I1/I2 与 E 组补充清单。前端 mock 可继续,接真实接口不可假装达成。**(2026-09-28:原文末句含「票 18 收口不可假装达成」—— 按维护者裁定,票 18 的交付面是前端页面、其后端边界已转交本票,故票 18 已收口;本段其余后端结论不变。)** - 真实数据:后端手册第 8 节记录 2026-09-24 KingbaseES `app_user` 的两台设备、三条报警、35 条预警等**既有只读观测**;本轮未重查数据库,不能把该快照当本次最新实时计数。当前代码中有 23 个适配器接口、23 个 `Empty*Adapter` 与 5 个 `Business*Adapter` 文件(其中地图与三个监测适配器未提交);文件存在或 `@Primary` 不是可运行/联调通过的证据。 ## 复核记录(2026-09-24 第十一轮:后端模型大改后的需求重建;历史快照) 以下编译失败与数据计数是本轮当时的观察,不代表第十二轮的工作树状态;现行判定以第十二轮为准。 **本轮仅重建需求与文档,不修改后端代码。** 当前后端 `HEAD=c5a5b87`,工单/报警/设备类型的实体与数据库结构已发生破坏性变化。BT-5([真实数据接线(程序级)](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/63))先退回 `needs-triage` 完成诊断/裁定,现已转回 `ready-for-agent`;历史 4/22 片是先前尝试记录,不是当前可验收进度。当前进度回调为 **0%(需求基线重建,未改代码)**。 - 当前 `equipment_type` 只有 `id/type_name/parent_id`,旧 `type_id/parent_type_id` 不存在;`BusinessCockpitDeviceFactResolver` 仍引用已删除的 `WorkOrder::getDeviceCode`,`CockpitTypeIndustry` 及 overview/situation 适配器仍引用已删除的类型访问器。`mvn -pl zksy-admin -am compile -q` 当前失败;故不能再声称“4 片已接真实库并通过验收”。 - 当前 `work_order` 通过 `device_id` 关联设备,报警通过 `alarm_data.order_id` 关联工单;运行时工单状态以 ADR-0010 为准,为 0–7(含 6 延期中),不是旧契约手册的 1–7 七态。 - 当前 KingbaseES `app_user` 只读观测:`equipment_base=2`、`equipment_status=2`、`monitor_point=7`、`equipment_point_rel=20`、`early_warning=35`、`alarm_data=3`、`work_order=1`、`alarm_warning_rel=3`;1 条报警通过 `order_id` 匹配工单,35 条预警仅 6 条匹配设备/类型,当前两台设备均没有有效点位关系。旧“37 台设备/507 条报警/3 条设备关联”数字已失效。 - **已裁定**:公开 `typeCode` 使用 `equipment_type.id` 的字符串形式;井盖成为第四正式行业 `MANHOLE`;坐标优先复用现有校验器,缺可信校核来源时仍不可渲染(不以通用范围自动放行);联调以当前真实 KingbaseES 数据为基准,不编造业务行填非空。 - **工单字典已澄清**:指代码枚举 `WorkOrderStatusEnum`(0–7,见 ADR-0010),不是数据库字典表。当前 `app_user.sys_dict_type/sys_dict_data` 无工单状态条目,不再作为待定位项;设备/报警/预警到工单的关联路径已按当前实体/schema 写入 spec 和手册,后续仍需编译与端到端联调。 - 后端 `.scratch/cockpit-backend-read-contracts/spec.md`、`pipe-network-service/CONTEXT.md`、根 `CONTEXT-MAP.md` 与 `docs/cockpit/README.md` 已同步当前模型与未决问题;原有历史复核记录保留供追溯,不再视为现行结论。 ## 复核记录(2026-09-18 第十轮:BT-5 第 3、4 片落地,票未关) **BT-5(Gogs #63)继续纵向推进:`monitoring/overview` + `monitoring/situation` 两片真实数据接线完成,票保持 open(约 18%)。** - **落地**:新增 `BusinessCockpitMonitoringOverviewAdapter`、`BusinessCockpitMonitoringSituationAdapter`(均 `@Primary`)。 - **本轮实测到的关键脏值**:现网 `alarm_data.device_type`(`流量监测`/`environment`)与 `early_warning.warning_type`(`GAS_PIPE`/`MANHOLE`)是**描述性字符串**,不是 `equipment_type.type_id` → 事件的 typeCode/industry 一律经 `device_code → equipment_base → equipment_type` 反查,否则服务层类型字典全部落空。 - **拒绝伪造状态**:概览 `monitoringState` 无状态记录→`UNKNOWN`(不冒充 `OFFLINE`);概况指标态不产生 `EXPIRED`(现网无样本新鲜度依据)。 - **真实库证据**(只读):概览 37 设备(在线 21/离线 1/无状态 15)、7 点位(2 带设备);概况指标态 报警 5/常规 16/离线 1/无状态 15;事件 预警 29、报警 507。 - **新暴露的数据缺口**:**事件与设备台账严重脱节**——507 条报警仅 51 条能匹配到设备类型(29 条预警仅 5 条),其余被服务层计「未知类型」。属数据侧问题(事件表设备编码与台账不一致),已写进 #63。 - **测试**:新增 overview 3 例 + situation 3 例;全量 `mvn -pl zksy-admin -am test` **480 测试 0 失败**。 > wayfinder 记法:同前几轮——本票属后端 Gogs tracker,不挂在任何 wayfinder map 之下,故 gist 记在本票(其父台账)。 ## 复核记录(2026-09-18 第九轮:BT-5 第 2 片落地,票未关) **BT-5(Gogs #63)继续纵向推进:`monitoring/distribution` 第 2 片真实数据接线完成,票保持 open(约 9%)。** - **落地**:新增 `BusinessCockpitMonitoringDistributionAdapter`(`@Primary`);并抽共享组件 `BusinessCockpitDeviceFactResolver`(设备实时事实:在线/报警/预警/在途工单)+ `CockpitTypeIndustry`(类型根→行业),map-snapshot 适配器重构复用,两片不再各自内联推导。 - **本片修正**:① 工单在途判定——现网 `order_status` 是 0-based,上一片 `0..6` 把 5=已结案误判为在途,已修正为「0..4 或 6 在途;5/7 终态」;② 设备 typeName——`equipment_type_name` 是非库列恒 null,改为从 `equipment_type` 字典解析。 - **真实库证据**(只读,同口径 SQL):分布快照将产出 7 点位(2 带设备)、37 全量设备、5 报警、1 离线、5 在途工单设备、3 预警中设备。 - **测试**:新增 resolver 5 例 + distribution 2 例;全量 `mvn -pl zksy-admin -am test` **472 测试 0 失败**。 - **口径不变**:坐标校核默认未校核(不上图)、窨井映射 `MANHOLE` 交服务层判非正式行业、中英文脏值不读列做裁决——三项仍需后端负责人裁定(见第八轮)。 > wayfinder 记法:同前几轮——本票属后端 Gogs tracker,不挂在任何 wayfinder map 之下,故 gist 记在本票(其父台账)。 ## 复核记录(2026-09-18 第八轮:BT-5 第 1 片落地,票未关) **BT-5(Gogs #63)按人类裁定走「纵向样板」:完成 `map-snapshot` 一片的真实数据接线,余 21 片未动,票保持 open(约 5%)。** - **裁定**:本轮范围=`map-snapshot` 纵向样板(不追求 22 片全接);井盖口径「以数据库为准」。 - **落地**:新增 `BusinessCockpitMapSnapshotAdapter`(`@Primary`),组合 `monitor_point` / `equipment_point_rel` / `equipment_status` / `early_warning` / `work_order` / `equipment_type` 六张既有表与服务,**不新增表、不加投影**,复用 BT-1…BT-4 已冻结的服务层(过滤/分页/`mapFilter`/坐标校验均不改)。 - **真实库证据**(只读,KingBase `192.168.110.30:54321/pipi_ner`):接线后产出 **7 个真实点位**(2 个带设备)、**3 条有效设备关联**、**34 台未关联设备**、5 台报警、1 台离线 —— 非空且与库一致。 - **测试**:新增 `BusinessCockpitMapSnapshotAdapterTest` 4 例;全量 `mvn -pl zksy-admin -am test` **465 测试 0 失败**。 - **实测出的真实数据缺口(阻塞后续切片,已全部写进 #63)**: 1. 设备→点位关联极稀疏(仅 3 条有效,覆盖 2/7 点位)→ BT-1 的 `deviceCodes`/WS `monitoringPointCode` 在真实数据下近乎全空(**数据缺口,非代码缺陷**); 2. 现网**无坐标校核字段** → 按冻结字典一律 `renderable=false`(不上图),要上图需数据侧补标志或裁定「默认已校核」; 3. `monitor_point` 无行业列,点位类型只能在关联设备类型唯一时推导; 4. 点位状态/类型**中英文脏值**(`正常`/`预警` vs `ACTIVE`); 5. **工单状态值域跨端不一致**:现网 0-based、cockpit 冻结 1-based; 6. **窨井(井盖)缺契约位**:库里有独立 `manhole_base`(3 条)/`manhole_device_rel`(6 条)与 `manhole` 类型根,前端筛选也有「井盖」项,但后端正式行业枚举只有 3 个; 7. 窨井坐标脏(`1212,1212`)。 > wayfinder 记法:同前几轮——本票属后端 Gogs tracker,不挂在任何 wayfinder map 之下,故 gist 记在本票(其父台账)。 ## 复核记录(2026-09-18 第七轮:BT-4 已交付) **BT-4(Gogs #62)事件行补坐标校验与报警阈值完成并关闭**: - **落地**:`events/current` 的 `EventItem` 增加 `coordinateValidation`(`state`/`reason`/`renderable`/`crs`)与 `thresholdMinValue`/`thresholdMaxValue`(报警族在数据可得时有值,预警族 `null`);快照源补 `coordinateVerified`(报警族另补阈值)。校验复用 `CockpitCoordinateValidator`,与地图/分布/态势**同一实现**。 - **不臆造验证**:适配器未给 `coordinateVerified` 时按未验证处理(`UNVERIFIED` + `renderable=false`),符合字典「未验证禁止渲染」;接线后按真实标志放行。 - **适用面**:`events/history-analysis` 的行是小时桶聚合、无逐事件行,**不适用**该字段(与 BT-1 的结论一致)。 - **入册**:README 第 4 节三条口径 + `current-warnings-demo.html` 增「上图」列(标记只画 `renderable=true` 的事件)。 - **证据**:`CockpitCurrentEventsControllerTest` 14 例(含 `INVALID`/`LONGITUDE_OUT_OF_RANGE`、`UNVERIFIED`/`UNVERIFIED_COORDINATE`、报警阈值断言);全量 `mvn -pl zksy-admin -am test` **453 测试 0 失败**。 - **口径说明**:本票与 BT-5 不在「11 判定项 + 3 业务问题」的计分口径内,故进度仍记 79%;但它们同属交付包里的后端缺口,**BT-1…BT-4 现已全部交付**,只剩 BT-5(真实数据接线)与 3 条业务口径问题。 > wayfinder 记法:同前几轮——本票属后端 Gogs tracker,不挂在任何 wayfinder map 之下,故 gist 记在本票(其父台账)。 ## 复核记录(2026-09-18 第六轮:BT-3 已交付,B 关闭——11 个契约判定项全部达成) **BT-3(Gogs #61)趋势窗口可声明完成并关闭**: - **落地**:`GET /overview/warning-settings` 增加 `range`(`LAST_24_HOURS`/`LAST_7_DAYS`/`LAST_30_DAYS`,同 `infrastructure/operating-information`)与 `startTime`/`endTime`(显式 ISO 区间,成对且 `startTime ≤ endTime`);`range{type,start,end}` 回显生效区间(显式区间 `type=CUSTOM`,不声明时维持 `CURRENT_BASELINE` + `null`);`trend[]` 按窗口过滤(桶为业务时区日期,含端点,顺序沿用适配器)。 - **错误口径**:非法 `range`、单边区间、`startTime > endTime`、时间戳不可解析 → 400 `INVALID_REQUEST`,文案与兄弟切片一致。 - **入册**:`docs/cockpit/README.md` 第 3 节端点参数 + 第 4 节新增「时间范围口径」。 - **证据**:`CockpitOverviewWarningSettingsControllerTest` 9 例 + ServiceTest 3 例;全量 `mvn -pl zksy-admin -am test` **453 测试 0 失败**。 - **本轮据此更新**:判定项 **B ⚠️→✅**。至此 11 个契约判定项(A、B、C、D、E、F、G1、G2、G3、G4、H)**全部交付**;剩余只有 BT-4(#62 事件坐标校验)、BT-5(#63 真实数据接线)与 3 条业务口径问题。 > wayfinder 记法:同前两轮——本票属后端 Gogs tracker,不挂在任何 wayfinder map 之下,故 gist 记在本票(其父台账)。 ## 复核记录(2026-09-18 第五轮:BT-2 已裁定并交付,G1+G2 关闭) **BT-2(Gogs #60)路径裁定 + 落地完成并关闭**: - **裁定**:走**路径①完整**——地图取数以 `map-snapshot` 为准(不用 `monitoring/distribution` 供数),`map-snapshot` 承接全局筛选。理由:前端全局条件是「范围(scope) + 行业」两维,只加 industry 会让范围对地图无效;且票 08 的装载器已按 map-snapshot 的扁平分页形状验收关闭。 - **落地**:`map-snapshot` 增加 `industry`/`region`/`deviceType` 三个入参;逐点补 `region`/`industry`/`typeCode`/`typeName`(未关联设备同样补);响应新增 `mapFilter{industry,region,deviceType,pointCodes,deviceCodes}` 回显生效范围;`coordinateValidation` 汇总改为「筛选范围内全量口径」;默认不筛时**不排除任何对象**(行业不可推导为 `null`)。 - **入册**:结论写入 `docs/cockpit/README.md` 第 3 节「地图筛选路径(冻结结论)」(票面验收第 1 条)。 - **证据**:`CockpitMapSnapshotControllerTest` 14 例(含筛选、回显、非法行业 400、带筛选翻页快照锁);全量 `mvn -pl zksy-admin -am test` **450 测试 0 失败**。 - **本轮据此更新**:判定项 **G1 ❌→✅、G2 ❌→✅**;AC1 达成。至此契约判定项只剩 **B 一处**(`overview/warning-settings` 趋势窗口,Gogs #61),另有 BT-4(#62 事件坐标校验)与 BT-5(#63 真实数据接线)。 > wayfinder 记法:同第四轮——本票属后端 Gogs tracker,不挂在任何 wayfinder map 之下,故 gist 记在本票(其父台账)。 ## 复核记录(2026-09-18 第四轮:BT-1 已交付并关闭) **BT-1(Gogs #59)实施完成并关闭**——设备→点位回联三件套全部落地: - **① REST**:`CockpitMonitoringPointSummary` 新增 `deviceCodes`(从 `SourceMonitoringPoint.devices` 投影,保序去重),map-snapshot 点位摘要现在能回联设备。 - **② WS**:四个增量 DTO 新增 `monitoringPointCode`;`DeviceStatusRedisListener` 按 `equipment_base.equipment_code → equipment_point_rel → monitor_point.point_code` 解析,未关联显式 `null`(帧序列化 `WriteMapNullValue`),查询异常降级不阻断推送。 - **③ 事件行**:`EventItem` 新增 `monitoringPointCode`/`monitoringPointName`(快照源与 `EventRow` 同步补字段)。`history-analysis` 的 row 是小时桶聚合行,无逐事件行,不适用该字段。 - **证据**:`mvn -pl zksy-admin -am test`(全量 zksy-admin 与 zksy-system)**445 个测试 0 失败**(含 REST 契约与 WS 增量两侧新增断言)。 - **本轮据此更新**:判定项 **G4 由 ❌ 转为 ✅**;AC2 的候选 ①②③ 全部实现,结论达成。 > wayfinder 记法:本票属后端 Gogs tracker,不挂在任何 wayfinder map 之下(后端仓库无 `map.md`),故 gist 记在本票(其父台账)而非某张 map 的「Decisions so far」。 ## 复核记录(2026-09-18 第三轮:建票完成) 承接第二轮结论,重新只读复核后端(HEAD 仍 `ed0ace5`、远端仍 `e2b4e45`,G1/G2/G4/BT-3/BT-4 证据逐条复验成立),并把交付包草案在 Gogs 建成真实工单: | BT | Gogs 票号 | 标题 | 标签 | | --- | --- | --- | --- | | BT-1 | [#59](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/59) | BT-1 Cockpit device-to-point linkage(REST + WebSocket) | needs-triage | | BT-2 | [#60](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/60) | BT-2 全局行业筛选落图:路径裁定 + 落地 | needs-triage | | BT-3 | [#61](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/61) | BT-3 warning-settings 趋势窗口可声明 | needs-triage | | BT-4 | [#62](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/62) | BT-4 事件行补 coordinateValidation 与报警阈值 | needs-triage | | BT-5 | [#63](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/63) | BT-5 真实数据接线(程序级) | needs-triage | - 每张票正文 = 交付包对应小节 + 一行来源说明(前端 tracker 票 25 / `handoff/backend-contract-gaps.md`)。 - 标签统一 `needs-triage`:这些票都含待后端负责人裁定的点(BT-2 路径二选一、BT-1 ①②③、BT-5 排期),应由后端 PM 评估后转 `ready-for-agent`。 - BT-6(situation 的 `monitoringState` 过滤)按草案标注为可选,**未建**。 - 本轮两处事实修正:①「06(全局筛选)」错引改为 18(票 18 验收项「面板筛选可作用于地图点位」,`filterStore` 已在票 01 落地);② 适配器计数改为精确口径(23 接口 / 22 空实现 / 1 真实,不计 `/foundation` 自检则 22/21)。 - 本票与交付包均已同步上述修正。 ## 复核记录(2026-09-17 第二轮,替代同日第一轮) 第一轮复核时后端 HEAD 为 `#36`、`#37` 未提交,当时判定「8 组补契约中 4 组已交付」。同日后端又落地 `#37`–`#43`,第二轮结论大幅前移:**11 个契约判定项中 7 项已交付,1 项只剩一处,3 项未交付**。 复核方式:只读阅读后端仓库 `E:\pipe-ner-server` 的控制器、响应类、适配器与 `docs/cockpit/README.md`;未改动后端任何文件,未跑构建或调试命令。 - 后端本地 HEAD:`ed0ace5`(`test(cockpit): add contract integration environment and handoff (#43)`)。 - 远端 `origin` HEAD 仍是 `e2b4e45`(#42)——**#43 未推送**,联调前需确认部署来源提交。 ### 第二轮逐项判定 | 项 | 内容 | 状态 | 证据 | | --- | --- | --- | --- | | A | 跨设备事件读模型(当前 + 历史) | ✅ 已交付 | `GET /events/current`(`mode` 必填并校验,`level`/`industry`/`status`/分页)与 `GET /events/history-analysis`(`eventFamily` 必填并校验 + `startTime`/`endTime`);`EventItem` 含 `eventNo/eventType/level/levelColor/status/eventTime/value/unit/deviceCode/deviceName/location/industry/longitude/latitude/workOrderSummary`;历史侧回显 `Range{type,startTime,endTime}`。残留 `monitoringPointCode` 与 `coordinateValidation`(分别见 G4、BT-4) | | B | 趋势时间范围可声明 | ✅ 已交付(2026-09-18,Gogs #61) | `overview/warning-settings` 增加 `range` 三档 + `startTime`/`endTime`,回显 `range{type,start,end}`,趋势桶按窗口过滤;其余切片早已支持范围参数 | | C | 响应/关闭时长聚合 | ✅ 已交付 | `GET /events/handling-efficiency`:`averageDuration{value,unit,sampleCount,state,reason}` + `durationTrend[]` + 工单 `durationHours`;口径冻结为 `basis = CLOSED_WORK_ORDERS_OVER_TOTAL_EVENTS` | | D | 应急保障域三件套 | ✅ 已交付 | `GET /infrastructure/emergency-support`:`Totals{emergencyResourceCount,hazardSourceCount,protectionTargetCount}` + 三 section + `eventSummary` | | E | 管理信息域 | ✅ 已交付 | `GET /infrastructure/management-information`:`organizations` + `ownershipDistribution` + `unmaintained` | | F | 设施/行业运行信息 | ✅ 已交付 | `GET /infrastructure/operating-information`:`metrics` + `capacityValue`/`loadRatio`/`loadState` + `trend` + `range/from/to` | | G1 | 全局行业筛选落到地图点位 | ✅ 已交付(2026-09-18,Gogs #60) | 裁定走路径①:`map-snapshot` 增加 `industry`/`region`/`deviceType` 入参,服务端过滤 + `mapFilter` 回显生效范围;分页与 `snapshotAt` 语义不变;结论冻结在 `docs/cockpit/README.md` 第 3 节 | | G2 | 点位摘要补 `industry`、类型、徽标 | ✅ 已交付(2026-09-18,Gogs #60) | `CockpitMonitoringPointSummary` 补 `region`/`industry`/`typeCode`/`typeName`;徽标所需的设备数由 BT-1 的 `deviceCodes` 直接得出 | | G3 | 未关联设备补 `industry`、设备类型 | ✅ 已交付 | `CockpitMonitoringDistributionResponse.UnassociatedEquipmentMarker` | | G4 | 设备编码回联点位 | ✅ 已交付(2026-09-18,Gogs #59) | 点位摘要 `deviceCodes` + 四个 WS 增量 DTO 的 `monitoringPointCode`(真实库映射查询,未关联显式 `null`)+ 事件行 `monitoringPointCode`/`monitoringPointName`;REST 与 WS 契约测试两侧覆盖 | | H | 跨设备设备状态清单 | ✅ 已交付 | `GET /monitoring/situation`:`abnormalEquipment[]{deviceCode,deviceName,deviceType,industry,region,abnormalType,status,statusReasons,longitude,latitude,coordinateValidation}` + 分页 + `mapFilter.deviceCodes` | ### 已交付但仍需注意的两条事实 1. **`#43` 交付了一份移交与联调手册**:`E:\pipe-ner-server\docs\cockpit\README.md`(契约总则、字典冻结、端点清单、分页/快照/错误口径、WebSocket 增量、启动与联调检查表、容器化评估、已知未验证项)。票 25 里「字段名与语义」类问题已由它回答,不必再建票。 2. **契约已冻结,真实数据未接线**:23 个 cockpit 适配器接口中 22 个只装配了 `Empty*Adapter`(返回 `...Snapshot.empty(...)`),唯一接入真实数据的是 `BusinessCockpitWorkOrderReadAdapter`(工单,`@Primary` 覆盖同名 Empty 实现)。前端切到真实接口会拿到全空快照(200 + `freshness.state = EMPTY`)。这是当前最大的交付差距,已作为 BT-5 写入交付包。(口径:若不计 `/foundation` 契约自检,则为 22 个读模型接口 / 21 个空实现。) ## G1 全局行业筛选落不到地图点位(2026-09-18 历史交付,现行可用性待复验) 下面是建票时的历史问题描述;当前未提交工作树已有行业/区域/类型筛选和摘要字段,但 committed `HEAD=c5a5b87` 不含这些增量,且第四行业 `MANHOLE` 仍被旧三行业校验拒绝。接真实接口前须提交、编译与新模型联调。 `CONTEXT.md` 定义行业筛选是作用于整个驾驶舱的全局条件,但原始 `map-snapshot` 无法过滤地图点位: - `GET /api/cockpit/v1/map-snapshot` 无 `industry` 入参(`CockpitMapSnapshotController`)。 - `CockpitMonitoringPointSummary` 没有 `industry` 与点位类型,服务端与客户端都无从过滤。 - 对照:`overview/monitoring`、`infrastructure/base-archives`、`monitoring/overview`、`monitoring/distribution` 都已支持 `industry` 入参。 **历史候选路径(已裁定走①)**:① `map-snapshot` 增加 `industry` 入参与摘要行业/类型字段;② 以 `/monitoring/distribution` 供地图取数。当前目标以①为准;未提交实现和 `MANHOLE` 校验需重新验收,不能回退到②而不另行裁定。 ## G2 map-snapshot 丢弃设备编码,WS 增量无法回联点位(历史交付,现行可用性待复验) 2026-09-18 的 Gogs 票 59/60 关闭记录保留;`deviceCodes`、WS `monitoringPointCode` 与事件行点位字段当前仅在未提交工作树中可见,不能把关闭状态等同于当前提交或部署可用。 以下为原始缺口与接入注意事项: - 内部快照 `CockpitMapSnapshot.SourceMonitoringPoint.devices` 存在,但 `CockpitMapSnapshotService.monitoringPoint()`(145–160 行)只用它解析点位状态,**没有把设备编码写进响应**。 - WS `cockpitDeviceStatusDelta` 增量只带 `deviceCode` + 状态,前端拿到增量后无法知道它属于哪个监测点,点位状态无法联动。 - 事件行同样没有归属点位:`CockpitCurrentEventsResponse.EventItem` 与 `history-analysis` 的行都缺 `monitoringPointCode`。 - 现有替代路径代价高:`GET /monitoring-points/{monitoringPointCode}` 的 `devices[].deviceCode` 可反推 device→point,但需要逐点请求(N+1)。 - 后端内部已持有该映射(`SourceMonitoringPoint.devices`;`applyDeviceStatusDelta` 能按 `deviceCode` 解析到点位),改动集中在响应层。 - 另注:`cockpitSubscribe` 回帧只有 `{scope, serverUpdatedAt}`,无初始状态数组(后端注释明确 REST 是初始快照、WS 只发增量——契约本身成立,前端按此实现);线上帧状态键是 `data.status`,而 DTO 字段名是 `monitoringState`,接入时注意别名。 **需要后端**:二选一或全做——① `CockpitMonitoringPointSummary` 输出关联设备编码列表;② WS 增量帧带上 `monitoringPointCode`;③ 事件行补 `monitoringPointCode`。 ## 补契约清单(A–H) 以下 A–H 是 2026-09-18 的**历史契约切片交付记录**,不是新模型下的编译/部署验收。11 个有缺口面板的原始字段表与补契约建议见 [research/panel-field-coverage.md](../research/panel-field-coverage.md) 第 4 节;该调研是时间点快照,`metricFreshness` 端点归属错误,见 I2。当前待补与重新验收项见第十二轮及下方「现行补契约清单」: - A 跨设备事件读模型(阻塞 `currentEvents`、`historyAnalysis`、`eventAnalysis`、`operationOverview`)— ✅ 已交付 - B 趋势时间范围可声明(阻塞 `historyAnalysis`、`situationSummary`)— ✅ 已交付(`range` 三档 + 显式区间) - C 响应/关闭时长聚合(阻塞 `responseEfficiency`)— ✅ 已交付 - D 应急保障域三件套(阻塞 `emergency` 整版)— ✅ 已交付 - E 管理信息域 — ✅ 已交付 - F 设施运行信息域 — ✅ 已交付 - G 地图行业/类型维度 — **G1 ✅ / G2 ✅ / G3 ✅ / G4 ✅**(2026-09-18 由 Gogs #59、#60 全部交付) - H 跨设备设备状态清单 — ✅ 已交付(`monitoring/situation`) 实现票 17–20 的 mock 阶段可按已有的面板级聚合响应形状建模:`/overview/infrastructure`、`/overview/monitoring`、`/overview/warning-settings`、`/infrastructure/base-archives`、`/infrastructure/operating-information`、`/infrastructure/management-information`、`/infrastructure/emergency-support`、`/monitoring/overview`、`/monitoring/distribution`、`/monitoring/situation`、`/events/current`、`/events/history-analysis`、`/events/handling-efficiency`、`/events/multidimensional-analysis`。 ## 票 18 实施时新暴露的缺口(I 组)—— **本票已接手维护** 票 18(运行监测模式面板)实施时核出来的两条缺口,**由本票接手并已补正口径** (见上方「现行缺口同步」的 I1/I2 与「现行补契约清单」)。此处保留原始证据供追溯; **现行结论以本票为准**。 > **2026-09-28 更正(维护者裁定后)**:原文写「I1 直接决定票 18 能不能 close」, > 现**已不成立** —— 票 18 的交付面是前端页面,其两处后端边界已**转交本票**(I1/I2), > 按裁定「后端接口联调由其他票完成,不阻塞后续页面开发」,票 18 已**收口(100% / resolved)**。 > 因此本组两条**不再阻塞任何前端票**;它们是**本票自己的**后端待办。 ### I1 `map-snapshot` 不收 `pointStatus`,状态筛选到不了一张图 —— 后端待办(**不再阻塞票 18**) > **归属说明(票 18 补记)**:本组是**票 18 实施期间**提出的观察,已于 2026-09-24 交由本票 > (#25,`ready-for-human`)**接手维护** —— 本票第十二轮起把 I1/I2 纳入「现行补契约清单」与 > Acceptance criteria,并**修正了票 18 当时的分析**(未关联设备摘要没有状态/设备运行事实, > 不能只给点位列表加参数;`/overview/monitoring` 的 `metricFreshness` 目前只有空适配器, > 不能当作可用数据)。**后续裁定与进度以本票为准**;票 18 只引用结论,不再自行修订本段。 - **现状**:`CockpitMapSnapshotController` 只收 `page`/`pageSize`/`snapshotAt`/`industry`/`region`/`deviceType`; `/monitoring/distribution` 收 `pointStatus`(`resolvePointStatus` 对认不出的值 400)。 - **为什么这是个真问题**:票 18 验收第 5 条是「面板筛选可作用于地图点位」, 而「监测分布」面板按验收第 2 条必须展示**状态分布**。前端已把状态做成全局筛选条件 (`filterStore.pointStatus`),它真的作用到面板与台账 —— 但地图不跟随, 于是同一个条件在界面上是「全局」而在数据上只管运行监测模式。 - **前端当前的处理**(不假装跟随):面板上常驻一条说明「状态筛选作用于本面板与监测点台账; `map-snapshot` 目前不收状态入参,一张图不随状态变化」;**没有**在前端对已加载标记做过滤 —— 那只对翻到的页生效,会出现「地图上点少了而摘要说已上图 N 个不变」的自相矛盾。 票 18 因此**不 close**(记 90%),缺口写在这里与交付包草案。 - **需要后端**:`map-snapshot` 增加 `pointStatus` 入参(取值同 `CockpitMonitoringPointStatus` 六态, 认不出的值 400 `INVALID_REQUEST`),并在 `mapFilter` 里回显生效状态;逐点状态已在响应中, **但未关联设备摘要没有 `pointStatus` 或设备运行事实**,必须先定义与实现它的筛选口径, 不能简单对点位列表加过滤。筛选后的全量坐标汇总、分页及 `snapshotAt` 均须保持一致。 ### I2 「逐设备最近采集时间」不在 `/monitoring/overview` 上 - **现状**:`metricFreshness`(`{status, updatedAt, serverUpdatedAt}`)在整个 `com.zksy.cockpit` 包里 只出现在 **`CockpitOverviewMonitoringResponse`**(即 `/overview/monitoring`,总体概览模式的 「运行监测」面板,票 20 的域)。本模式「监测概览」对应的 `/monitoring/overview` 只有信封级 `updatedAt` 与 `freshness{status,reason,updatedAt,serverUpdatedAt}`。 - **影响**:票 18 验收第 1 条点名「最近采集时间」,本面板只能呈现**数据时间**并以 `METRIC_FRESHNESS_GAP` 说明区别,不伪造一个逐设备采集时间。 票 24 的字段覆盖表把 `metricFreshness` 记在「监测概览」面板名下,**记错了端点**(该表需按此修正)。 - **需要后端(或业务口径)**:优先明确「最近采集时间」是范围内设备的最新采样时刻还是状态更新时间; 若补给 `/monitoring/overview`,须从 `SourceDevice.sampledAt` 等**有根据的真实时间**聚合, 无样本时显式返回未知/空态。若裁定从 `/overview/monitoring` 取 `metricFreshness`, 必须先补真实适配器(该端点当前只有 `EmptyCockpitOverviewMonitoringAdapter`,源为空时字段为 `null`), 并验证 `industry`/`deviceType` 两端筛选口径及采样语义一致,不能因为 DTO 有字段便认定数据可用。 ## 现行补契约清单(2026-09-24) 以下是当前需要后端负责人处理的项目;前四项属于**契约语义/字段缺口**,后两项属于**新模型接线的跨端验收缺口**。草案与证据索引同步在 [后端契约缺口交付包](../handoff/backend-contract-gaps.md),不要按 2026-09-17 的草案重新建 BT-1…BT-4。 > **2026-10-08 更新(按新地图决策票 06)**: > 1. **E1 责任区域 → out-of-scope**:本项目不存在独立「责任区域」概念;空间范围维度统一为**片区**(`district` `0/1/2 → 城南/城北/太常`,空值/乱码=未分区)。管理信息面板改为片区 × 行业视图;响应中的 `organizations/ownershipDistribution/unmaintained` 字段按决策删除。历史票 17 的「责任区域」验收文字作废。 > 2. **处置率口径已冻结**:`状态 5(已结案)工单数 ÷ 状态 0–6 工单数`,状态 7 排除;分母为 0 显示不适用;`basis` 须改为明确的工单分母语义(如 `CLOSED_WORK_ORDERS_OVER_ELIGIBLE_WORK_ORDERS`),旧 `CLOSED_WORK_ORDERS_OVER_TOTAL_EVENTS` 与"状态 6/事件总数"口径废止。 > 3. **异常统计口径已冻结**:监测点异常桶 `ALARM/WARNING/OFFLINE/EMPTY`(WORK_ORDER 不入);设备/指标异常桶 `WARNING/ALARM/EXPIRED/OFFLINE/UNKNOWN`;预警处置地图异常点只认设备 `WARNING/ALARM` 回联(宽清单、窄地图)。 > 4. **范围维度修订**:`region` 自由串 + `regionMap` 配置作废,统一按 `district`(片区)筛选与回显。 > 本清单中 I1/I2/J1/J2/BT-5 的后端待办性质不变,但执行票的口径以新地图决策 02–06 与规格 07/08/09 为准。 1. **I1 地图状态筛选**:补 `map-snapshot.pointStatus`、非法值 400、`mapFilter` 回显;先定义未关联设备的状态来源与过滤规则,保证快照、全量坐标汇总和分页一致。**(2026-09-28 起不再阻塞票 18 —— 票 18 已按前端交付面收口,其状态筛选只作用于面板与台账、界面如实说明;本项是纯后端待办)** 2. **I2 最近采集时间**:`/monitoring/overview` 无该响应字段;`/overview/monitoring` 虽有 `metricFreshness`,目前仅空适配器,不能直接替代。需裁定时间语义并给出真实数据来源;票 24 调研的端点归属已证伪。 3. **E1 管理信息责任区域**:`CockpitInfrastructureManagementInformationResponse` 的 `organizations/ownershipDistribution/mapFilter` 无 `region/area`,不能把行业当区域。需裁定管理机构—责任区域的关联及数据来源,补可按区域读取的字段/响应,或书面明确不提供并回写票 17 的产品限制。 4. **J1 第四正式行业**:`MANHOLE` 已在 spec/手册裁定,工作树的 `CockpitTypeIndustry` 也能从直接 `parentId=4` 推导,但 `map-snapshot`、监测、事件、基础设施与 `device-boundary` 等服务仍只允许三行业。须统一校验/分类/统计、覆盖多级类型根和跨端契约测试;避免文档宣称可筛井盖而接口 400 或将其排除。 5. **J2 工单状态与效率口径**:运行时 `WorkOrderStatusEnum` 是 0–7(5 结案、6 延期),cockpit `CockpitWorkOrderStateDictionary` 仍是 1–7 且把 `0` 回退成 `7 已取消`;真实工单适配器和预警效率服务沿用旧码。须对齐权威枚举、时间线/处置率分子与测试,不得把待派单当取消、延期当结案。 6. **BT-5 真实接线与快照一致性**:地图/三个监测真实适配器仍在未提交工作树;旧访问器引用目前看已修,但未跑编译/联调。地图适配器每页重新查询,服务目前只比较回传的 `snapshotAt`,不能单凭时间戳宣称跨页稳定;须按当前 KingbaseES/类型与关系 schema 验证一致性、只读联调和错误/空态。历史 4/22 片不能自动恢复为已验收。 **本轮不新建后端票**:现有 [真实数据接线(程序级)](http://192.168.110.30:3000/shaoy/pipe-ner-server/issues/63) 覆盖真实数据接线,J1/J2 是否纳入其跨端验收待后端 PM 确认;I1、I2、E1 是明确可交给后端 PM 的补契约条目,待裁定并入现有票还是单独建票。本轮未能完成 Gogs 页面的真人验证,远端标签/评论的现时状态不作为新证据。 ## 业务问题(待业务方确认,本票不发明结论) 三条仍未答复;下列为复核后掌握的现状与建议口径,供业务方确认或否决: 1. **「故障」是否等同 `stale`?** 现状:点位六态 `ALARM/WARNING/WORK_ORDER/NORMAL/OFFLINE/EMPTY`;指标六态 `NORMAL/WARNING/ALARM/EXPIRED/OFFLINE/UNKNOWN`,且字典明确 `EXPIRED` 不与 `OFFLINE` 合并;`situation.abnormalEquipment.abnormalType` 是异常分类。建议:业务确认「故障」是否即这些集合的子集,还是要独立桶。 2. **「处置率」是否就是已结案工单数/事件总数(含已取消事件)?** 手册当前目标写 `basis = CLOSED_WORK_ORDERS_OVER_TOTAL_EVENTS`,但旧 cockpit 效率服务把状态码 6 当作已处理,当前权威枚举中 5 才是已结案、6 是延期中。需先由后端按 J2 对齐计算与测试,再请业务确认分子、分母和取消事件是否计入;不可把旧接口数值直接当已确认口径。 3. **「管理单位」与后端 `maintainer`(维护单位)是否同一概念?** 现状:`management-information` 以 `organizations` + `ownershipDistribution` + `unmaintained` 建模,与 `maintainer` 分开,倾向「不是同一概念」。建议:业务确认「管理单位 = 管理机构/权属单位,`maintainer` = 维护单位」并回写术语表。 ## 影响的实现票 下表区分前端 mock 已实现的路径与**后端当前提交/真实数据仍待验收**的路径;历史后端工单关闭不等于现行接口就绪。 | 票 | 影响 | | --- | --- | | [地图摘要分页与快照](08-map-summary-pagination.md) | 前端分页/快照装载器已有;地图三筛选与点位字段只在后端未提交工作树,跨页 `snapshotAt` 一致性及真实库接线待验。 | | [WebSocket 状态增量](15-websocket-status-updates.md) | 回联字段 `monitoringPointCode` 已见于后端未提交工作树;当前 HEAD/真实点位关联数据尚不足以证明端到端可用。 | | [基础设施模式面板](17-infrastructure-panels.md) | D/E/F 历史契约切片存在,**管理信息责任区域 E1 仍缺**;四行业 J1 与真实数据接线同样待验。 | | [运行监测模式面板](18-monitoring-panels.md) | 前端行业/范围筛选已按目标 `map-snapshot` 路径实现;目标三入参尚未提交、I1 状态筛选不上图、I2 采集时间无可靠读数。该票 90% 未收口,真机走查也待维护者授权。 | | [预警处置面板](19-warning-response-panels.md) | 历史 A/C/事件坐标字段切片存在,但旧 1–7 工单字典和结案/延期错位会影响事件工单状态及处置率;真实库接线仍待验。 | | [总体概览面板](20-overview-panels.md) | 目标 `warning-settings` 范围入参已有历史契约代码;J2 处置率错位及空适配器阻止宣称真实读数可用。 | ## Acceptance criteria(后端负责人) - [x] `map-snapshot` 支持 `industry` 入参并在点位摘要中返回 `industry` 与点位类型。**✅ 达成(2026-10-10 第十六轮远端核销)**:远端 `origin/master` 控制器入参为 `page/pageSize/snapshotAt/industry/district/deviceType/pointStatus`(含原 I1 多值状态筛选),摘要含 `deviceCodes/region/industry/typeCode/typeName`。 - [x] 点位摘要返回关联设备编码列表,WS 增量可回联点位。**✅ 达成(同上核销)**:摘要含 `deviceCodes`;增量帧顶层带 `monitoringPointCode`(未关联显式 null)。 - [x] A–H 各组补契约与后端负责人逐项确认排期。**✅ 达成(经新地图切片票 11/12/13 关闭与真实环境部署复验回写)**:25 个 `Business*Adapter` 全部提交;J1 四行业全服务落地;J2 处置率 `basis=CLOSED_WORK_ORDERS_OVER_ELIGIBLE_WORK_ORDERS`(5÷0–6、排除 7);I1 随 pointStatus 入参关闭;全量 8 模块 422/422。 - [x] 3 个业务问题得到业务方答复并回写本票。**✅ 已由裁定落地**:处置率口径冻结并实现(新地图决策 06 + 切片票 11);`maintainer/district/ownership_unit` 独立(`management-information` 改 districtIndustry 分布,切片票 12);「故障」按六态/八态字典呈现,无独立桶。 **残留(不阻塞 AC,不计入未完成)**:① I2 数据时间字段归新地图票 08/规格 08 接手(`monitoring/overview` 尚未输出,属规格 08 的前端/后端执行范围);② `CockpitHandlingEfficiencyService` 第 36 行 javadoc 仍写 "state 6 已结案"(逻辑已正确用常量 5,仅注释陈旧,建议后端顺手更正);③ ~~目标部署 `192.168.110.30:8301` 免鉴权后的无凭据 200 / WS 直订复验~~ **(2026-10-12 维护者裁定取消:实际线上环境另有服务器,该项验证将在生产部署时于真实环境进行,不再作为本票待办)**。 ## 进度:100%(已关闭) 第十六轮远端核销(`origin/master=989a707e`)确认四条 AC 全部达成:原跨领域两项(G1 行业筛选、G2/G4 设备回联)已在远端提交,A–H 补契约经新地图切片票 11/12/13 关闭与真实环境部署复验全部回写,三条业务口径由裁定落地为代码。 - **2026-10-12 维护者裁定**:原 95% 待确认项「目标部署 `192.168.110.30:8301` 复验」**取消**——该服务器不是实际部署环境,实际线上环境另有服务器;免鉴权与真实接口行为将在**生产部署时于真实环境验证**,属部署验收而非本票范围。 - 据此本票按维护者裁定关闭为 **100%**;下文「下一步」的部署复验清单保留作生产部署时的参考检查表(原样可用于任意部署环境)。 ## 下一步(生产部署时的参考检查表) 原为目标部署复验而写的清单,随本票关闭转为**生产部署参考检查表**——实际线上环境部署免鉴权版本时逐项核对: 1. **确认部署包含提交 `8c0771a`(及后续切片提交)**。验证:部署机上 `git log --oneline -3` 或 jar 构建时间晚于 2026-09-28。 2. **无凭据 REST 实测**:浏览器无痕窗口或 `curl`(不带 Authorization)访问 `<生产地址>/api/cockpit/v1/foundation` 与任一业务端点。通过标准:HTTP 200 且 `data.readOnly=true`。 3. **WS 直订实测**:浏览器控制台建连 `<生产地址>/ws/deviceStatus` 后直接发 `{"type":"cockpitSubscribe","scope":"all"}`(不发 authenticate)。通过标准:收到 `cockpitSubscribed` 与后续增量帧。 4. **非法参数仍 400**:`GET /api/cockpit/v1/monitoring/overview?industry=NOPE`。通过标准:400 `INVALID_REQUEST`。 5. **非 GET 仍拒绝**:对任一端点 POST。通过标准:405(映射拒绝)或认证拦截,不产生业务写入。 6. **边界与回归自查**:① 携带**过期 token** 的 GET 仍应 200(匿名放行不受无效凭据影响);② 管理端任一写接口仍要求登录(未带凭据应 401);③ `workOrderReminder` 推送仍需 authenticate 帧(工单链路未受影响)。 7. 若生产验证发现问题,**另开缺陷票**并回链本票 Comment(本票已关闭,不再作为缺陷载体)。 **不在本票范围**:I2 数据时间(归新地图规格 08 的执行票);工单状态 javadoc 更正(后端顺手项);前端面板对接(归前端执行票 14/15/16);生产部署验证(按维护者裁定在生产环境进行)。 ## Comments - **关闭(2026-10-12,维护者裁定)**:第十六轮远端核销确认四条 AC 全部达成;原「目标部署 `192.168.110.30:8301` 复验」按维护者裁定取消——实际线上环境另有服务器,免鉴权与真实接口行为将在生产部署时于真实环境验证(上方清单转为生产部署参考检查表)。本票以 100% 关闭,I2 数据时间残留归新地图规格 08。 - **管网映射修复回写(2026-10-12)**:[管网编码与设施类型命名空间](../../cockpit-real-data-wayfinding/issues/20-20-0-1.md)已关闭。主修复740d896现场五端点管网集合一致为537燃气/996供水/3735排水(5268),未知计数归零、设施名称行业正确;审查P2/P3补齐29d1ae2与合并0a6b108已推送,管网专项29/29通过。同步远端前system187+admin441=628项全过;同步最新报警描述改动后报警生命周期出现1项顺序断言失败,本次管网未改相关文件,不宣称当前全量通过。说明与证据见[审查报告](../../cockpit-real-data-wayfinding/handoff/review-pipe-type-namespace.md)、[人工核验步骤](../../cockpit-real-data-wayfinding/handoff/manual-verify-pipe-type-namespace.md);阶段界面验收仍归真实联调收口票。 - 本轮已把真实数据接线的后续路线迁移到 [驾驶舱真实后端数据接线(决策地图)](../../cockpit-real-data-wayfinding/map.md)。票 25 继续作为历史契约事实台账和地图入口,不再单独拆泛化后端执行票。 - 本轮核对到后端 `HEAD=origin/master=355a8af`;文档记录的本机真实 HTTP/WS 证据已同步,但目标部署 `192.168.110.30:8301` 不可达,故本票保持 `ready-for-human`,不关闭。 - 新地图 02–06 仍未 resolved,且是 HITL `grilling` 决策票;#01 已解决并写回地图与本票,本票不代替其余票回答。 - 新地图 #01 已 resolved:首阶段改为报警—工单闭环读模型,后端拆为工单状态/处置率读模型、报警/工单回联读模型、实时同步三张切片票;驾驶舱只读 REST `/api/cockpit/v1/**` 与 WS `/ws/deviceStatus` 的免鉴权范围已由旧鉴权决策同步修订,本票承接后端实现与目标环境证据。 - 新地图 #02–#04 已 resolved:地图摘要状态筛选与未关联设备语义(设备级匹配/点位 OR 归并、多值 `pointStatus` 含 UNKNOWN/UNASSOCIATED、顶部状态栏全局组合入口、饼图、坐标汇总筛选后口径、自动分批加载 + 右上角手动刷新)、监测数据时间(`createdAt`=create_time 跨类型 max,三端点分区级/逐对象级,与 `sampledAt` 分离,空态不冒充)、real 生命周期(`dataSource` 只换 transport、与 mock 全同构、严格不回退 mock、刷新调度唯一权威)。对应规格子票 07/08/09 已发布为 `ready-for-agent`;仅剩 #06(异常统计/处置率/管理字段业务语义)待决策。 - **上位回写(2026-10-09,按决策 01「切片票关闭时回写」义务)**:后端三张切片票 11/12/13 已全部 resolved 并经**真实环境部署复验通过**(复验记录见 [票 17](../../cockpit-real-data-wayfinding/issues/17-postdeploy-live-verification.md))。①[票 11 工单状态与处置率](../../cockpit-real-data-wayfinding/issues/11-backend-work-order-rate.md):`basis=CLOSED_WORK_ORDERS_OVER_ELIGIBLE_WORK_ORDERS`(状态5÷状态0–6),提交 `3de679c`,实测 `num/den=2/3`、`sum(0–6)==分母`(基线卡片 02 至 ③)。②[票 12 报警/工单读模型 + district](../../cockpit-real-data-wayfinding/issues/12-backend-read-model-district.md):六族 `region`→`district`(编码+中文名双字段、脏值 400、`districtFilter` 回显),管理信息删 `organizations`/`ownershipDistribution`/`unmaintained`,工单逐张显式 `associatedWithCurrentEvent`,提交 `818a6d7`,复验 8 项全通过(基线卡片 03 至 ③)。③[票 13 报警/工单实时同步](../../cockpit-real-data-wayfinding/issues/13-backend-realtime-sync.md):新增 `cockpitWorkOrderStateDelta` 工单状态增量帧(扫描-比对-变化才推,首扫建基线不推送,`scanIntervalMs` 诚实标注延迟)+ 设备帧 `eventId` 透传,提交 `d8a6b03`,复验 6 项全通过——含真人操作 284 工单(3→4)**40 秒内帧到达**的端到端证据(基线卡片 04 至 ③)。**测试**:全量 8 模块 **422/422**(自基线 299 起累计 +123 例,含三切片全部契约测试)。**下游解锁**:后端切片 11–13 完成,前端执行票 14/15/16 的后端依赖全部就绪(15/16 的消费侧契约变更已写入各自票正文:`regionMap` 失效、管理信息字段删除、新帧契约)。**Gogs #63 的同文回写需负责人在远端执行**(本会话工具只达本地 Markdown 台账)。