backend-contract-gaps.md 14 KB

后端契约缺口交付包(供后端项目经理建票)

Status: ready-for-human Labels: ready-for-human Category: handoff Blocked by: None

本文件是 25: 后端契约缺口待办(跨领域两项 + 补契约清单) 的交付资产:把复核后仍然缺失的后端工作写成可直接建票的草案,交给后端项目经理排期,不需要 agent 再加工。

已建票(2026-09-18):五张草案已在 Gogs shaoy/pipe-ner-server 建成真实工单(标签 needs-triage,待后端 PM 排期与裁定):

草案 Gogs 票号 状态
BT-1 #59 ✅ 已交付并关闭(2026-09-18)
BT-2 #60 ✅ 已交付并关闭(2026-09-18,走路径①完整)
BT-3 #61 ✅ 已交付并关闭(2026-09-18)
BT-4 #62 ✅ 已交付并关闭(2026-09-18)
BT-5 #63 🔄 进行中(2026-09-18:map-snapshot 第 1/22 片已接真实库,票未关)

BT-6 为可选票,未建。若后端 PM 确认需要,再按下面草案建。

复核基线(2026-09-17,2026-09-18 第三轮复验无变化):

  • 后端仓库 E:\pipe-ner-server,本地 HEAD ed0ace5(test(cockpit): add contract integration environment and handoff (#43))。
  • 远端 origin HEAD 仍是 e2b4e45(#42)——#43 尚未推送,联调前请确认部署来源是其预期提交。
  • 复核方式:只读阅读控制器、响应类、适配器与 docs/cockpit/README.md;未改动后端任何文件,未跑构建或调试命令。

一、完成情况总览

票 25 列出的缺口,今天的状态如下(后端 Gogs #33–#43 已交付的切片):

项 内容 状态 证据
A1 跨设备当前事件流 ✅ 已交付 GET /api/cockpit/v1/events/current(mode 必填,level/industry/status/分页);CockpitCurrentEventsResponse.EventItem 含 eventNo/eventType/level/levelColor/status/value/unit/deviceCode/location/industry/longitude/latitude/workOrderSummary + sections{events,workOrders} + mapFilter.deviceCodes
A2 跨设备历史事件流 + 时间范围 ✅ 已交付 GET /api/cockpit/v1/events/history-analysis(eventFamily 必填 + startTime/endTime);回显 Range{type,startTime,endTime}
B 趋势时间范围可声明 ⚠️ 仅剩一处 monitoring/situation、infrastructure/operating-information、events/history-analysis、events/handling-efficiency、events/multidimensional-analysis 均已支持范围参数;overview/warning-settings 仍只有 mode(→ 见 BT-3)
C 响应/关闭时长聚合 ✅ 已交付 GET /api/cockpit/v1/events/handling-efficiency:averageDuration{value,unit,sampleCount,state,reason} + durationTrend[] + 工单 durationHours;口径已冻结 basis = CLOSED_WORK_ORDERS_OVER_TOTAL_EVENTS
D 应急保障域三件套 ✅ 已交付 GET /api/cockpit/v1/infrastructure/emergency-support
E 管理信息域 ✅ 已交付 GET /api/cockpit/v1/infrastructure/management-information
F 设施/行业运行信息 ✅ 已交付 GET /api/cockpit/v1/infrastructure/operating-information
G1 全局行业筛选落到地图点位 ❌ 未交付(且路径待裁定) map-snapshot 入参仍只有 page/pageSize/snapshotAt;但 /monitoring/distribution(#37)已带 industry/deviceType/pointStatus/region 与逐点 industry/deviceType(→ 见 BT-2)
G2 点位摘要补 industry、类型、徽标 ❌ 未交付 CockpitMonitoringPointSummary 仍只有 pointCode/pointName/pointStatus/statusReasons/longitude/latitude/coordinateValidation
G3 未关联设备补 industry、设备类型 ✅ 已交付 CockpitMonitoringDistributionResponse.UnassociatedEquipmentMarker
G4 设备编码回联点位(WS 增量可用) ❌ 未交付 四个增量 DTO 均只有 deviceCode + 状态,无 monitoringPointCode(→ 见 BT-1)
H 跨设备设备状态清单 ✅ 已交付 GET /api/cockpit/v1/monitoring/situation:abnormalEquipment[]{deviceCode,deviceName,deviceType,industry,region,abnormalType,status,statusReasons,longitude,latitude,coordinateValidation} + 分页 + mapFilter.deviceCodes

另有 #43 交付的移交与联调手册:docs/cockpit/README.md(契约总则、字典冻结、端点清单、分页/快照/错误口径、WebSocket 增量、启动与联调检查表、容器化评估、已知未验证项)。这份手册本身已解答了票 25 里「字段名、语义、字典」类的问题,不需要再建票。

二、真实数据接线状态(程序级缺口)

后端目前交付的是契约,不是数据:

  • 23 个 cockpit 适配器接口中,22 个只装配了 Empty*Adapter(@Service,直接返回 ...Snapshot.empty(...))。
  • 唯一接入真实数据的是工单读模型:BusinessCockpitWorkOrderReadAdapter(@Primary,覆盖 EmptyCockpitWorkOrderReadAdapter)。
  • 各切片在 docs/cockpit/ 下的 *-demo.html 用的是内嵌 fixtures,不代表真实库数据。
  • 计数口径:若不计 /foundation 契约自检,则为 22 个读模型接口 / 21 个空实现。

后果:前端把适配层切到真实接口后会拿到全空快照(200 + freshness.state = EMPTY),mock 阶段不受影响。这项工作需要一个程序级排期(→ 见 BT-5)。

三、建议新建的后端工单

以下每节即一张工单草案,标题与正文可直接复制到 Gogs(shaoy/pipe-ner-server)。顺序即建议优先级。

BT-1 Cockpit device-to-point linkage(REST + WebSocket)→ Gogs #59 ✅ 已交付

背景与证据

  • CockpitMapSnapshotService.monitoringPoint() 只把 CockpitMapSnapshot.SourceMonitoringPoint.devices 用于解析点位状态,没有写进响应;CockpitMonitoringPointSummary 没有任何设备字段。
  • WS 增量只带 deviceCode:CockpitMonitoringDistributionDeviceStatusDelta、CockpitMonitoringOverviewDeviceStatusDelta、CockpitMonitoringSituationDeviceStatusDelta、CockpitOverviewMonitoringDeviceStatusDelta 四个 DTO 均无 monitoringPointCode;DeviceStatusWebSocketHandler 全文无点位字段。
  • 事件读模型的行也没有归属点位:CockpitCurrentEventsResponse.EventItem 与 history-analysis 的 row 都缺 monitoringPointCode。
  • 现有可用但代价高的替代路径:GET /monitoring-points/{monitoringPointCode} 的 devices[].deviceCode(逐点 N+1)。
  • 后端内部已持有该映射(SourceMonitoringPoint.devices;applyDeviceStatusDelta 能按 deviceCode 解析到点位),因此改动量集中在响应层。

要做什么(建议 ①+②,③ 视事件面板需要)

  1. CockpitMonitoringPointSummary 增加 deviceCodes(关联设备编码列表),并顺带补 industry 与 typeCode。
  2. WS 增量帧增加 monitoringPointCode(未关联设备为 null / 不出现)。
  3. 事件读模型行增加 monitoringPointCode 与 monitoringPointName。

验收标准

  • 点位摘要返回关联设备编码;同一 snapshotAt 下与 /monitoring-points/{code} 的 devices[] 一致,且不产生重复点位。
  • WS 增量给出 monitoringPointCode;未关联设备显式 null,不静默丢失。
  • 事件行返回 monitoringPointCode,无归属时为 null。
  • 契约测试覆盖 REST 与 WS 两侧;docs/cockpit/README.md 与字段字典同步更新。

解除阻塞的前端票:15(WebSocket 状态联动)、08(地图摘要)、19(当前预警 / 历史分析上图联动)。

BT-2 全局行业筛选落图:路径裁定 + 落地 → Gogs #60 ✅ 已交付(走路径①完整)

背景与证据

  • CONTEXT.md 定义行业筛选是作用于整个驾驶舱的全局条件。
  • GET /map-snapshot 没有 industry 入参;CockpitMonitoringPointSummary 也没有 industry/类型字段,服务端与客户端都无从过滤。
  • 但 GET /monitoring/distribution(#37)与 GET /monitoring/overview 已支持 industry/deviceType,distribution 还逐点返回 industry/deviceType 并给 mapFilter{industry,deviceType,pointStatus,region,pointCodes,deviceCodes}。

要做什么(二选一,并在 docs/cockpit/README.md 第 3 节写明结论)

  1. 给 map-snapshot 增加 industry(以及 deviceType)入参,并给 CockpitMonitoringPointSummary 补 industry/typeCode;或
  2. 正式声明地图筛选以 /monitoring/distribution 为准,map-snapshot 保持纯分页快照,前端改取数路径。

验收标准

  • 决策结论写入契约手册,前端不需要猜路径。
  • 选定路径端到端可用:服务端完成过滤,mapFilter 回显实际生效范围,分页与 snapshotAt 语义不变。

解除阻塞的前端票:18(运行监测面板,含验收项「面板筛选可作用于地图点位」与监测点台账)、08(地图摘要)。

BT-3 warning-settings 趋势窗口可声明 → Gogs #61 ✅ 已交付

背景与证据:其余切片都已接受时间范围并回显 Range,只有 GET /overview/warning-settings 仍只有 mode;CockpitOverviewWarningSettingsResponse.Range{type,start,end} 结构已存在,窗口目前固定。

要做什么:给该端点增加 range / startTime / endTime 入参,填充 Range 与 trend[].bucket,沿用兄弟切片的范围语义。

验收标准:非法范围返回 400 INVALID_REQUEST;range 回显实际生效区间;趋势桶跟随窗口变化;契约测试与手册同步。

解除阻塞的前端票:20(态势总览近 7 日趋势)、总体概览的预警设置面板。

BT-4 事件行补 coordinateValidation 与报警阈值 → Gogs #62 ✅ 已交付

背景与证据:字典已冻结「无效或未验证坐标 renderable=false,禁止渲染」,CockpitMonitoringDistributionResponse、CockpitMonitoringSituationResponse 等都已携带 CockpitCoordinateValidation;但 CockpitCurrentEventsResponse.EventItem 只有 longitude/latitude,没有 coordinateValidation,事件因此无法判定能否上图。A1 原建议中的 thresholdMinValue/thresholdMaxValue(仅报警族)同样缺失。

要做什么:事件读模型(events/current 与 events/history-analysis)的行补 coordinateValidation;报警族在数据可得时补阈值字段。

验收标准:每条事件携带 coordinateValidation(state/reason/renderable/crs);坐标缺失或未验证时 renderable=false 且有 reason;契约测试与手册同步。

解除阻塞的前端票:19(当前预警上图、历史分析定位)。

BT-5 真实数据接线(程序级) → Gogs #63

背景与证据:见上文「二、真实数据接线状态」——23 个适配器接口中 22 个仍为空实现(不计 /foundation 自检则 21/22)。

要做什么:按切片补真实适配器(复用既有表与服务,遵循 cockpit-backend-read-contracts spec 的「先组合既有表与服务,测量后再加投影/索引」)。建议优先级:先地图与监测链路(map-snapshot、monitoring/distribution、monitoring/overview、monitoring/situation、monitoring-points/{code}),再基础设施三切片,最后预警处置四切片(其中工单链路已接)。

验收标准:每个切片存在非空适配器并被 Spring 装配;用真实库跑通 docs/cockpit/README.md 第 6 节的联调检查表 1–7;snapshotAt 分页稳定、监测点不重复;空结果仍走 200 + freshness.state=EMPTY,不用 5xx 表达空。

解除阻塞:所有前端票「接真实接口」的环节(mock 阶段不受阻)。

BT-6(可选,待确认)situation 支持 monitoringState 过滤

背景:H 的原始需求是「跨设备设备状态清单(如离线设备清单)」。/monitoring/situation 已给出分页的 abnormalEquipment[],但它按 industry/deviceType/时间过滤,没有 monitoringState 入参。

要做什么:若 operationOverview 的离线设备清单需要按状态取数,给 situation 增加 monitoringState(六态字典)入参。

验收标准:传 OFFLINE 只返回离线设备;mapFilter 回显;不改变默认行为。

备注:若 abnormalEquipment 已满足面板需求,此票不必建。

四、需要业务方口径(不是后端工单)

  1. 「故障」是什么? 字典现状:点位六态 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(已结案工单数 ÷ 事件总数,见 docs/cockpit/README.md 第 2 节)。需业务确认这是否即所说的处置率(含已取消事件)。
  3. 「管理单位」与 maintainer:management-information 以 organizations + ownershipDistribution + unmaintained 建模,与维护单位分开。需业务确认这一区分并回写术语表。

五、给项目经理的决策点

  1. G1 的落图路径二选一(BT-2 的两个方案)。 已裁定(2026-09-18):走路径①——地图以 map-snapshot 为准,且补全 industry/region/deviceType 三入参与 mapFilter 回显;结论见 docs/cockpit/README.md 第 3 节。
  2. G2/G4 的实现取一或全做(BT-1 的 ①②③)。 已全部实现:BT-1(#59)交付 G4 三件套,BT-2(#60)交付 G1+G2。
  3. 真实数据接线的排期与责任人(BT-5 #63)——这是当前唯一剩下的后端缺口(BT-1…BT-4 均已交付关闭)。
  4. 提醒:后端本地 #43 未推送,远端仍是 #42;联调前请确认部署来源提交。
  5. 提醒:各切片 *-demo.html 是 fixtures,不是真实数据;手册第 7/8 节的容器化与性能均为未验证项。