09-task-backend-device-coordinate-contract.md 12 KB

任务 —— 向后端确认/补齐「点位下设备的坐标与状态」契约

Type: task Status: resolved Labels: wayfinder:task Blocked by: 01

进度:100%

已认领(claimed);第二轮仍未通过原验收,不关闭。 本轮静态检查后端提交 3dd4b32:新增 snapshotAt 参数、详情从地图快照路径取数、跨端点投影契约测试及 README 说明;但尚未证明同一时间戳对应冻结/复用的同一份关系数据。该提交目前只在本地 master,比 origin/master 超前 1 个提交;不能作为远端已发布证据。后端工作树另有概览模块的未提交改动,本次未触碰。已把本轮差距回馈至 Gogs #69。

  • 通过(静态):详情 API 支持可选 snapshotAt;传入时由 CockpitMonitoringPointDetailService 采用地图快照适配器路径,返回错误时间戳为 SNAPSHOT_EXPIRED;README 明确有参数时的设计口径、无参数的尽力模式及现网“只保留清单、不画设备位置”边界。之前设备级坐标/校验的透传仍成立。
  • 仍不通过:真实同快照一致性:BusinessCockpitMapSnapshotAdapter.load(snapshotAt) 每次都会重新查 monitorPointService.list()、equipmentBaseService.list()、getEquipmentByPoint() 当前数据,只将传入 snapshotAt 写入返回快照,没有历史数据读取、冻结缓存、快照版本键或一致性事务。若两个请求之间点位关联改变,相同参数仍可能得到不同集合。
  • 新增测试的边界:CockpitMonitoringPointDetailSnapshotContractTest 用 Mockito 为 mapAdapter.load(SNAPSHOT_AT) 配置同一个预设快照,再比较同一内存对象投影的详情和地图设备集合,验证集合转换/归一化(含离线、空码、重复)正确;不能验证生产适配器在时间间隔/关系变化后对相同 snapshotAt 复用一致的源数据。实际适配器缺少同快照版本语义测试。
  • 发布证据:3dd4b32 为 master HEAD,但 origin/master 仍是其父提交 50a5711;提交仅本地领先 1,未证明推送/部署。不要声称远端已发布。
  • 坐标功能边界:真实适配器仍无可信坐标校核源,关联设备为 UNVERIFIED_COORDINATE/renderable=false,只展示清单、不绘制设备位置;README 现已正式记载。这一点本轮不再单独阻塞,因为对外边界明确。

下一步:后端需使相同 snapshotAt 代表可复用的同一源数据快照(版本化/缓存/事务等方案之一),新增真实适配器或快照仓储测试覆盖两个请求间关联变化的情景,之后发布提交。收到后再复验并决定是否通过;项目规则要求不自动运行构建/调试,本轮仅静态检查。

Question

需求②要画「该监测点下所有设备点位」,而实现这条路完全取决于后端给不给数据。票 01 会给出确切断口;本票负责把它推成后端的一个明确答复(排期 / 拒绝),因为「前端要不要另想办法拿设备位置」这个决策卡在它上面。本票是 wayfinder 里唯一「做而不是决定」的类型,它的价值在于解除一张决策票的阻塞。

要做的事:

  1. 提票(若 01 确认缺字段,预期是 CockpitMonitoringPointDeviceCard 缺 longitude/latitude/coordinateValidation):按 .scratch/cockpit-shell-panel-layout/handoff/backend-contract-gaps.md 里 BT 系列草案的格式,向 shaoy/pipe-ner-server(Gogs)提一张「点位详情补设备坐标与坐标校验(含 deviceCodes 对齐)」的工单,写清:背景与证据(类名 + 现有字段)、要做什么、验收标准(同一 snapshotAt 下与既有端点的设备集合一致;坐标缺失/未验证时 renderable=false 且有 reason;契约测试与 docs/cockpit/README.md 同步)、以及解除阻塞的前端票。
  2. 走已有的口子:.scratch/cockpit-shell-panel-layout/handoff/backend-contract-gaps.md 已记录 BT-1 / #59、BT-2 / #60 均已交付;本票先核对「是不是 #59 已经带了坐标而前端适配层漏读」,避免重复提票 —— 若属误读,本票的结论就是「补前端适配层」,并在此写明证据。
  3. 无答复时的兜底:若后端拒绝或一个工作日内无答复,记录答复原文与日期,并列出前端可走的三条备选供票 05 裁决:① 逐台 /equipments/{deviceCode}/archive(N+1,注明并发与失败处理);② 只用点位坐标 + 设备清单、不画设备位置;③ 等后端。注意 CONTEXT.md 禁止「人工坐标偏移」把对象当真实点位(`Avoid_: 人工坐标偏移、把聚合点当作真实监测点)。
  4. 落记录:Gogs 票号 / 答复原文 / 日期写进 Answer;地图摘要里读不到的设备坐标这件事不许含糊过去。

HITL:需要维护者用后端仓库账号建票并跟答复(本工作区已按 AGENTS.md 只读阅读后端源码,不改后端文件)。

Answer

第三轮验收:后端契约已实现,发布/联调仍待维护者执行

  • 后端当前远端 master 已包含 #69 实现提交链,最新远端 HEAD 为 77b4a34;前序实现从 3dd4b32 开始,工作区另有 overview/MonitorPoint 改动但未纳入这些提交。
  • GET /api/cockpit/v1/monitoring-points/{monitoringPointCode} 接受可选 snapshotAt;有参数时详情从地图快照读取。BusinessCockpitMapSnapshotAdapter 通过 Redis SET NX 发布首次完成快照,应用节点共享;本地缓存仅作加速,容量达到 256 时仍走 Redis。TTL 覆盖 snapshotAt 后 10 分钟,分数秒向上取整;请求、缓存命中和构建完成均按半开时间窗复核,构建期间过期不发布。
  • 设备集合证据已覆盖:真实适配器关系变化后的复用、独立适配器共享 Redis、地图分页边界、真实地图分页结果与详情 devices[] 的 deviceCode 对齐、空/重复编码去重及离线设备保留。Redis JSON 往返测试覆盖设备坐标、UNVERIFIED_COORDINATE 原因、renderable=false 与离线状态。
  • 坐标来自 equipment_base 设备自身字段,不复制监测点坐标、不制造偏移;当前无可信 coordinateVerified 来源,因此真实设备统一 UNVERIFIED_COORDINATE/renderable=false,正式边界是保留清单、不绘制设备位置。
  • 后端验证结果:全量 Maven 测试 377 项通过,0 失败;快照适配器专项测试 13 项通过。双轴审查未发现硬性规范或明确验收缺口。
  • 尚未完成发布证据:最新实现仅在后端本地分支,未推送/部署,也未做真实 Redis/Kingbase 联调。后续动作是已完成推送的远端 master(当前 77b4a34)部署后按 README 联调检查表复验;初次快照构建由多次数据库查询组成,未显式包在单事务中,这是部署前应关注的残余一致性风险。

第二轮验收:仍不通过原同快照验收

  • 新提交 3dd4b32 给详情端点加入可选 snapshotAt,调用地图快照适配器,并对时间戳不匹配返回 SNAPSHOT_EXPIRED;CockpitMonitoringPointDetailSnapshotContractTest 覆盖给定快照对象下详情 devices[] 与地图 deviceCodes 的投影集合一致,包括离线设备、坐标缺失、空/重复编码。README 同步写明参数与交付边界。
  • 但生产 BusinessCockpitMapSnapshotAdapter.load(snapshotAt) 每次仍然读取当前点位、设备与关联关系,再把请求中的时间戳回写为快照时间。没有按 snapshotAt 取历史版本、缓存/快照 ID 复用或一致性事务。真实源数据变化时,同一时间戳的两个请求仍可能取得不同设备集合。
  • 新契约测试将 mapAdapter.load(SNAPSHOT_AT) mock 为同一个预设对象,证明同一对象投影相同;没有证明真实适配器/仓储在两次请求或关联变化后冻结并复用同一源数据。故原要求“同一 snapshotAt 下集合必然一致”未证实。
  • 发布状态:当前后端 master 的 3dd4b32 比 origin/master 超前 1 个提交;本次未见该修复已推送。工作树其他概览模块有未提交变更,本次未修改。
  • 当前可信坐标数据源不足而统一返回 UNVERIFIED_COORDINATE/renderable=false;README 已明确本期仅保留设备清单、不绘制设备位置。这一降级边界现已清楚记载,不再作为本轮单独未决项。
  • 已将第二轮意见发回 Gogs #69(页面仍显示开启中)。本轮未运行 Maven、构建或联调,遵循后端仓库 AGENTS.md。

结论与下一步:任务继续 claimed。后端需实现同一 snapshotAt 真正映射到可复用、稳定的源数据版本,并对真实快照机制增加覆盖关联关系变化的测试;随后发布提交,再进行第三轮验收。

第一轮结果(历史)

  • 2026-09-24 以维护者账号 ChenJZ 创建后端工单 Cockpit:点位详情补齐关联设备坐标与坐标校验 #69。#59 仅提供编码清单,设备级坐标确实曾在点位详情模型链路丢失。
  • 后端 8006fb4(2026-09-28,已在本地 origin/master 历史中,工作树检查为空)新增快照/卡片 longitude/latitude/coordinateValidation,由设备事实解析器读取 equipment_base 的设备经纬度,经 cards() 透传;后端契约手册 已说明 WGS84、未验证降级和设备清单保留。
  • 坐标校验目前真实适配器恒传 coordinateVerified=false,结果为 UNVERIFIED/UNVERIFIED_COORDINATE/renderable=false。这准确表达了无可信校核来源,不意味着关联设备已能上图。

验收结果:部分通过,整票暂不通过

  1. 通过:设备身份/状态/坐标/校验的输出链路及文档;坐标来自设备本身,不以点位坐标或人工偏移代替;缺验证时禁止渲染且有原因。新增单元与 Controller 测试覆盖了坐标透传和 UNVERIFIED 路径(仅静态检查,未实际运行)。
  2. 未满足原验收:详情端点没有 snapshotAt 参数;地图适配器 load(snapshotAt) 每次读实时关系,并将传入标记回显。关系变更时,详情 devices[] 与地图 deviceCodes 无法保证是同一版。提交新增测试没有两端点同一 snapshotAt 集合一致、详情有效/缺失/非法坐标和离线集合的组合契约断言。票 05 后续已选择“跨端点尽力展示并提示不同步”,与本票/#69 的强同版验收有冲突;不能未经维护者确认自行放宽。
  3. 功能边界未确认:无可信设备坐标校核源导致真实关联设备全部不可上图。需后端/维护者明确本期是否接受“仅保留设备清单、位置待确认”,以及未来可信校核来源的负责人和排期。Gogs #69 在复核时仍显示开启中,原先 0 条评论;验收意见现已发在评论 #106。

下一步:等待 #69 对评论 #106 的正式答复及测试/联调证据;若维护者确认用票 05 的尽力展示口径替代强同版要求,须在 #69 与本票同步修订验收,并如实声明本期无可上图设备。否则由后端补版本一致性机制和契约测试。完成后再改 Status: resolved 并向地图 Decisions so far 追加索引。

Comments

后端提交静态验收

第三轮收尾记录

已完成本票后端契约验收并将状态置为 resolved。验收基线为远端 master 当前 77b4a34,全量 Maven 测试 377 项通过;未声称已完成真实 Redis/Kingbase 联调。设备坐标当前正式降级为 UNVERIFIED_COORDINATE/renderable=false,前端保留设备清单、不绘制位置。发布后需按 docs/cockpit/README.md 联调检查表复验;初次快照构建的多次数据库读取未显式事务化,作为部署前残余风险保留。