map.md 31 KB

驾驶舱真实后端数据接线(决策地图)

Status: open Labels: wayfinder:map

本 effort 先产出跨前后端真实数据接线所需的决策,再为已收口的决策创建前端/后端执行票。地图不直接修改后端代码;后端执行票需在后端仓库、负责人和权限明确后开启。

Destination

为 /cockpit 四个只读一级模式建立一条可验收的真实数据接线路线:报警—工单闭环读模型 → 地图摘要 + 运行监测 → 基础设施 → 预警处置 → 总体概览。报警—工单阶段由外部业务系统执行工单流程,驾驶舱只读取并实时呈现真实报警、工单关系和状态,不提供任何写操作。

目的地达成的判据:后端契约与真实适配器已提交并通过测试,前端 real 生命周期与 mock 同构,真实联调基线(提交版本、环境、认证、只读数据源)已锁定,筛选/分页/快照/推送/空态/失败态语义通过验证,并完成真人团队的真实设备报警闭环验收;real 失败不回退 mock。

Notes

  • Domain:城市生命线 Web 驾驶舱。术语以 CONTEXT.md 为准;监测点、监测设备、地图摘要、快照、异常点不可混用。
  • 复用现有事实台账:后端契约缺口待办 及其 后端契约缺口交付包。后端 Gogs 真实数据接线(程序级)作为上位来源,但不作为唯一笼统执行票;后续按切片拆分粒度明确的后端票,并注明承接关系。
  • 已确认推进顺序:报警—工单闭环读模型 → 地图摘要 + 运行监测 → 基础设施 → 预警处置 → 总体概览。
  • 首阶段由外部业务系统完成工单流程,驾驶舱只读消费报警、工单、设备和监测点关系;后端拆为工单状态与处置率读模型、报警/工单回联读模型、实时同步三票,前端另建对应迁移/接线/实时消费票。
  • 已确认运行策略:默认 mock;real 必须由部署配置显式开启;真实请求失败只影响对应分区,不回退 mock,也不牵连其它分区。
  • 已确认业务口径:处置率 = 状态 5(已结案)工单数 / 状态 0–6 工单数,状态 7(取消)排除;数据库 create_time → Java createTime → API createdAt → 前端“数据时间”;maintainer、district、ownership_unit 各自保持字段语义,历史“责任区域”不属于本次目的地。
  • “异常”允许按监测点、监测设备/指标分别统计各自异常集合;预警处置地图的“异常点”仍只由设备 WARNING/ALARM 回联决定,不因统计总称扩大可见范围。
  • 驾驶舱鉴权范围已修订为只读 REST /api/cockpit/v1/** 与 WS /ws/deviceStatus 不鉴权;后端其他路径与未来写接口不受此变更影响。权威记录见旧鉴权决策与 ADR 0005,票 25 承接后端执行证据。
  • 技能:grilling、domain-modeling、research;决策票逐张处理,决策完成后再创建执行票。
  • 本地 tracker 仅支持 Markdown 的 Blocked by: 依赖表达,没有独立原生建边接口;本图按 tracker 规则落依赖并在建图后校验数量。

任务清单

Decisions so far

  • 前端执行票 —— 报警–工单闭环消费(事件/工单状态/时间线/处置率/异常点) — 真实响应消费与mock已对齐,处置率零工单分母不适用、异常桶分对象、0–7时间线与独立工单增量/报警重取已接入;契约和Pinia回归通过,8001 mock浏览器验收完成,真实联调归阶段收口票。
  • 15: 前端执行票 —— 数据时间展示 + 片区/行业维度 + 管理面板片区化 — 前端消费侧已切换 createdAt/sampledAt、district/districtFilter 与窨井词汇;管理面板改为片区×行业设施/设备计数;T15 契约闸门 11/11 通过,8001 mock 浏览器走查确认数据时间、未分区、窨井和管理计数。
  • 14: 前端执行票 —— real 生命周期接线 + 状态筛选/自动加载/饼图 — 前端实施与 8001 浏览器验收完成(t08 15/15、t18 40/40、补充 7/7);多选 OR、饼图高亮、命中子集与 real 分区不可用语义已验证,正式后端业务联调归票 18。

  • 01: 报警—工单闭环读模型与 Gogs 票拆分边界 — 首阶段只读消费外部业务系统的报警/工单真实关系与状态;后端拆为工单状态与处置率、报警/工单读模型回联、实时同步三票,前端另建三票;真人团队的真实设备报警闭环是阶段总收口。

  • 02: 地图摘要状态筛选与未关联设备语义 — 行业/范围/类型=设备级匹配、点位 OR 归并;状态筛选对监测点按聚合六态、对未关联设备按设备状态词表各自匹配;「无关联设备」桶=只看该类对象;pointStatus 多值(含 UNKNOWN/UNASSOCIATED);顶部状态栏=全局组合筛选入口(八桶 OR,计数为全局未筛全集);饼图共用同一份分布;坐标汇总按筛选后口径;移除加载下一页、自动分批加载,右上角留 🔄 手动刷新;刷新时机=筛选变化/新鲜度 tick/WS 增量。

  • 03: 监测数据时间字段与异构设备来源 — createdAt=记录创建时间(create_time,跨类型 max);三端点:overview 分区级、distribution 信封+台账逐对象、situation 信封+异常设备逐对象;sampledAt(采样/上报时刻)与 createdAt 并存分离;空态显式 null 不冒充;前端“数据时间/采样时间”两套标签;archive 不加 createTime;refresh 时机归 #04;更正:/overview/monitoring 的 metricFreshness 已真实接线(固定 CURRENT)。

  • 04: real 生命周期与 mock 同构启动契约 — dataSource 只换 transport:real 照搬 mock 全部自动初始化(地图第 1 页、四模式面板、WS 直订、新鲜度 tick);失败同套分区语义(UNAVAILABLE)、严格不回退 mock;未配 baseUrl 如实报 NO_BASE_URL;WS 只定连接生命周期(增量帧解析归 #01);刷新调度以本票为唯一权威(02/03 引用);失败不无限重试;验收为端到端证据。

  • 05: 真实联调基线与收口证据门槛 — 基线锚点=仓库提交(分支+哈希+已推送 Gogs);联调判定环境=本地 192.168.110.96:8301 可达,本地通过后再提交;目标部署移出本阶段;四态阶梯(接口 200 / 契约已接 / 真实数据联调完成 / 模式整体收口)+ 缺项即降级明写原因;卡片落 handoff/baselines/<切片名>.md(纯 Markdown + 可复制命令,追加不覆盖,只记角色与出处);第一张样板卡 地图摘要+运行监测 已产出(实测:免鉴权 200 达标,pointStatus 被忽略、三端点无 createdAt,状态至 ①)。

  • 06: 异常统计、工单处置率与管理字段词汇 — 异常统计:监测点桶 ALARM/WARNING/OFFLINE/EMPTY、设备/指标桶 WARNING/ALARM/EXPIRED/OFFLINE/UNKNOWN(按对象计数不相加、成功响应缺失桶显 0);异常点(预警处置地图)只认设备 WARNING/ALARM 回联(宽清单窄地图);处置率=状态5 ÷ 状态0–6(范围=当前筛选全部工单,分母 0 显示不适用,basis 改为工单分母语义、旧"事件总数"口径废止);本项目维度只有片区(district 0/1/2→城南/城北/太常,空/乱码=未分区,取代 organization 与 regionMap)与行业(供水/排水/燃气/窨井);管理信息面板改片区×行业视图、后端删 organizations/ownership/unmaintained;档案 ownershipUnit/maintainer 留作静态信息;「责任区域」=片区别名,历史票 17 验收文字作废;票 25 已回写 E1/处置率/异常口径。

  • 11: 后端执行票 —— 工单状态与处置率读模型对齐 — 处置率分母由事件总数改为状态 0–6 工单数(状态 7 排除;范围=当前筛选内全部工单,按 work_order.create_time 界定,不要求关联报警/事件),basis 改 CLOSED_WORK_ORDERS_OVER_ELIGIBLE_WORK_ORDERS,分母 0 → EMPTY+NO_ELIGIBLE_WORK_ORDERS;三处同族分母一并修订(handling-efficiency / history-analysis 仅汇总 / overview warning-settings 两 family 共用),状态分布同步改工单口径使 sum(0–6)==分母 可复算;口径单源收敛到 CockpitWorkOrderStateDictionary,三个 snapshot 新增 scopeWorkOrders(旧快照只带已关联事件工单,结构上给不出该分母)。工单字典 0–7 本已对齐、复用之。提交 3de679c 已推 origin/master,编译通过、Cockpit*Test 299/299。部署后真实环境复验已移交 票 17 滚动承载,本票按自身交付物收口。

  • 12: 后端执行票 —— 报警/工单读模型、设备–监测点回联 + district 片区契约 — 旧自由串 region(实测恒为「未分区」、适配器写死 null)被片区 district 取代:权威来源=equipment_base.district(0城南/1城北/2太常),点位按「经其上挂设备归纳」(不一致/无设备→未分区)、设施无来源一律未分区——不加 DDL、不用行业或管理单位冒充;响应形态=district(Integer,未分区 null)+districtName,筛选入参 district=0|1|2|UNASSIGNED(脏值 400),mapFilter 增 districtFilter(NONE/ASSIGNED/UNASSIGNED,区分「未筛」与「只看未分区」这两种编码同为 null 的情形);口径单源 cockpit/foundation/CockpitDistrict.java。六族统一改造(地图摘要、运行监测 distribution+situation、基础设施 base-archives、事件多维分析);管理信息按 #06 删字段 organizations/ownershipDistribution/unmaintainedCount 改 districtIndustry[](片区×行业)。工单读模型:设备维度返回已有全部工单并逐张加显式 associatedWithCurrentEvent + 顶层 unassociatedWorkOrderCount(满足「未关联当前报警明确提示」);关联键经真实库核实为 alarm_data.work_order_id = work_order.order_id(维护者原述 alarm_no = order_no 实测命中 0 条、两列均不存在)。提交 818a6d7 已推 origin/master,组合测试 372/372,部署后真实环境复验 8 项全通过(基线卡片 03 至 ③)。教训:复验中曾因控制台把 32 位十六进制串统一渲染成 0 而误判 alarm_data.id 为占位值并提交改动,经 count(DISTINCT)/直方图/base64 复核后撤回(18db910)——判「相同/为零」不可凭肉眼读控制台。前端消费侧必须同步(已通知 票 15)。

  • 13: 后端执行票 —— 报警/工单实时同步 — 工单状态增量从无到有:新增 cockpitWorkOrderStateDelta 帧(CockpitWorkOrderDeltaPushTask,定时扫描 work_order.order_status 逐单比对——状态流转不写 update_time,靠时间过滤会漏掉全部流转),变化才推给驾驶舱全量订阅会话(免鉴权、不按人过滤,与管理端 workOrderReminderPush 提醒语义隔离);首扫只建基线不推送(REST 才是初始快照);帧带 scanIntervalMs(默认 60s 可配)诚实标注延迟上限、不带会误导的 updateTime、不泄漏主键 orderId(对外键 workOrderCode,与 REST 读模型同口径);stateCode/stateName 出自票 11 字典单源,脏码名称显式 null。设备帧 cockpitDeviceStatusDelta 补 eventId 透传(缺省显式 null;zk-api-service 是否真发未证实,防御性透传不臆造)。REST 快照复用票 11/12 读模型无新端点;降级纪律(无订阅不查库、失效会话清理、断线重订)有测试锁定。提交 d8a6b03 已推 origin/master,针对性 21/21 + 全量 422/422,部署后复验 6 项全通过——含端到端正面证据(真人提交验收 284 工单 3→4,40 秒内帧到达、字段全对)与两项负向证据(无变化不推送;只改 update_time 不改状态码的「处置」不触发,证明检测由 orderStatus 驱动)。前端消费归 票 16(对未知帧静默忽略,不升级不会崩)。

  • 17: 部署后真实环境复验(后端切片 11–13,滚动复验票) — 按维护者裁定作为贯穿 11–13 的滚动复验票单独承载部署后证据:三切片全部复验通过(11:处置率新口径 num/den=2/3 自洽;12:district 契约 8 项;13:增量帧 6 项含真人触发端到端),三张基线卡片 02/03/04 均升至 ③ 真实数据联调完成;全量测试自基线 299 增至 422/422。滚动使命完成故收口;决策 01 的真人闭环演示归阶段总收口(票 18 上位阶段),上位回写(票 25/Gogs #63)已按决策 01 执行。复验方法论沉淀:负向观察必须闭环(说「没收到帧」须同时复查库证明「确实没变化」);临时探针一律放 %TEMP% 用完即删(不进 git 跟踪目录);控制台渲染不可作为「值是否相同」的证据。

  • 28: 后端执行票 —— 无关联设备监测点被静默丢弃(计数不对称) — 维护者裁定方案 A(2026-10-10):无关联设备的监测点是合法监测点,按其真实「无关联设备 / EMPTY」状态计入监测点总数与状态分布(EMPTY 桶),不得静默丢弃;方案 B(仅记入 excluded 新计数、界面仍显示 0)不采纳。配套澄清两条术语:无设备点位是合法点位,类型/片区无法经设备推导时如实显示未分区/未知,不伪造归属;坐标能否上图只决定呈现,不决定是否计入统计——坐标未校验的对象仍参与计数、分布与筛选。根因为 CockpitMonitoringDistributionService 点位循环按 devices.size() 累加排除计数,无设备点位计 0 而被抹除(设备侧同分支按自身计 1,口径不对称);连带 NO_RESOLVED_DEVICES 把「设备坐标未校验」误报为「无设备」。CONTEXT.md 的「点位状态」「无地图位置」两条已就地澄清。

Not yet specified

  • 首批真实接线完成后,基础设施四个面板各自需要哪些真实适配器、district/ownership_unit 的筛选与展示边界,以及井盖(MANHOLE)跨端是否已可用。
  • 预警处置的事件读模型、设备异常回联、时间线展示与处置率聚合在真实后端中的切片拆分和数据稀疏降级。
  • 总体概览缺失的前端面板实现、聚合端点与其对基础设施/运行监测/预警处置的复用关系。
  • 后端真实数据库快照中坐标校验、设备—监测点关联稀疏和空数据的最终演示样本。

Out of scope

  • 登录、权限管理、工单处置等写操作。
  • 将历史“责任区域”验收文字复活为本次字段,或用 district、industry、maintainer 冒充责任区域。
  • 用前端本地过滤替代后端 map-snapshot 的状态筛选;不得把未加载分页的数据静默删掉。
  • 失败时静默回退 mock,或把 mock 走查结果当成真实后端联调证据。
  • 重写既有 mock 面板、模式词典、地图/相机决策和已关闭的前端实现票。
  • 移动端、写操作业务、UE5、Docker、国产化认证及非驾驶舱领域。

Current status

6/6 决策票已解决 + 4 张规格子票 + 后端执行票 11/12/13 全部收口并复验通过(滚动复验票 17 亦收口)。 决策 01–06 收口;规格 07/08/09/10 为 ready-for-agent;执行票 11/12/13 已 resolved 且真实环境复验全部通过(基线卡片 02/03/04 均至 ③)、17 已 resolved(三切片滚动复验完成),14–16(前端契约/mock实现,后端依赖已全部就绪)、18(前端真实接口联调与阶段收口,依赖 14–17,仅剩 14–16)。第一张联调基线卡 地图摘要+运行监测 状态至 ①;真实联调与阶段收口由 18 统一承载。

2026-09-28 追加(免鉴权已落地,未提交):免鉴权范围已按 ADR 0005 修订实现——后端(E:\pipe-ner-server 工作树):SecurityConfig 放行 GET /api/cockpit/v1/**、24 个 cockpit 控制器移除方法级认证、WS 协议注释与手册对齐"cockpitSubscribe 直订无需 authenticate"(authenticate 帧保留给管理端工单推送);新增 CockpitAnonymousAccessSecurityConfigTest 等回归。前端(本仓库):cockpitApi 不再发送 Authorization,runtimeSocket open 后直接 cockpitSubscribe(无 authenticate 帧)、token 链路下线,mock/文档/验证脚本同步。验证:前端 t15 43/43、t04、t08 通过;后端改动未跑 Maven,且前后端均未提交——票 05 的联调基线只需补提交哈希/环境/数据快照,但免鉴权的真实 HTTP/WS 复验(无凭据 200、WS 直订)须在部署后进行。落地明细见 票 25 第十五轮。

后端最新基线(2026-10-09 票 12 复验后更新):E:\pipe-ner-server 的 origin/master=818a6d7(工作区干净,已推送;含本图 3de679c、票 12 的 ee2e1b6+18db910 与上游 7df9a87);联调环境 http://192.168.110.96:8301(= 本机,IDE 内运行的 Spring Boot 进程)实测可达、免鉴权只读接口全部 HTTP 200,且已加载新构建(进程 PID 15244)。目标部署 192.168.110.30:8301 已按决策票 05 移出本阶段,不再作为收口条件。

票 25 已同步为本图入口和历史契约台账,最新事实见 25: 后端契约缺口待办 与 交接包。执行票 11–13(后端)与 14–16(前端)已发布;后端票待负责人、Gogs 提交基线与联调环境确认后认领,前端票可认领。联调基线卡片的格式与第一张样板卡已就绪,后续切片按模板追加。不把未提交工作树或 mock 走查当成真实联调证据。

2026-10-08 执行票 11 已收口(resolved);复验抽为票 17:11 工单状态与处置率读模型对齐 诊断 + 口径修订 + 契约测试 + 提交推送全部完成——工单字典 0–7 本已对齐(新增逐码锁死测试);处置率分母由事件总数改为状态 0–6 工单数(状态 7 排除,范围=当前筛选内全部工单、按 work_order.create_time 界定),basis 改为 CLOSED_WORK_ORDERS_OVER_ELIGIBLE_WORK_ORDERS,分母 0 → NO_ELIGIBLE_WORK_ORDERS,并在维护者裁定下同口径修订三处(handling-efficiency / history-analysis 汇总 / overview warning-settings 两 family 共用);关键结构性事实:旧 snapshot 只携带已关联报警的工单,给不出该分母,故三个 snapshot 新增 scopeWorkOrders。后端 E:\pipe-ner-server 14 个源文件改动,编译通过、Cockpit*Test 299/299 通过(提交后复跑一致)。提交与推送:3de679c(本票口径修订)+ 9380c1b(非本票:修复 HEAD 中 CockpitFreshnessSemanticsControllerTest.java 未闭合语句导致 zksy-admin 测试模块无法编译,单独成提交)→ origin/master 5b53a6d..9380c1b;基线卡片 02 工单状态与处置率读模型 已产出。

为解阻塞而做的收口拆分:「新契约在部署环境生效」需要一次真实部署才会发生,把它留在票 11 会让「已完成的实现」绑住「尚未发生的部署」,无谓阻塞票 12/13。故抽为独立票 17 部署后真实环境复验(ready-for-human,Blocked by: 11),票 11 按其自身交付物 close;票 12 阻塞随之解除。票 17 不阻塞 12/13,且票 12/13 落地后的复验并入票 17 同一部署窗口。

勘误(2026-10-08):早先写入本图与两处票面的复验预期「ALARM 组 denominator=2、value=0.5000」错误。该 2 由旧响应 stateCounts(0=1, 5=1)反推,而旧 stateCounts 只累积已关联报警的工单(未关联者直接 continue 跳过)且按事件累加(同一工单多事件重复计);新口径分母取自 scopeWorkOrders(范围内全部工单,含未关联报警者),两者基数不同、不可互推。复验判据已改为自洽性:basis 为新值、sum(workOrderStateCounts[0..6]) == denominator、denominator ≠ totalEvents、分母 0 时 reason=NO_ELIGIBLE_WORK_ORDERS。前端 contractMocks.js 的处置率分母/hint 文案仍是旧口径,归执行票 14–16。

2026-10-08 票 17 复验:票 11 切片已通过(③ 达成)。部署基线 origin/master = 89ca989(含 3de679c 与上游 7df9a87),进程 18:39:11 重启后实测:

复验项 实测 判定
events/handling-efficiency?eventFamily=ALARM basis=CLOSED_WORK_ORDERS_OVER_ELIGIBLE_WORK_ORDERS、num/den=2/3、value=0.6667、sum(状态0–6)=3==分母、totalEvents=6≠分母 通过
events/history-analysis?eventFamily=WARNING 汇总 num/den=2/3;行级仍 reason=NO_EVENTS(事件桶未变) 通过
overview/warning-settings warning / alarm 均 num/den=2/3(两 family 同源);事件计数各算(10 / 6) 通过

数据稀疏事实:work_order 仅 3 行(状态 1×1、5×2),分母即为 3 —— 故实测分母为 3 而非勘误前预期的 2,进一步确证判据须用自洽性而非固定数值。基线卡片 02 阶梯升至 ③ 真实数据联调完成;④「模式整体收口」仍待真人验收(决策票 01)与前端接线(14–16)。

票 17 定位(维护者裁定):作为贯穿票 11–13 的滚动复验票,保持开放(in-progress),票 12/13 落地并部署后在同一票、同一部署窗口追加,不另开复验票;故本票未记入 Decisions so far(未关闭)。票 11 切片结果单独记于其「复验进度」表。

复验窗口故障(已解决,教训留存):重启窗口内 5 个只读端点(events/* 与 overview/warning-settings)曾 500,根因是数据库表结构重构与 Java 层不匹配 —— app_user.equipment_warning_type 已改为关联表(equipment_type_id + warning_type_id),元数据移到新表 app_user.warning_type;app_user.alarm_data.warning_type 列已删除。该重构由上游 7df9a87「优化报警管理」完整修复(新增 EquipmentWarningType 实体、AlarmData 去 warning_type 并加非持久化 warningName、WarningThresholdServiceImpl 与 4 个 XML mapper 一并改到新结构)。本会话曾基于落后基点 9380c1b 做局部修复(分支 fix/cockpit-warning-type-split),确认上游已有完整解后已废弃(未推送、无损失)并跟随 master。教训:复验前必须先 git fetch 确认远端基线,不要在落后基点上把上游的新结构误诊为「改了一半」。

2026-10-08/09 执行票 12 已实施、推送并复验通过:12 报警/工单读模型、设备–监测点回联 + district 片区契约 诊断 + 六项维护者裁定 + 实施完成 —— 把旧自由串 region(实测恒为「未分区」,适配器写死 null)改为权威片区 district:新增口径单源 cockpit/foundation/CockpitDistrict.java(归一/点位归纳/入参解析/匹配),六族统一改造(地图摘要、运行监测 distribution+situation、基础设施 base-archives、事件多维分析),响应形态为 district(Integer,未分区 null) + districtName,筛选入参 district=0|1|2|UNASSIGNED(脏值 400),mapFilter 增 districtFilter(NONE/ASSIGNED/UNASSIGNED,用于区分「未筛」与「只看未分区」这两种编码同为 null 的情形)。管理信息按决策 06 删字段 organizations/ownershipDistribution/unmaintainedCount/organizationCount,改 districtIndustry[](片区×行业)。工单读模型新增逐张 associatedWithCurrentEvent + 顶层 unassociatedWorkOrderCount,满足「未关联当前报警的工单明确提示」。提交 818a6d7 已推 origin/master(89ca989..818a6d7),组合测试 372/372,部署后真实环境复验 8 项全通过(基线卡片 03 至 ③)。本票已 close,票 13 阻塞解除。

关键事实:只有 equipment_base 有 district(7 行全非空 0→4/1→2/2→1);monitor_point 无该列、PipeNetworkBase 无该字段、equipment_point_rel 实测 0 行 —— 故点位按「经其上挂设备归纳」、设施一律未分区,如实呈现、未加数据库列、未用行业或管理单位冒充(维护者裁定)。关联键经真实库核实为 alarm_data.work_order_id = work_order.order_id(维护者原述 alarm_no = order_no 命中 0 条且两列均不存在,已按数据库事实裁定)。

验证与状态(票 12 收口):48 个文件改动 + 1 个新增;编译通过、组合测试 372/372(早期 311 的统计漏掉 Business*AdapterTest 一族,已修正口径)。分支经复验后合入 master 并推送(818a6d7),部署后真实环境复验 8 项全通过,票 12 已 close。前端消费侧必须同步(已通知 执行票 15):regionMap 配置映射失效、管理信息三字段消失、NO_ORGANIZATIONS 改名 NO_RELATIONS。测量教训:复验中曾因控制台把 32 位十六进制串统一渲染成 0 误判 alarm_data.id 为占位值并提交改动,经 count(DISTINCT)/直方图/base64 复核后撤回(18db910)——判「相同/为零」不可凭肉眼读控制台。

2026-10-09 执行票 13 已收口(含部署复验),滚动复验票 17 亦收口:13 报警/工单实时同步 诊断 + 2 项维护者裁定(① 实现 cockpitWorkOrderStateDelta 工单状态增量帧;② 设备帧补 eventId 透传)+ 实施 + 复验完成。诊断证实:唯一工单推送 workOrderReminderPush 是管理端提醒(需鉴权+按人过滤),驾驶舱收不到——印证决策 01 预判;且 work_order.update_time 在状态流转时不更新(transition() 只 set orderStatus、无 FieldFill),增量检测必须逐单比对 orderStatus。新增 CockpitWorkOrderDeltaPushTask:定时扫描(60s 可配)+ 逐单比对 + 变化才推给全量订阅会话(免鉴权,不按人过滤,与管理端提醒语义隔离);首扫只建基线不推送(REST 才是初始快照);帧带 scanIntervalMs 诚实标注延迟上限、不带会误导的 updateTime、不泄漏主键 orderId(对外键 workOrderCode,与 REST 读模型同口径);stateCode/stateName 出自票 11 字典单源,脏码名称显式 null。设备帧 cockpitDeviceStatusDelta 补 eventId 透传(缺省显式 null;zk-api-service 是否真发未证实,防御性透传不臆造)。范围 1 REST 快照复用票 11/12 读模型无新端点;降级纪律(无订阅不查库、失效会话清理、断线重订)有测试锁定。提交 d8a6b03 已推 origin/master(4ef2159..d8a6b03),针对性 21/21(新增 8 例)+ 全量 422/422。部署复验 6 项全通过(实例 PID 20240 @ 13:41):WS 回执正常;无变化不推送(75 秒订阅窗口 + 库状态对照闭环);真人提交验收 284 工单(3→4)→ 40 秒帧到达(延迟 < scanIntervalMs=60000 标注上限,workOrderCode/stateCode=4/stateName=待验收/deviceCode 全对,帧内无 orderId/updateTime,items 只含变化那一张);且 13:55:47 一次只改 update_time 不改状态码的「处置」不触发帧(检测由 orderStatus 驱动的正面证明)。基线卡片 04 报警/工单实时同步 升至 ③;票 17 三切片(11/12/13)复验全部通过、滚动使命完成故收口。上位回写已按决策 01 执行(票 25 已回写三切片证据;Gogs #63 同文回写需负责人远端执行)。后端三切片全部完成;剩余前端 14–16 与阶段收口 18,真人闭环演示归阶段总收口。