08-monitoring-created-at-spec.md 8.7 KB

08: 监测数据时间字段规格(来自决策票 03)

Type: spec Status: ready-for-agent Label: ready-for-agent Blocked by: 03 Category: spec

本规格固化决策票 03的维护者确认结果,作为同一张 map的子规格单。它是运行监测真实数据「数据时间」契约的实施输入;不覆盖 .scratch/cockpit-shell-panel-layout/spec.md。

进度:100%

规格文档已发布为 ready-for-agent 并挂到同一决策 map;100% 仅指规格交付,不表示 createdAt 字段、前端时间标签或后端契约已实现。后端契约改动(三端点加 createdAt)需按地图约定在决策收口后进入后端执行票;前端接线边界在本规格内。

Problem Statement

运行监测模式的三个面板级聚合端点当前没有统一的“数据时间”表达,导致三处问题:

  1. 时间语义不清:/monitoring/overview 只有信封级 updatedAt(快照加载时刻)与 freshness.serverUpdatedAt(响应生成时刻),没有“这批数据记录写到什么时候”的表达;前端只能以“数据时间”呈现 updatedAt 并写明区别(METRIC_FRESHNESS_GAP),无法证明它是真实数据记录时间。
  2. 采集/上报时刻与记录创建时刻混淆:设备级已有 sampledAt(复合语义:GAS report_time、WATER timestamp_since 优先,create_time 兜底)与 equipment_status.status_update_time;若面板直接把 sampledAt/updatedAt 当“数据时间”,会把采样时刻、状态更新时刻、记录创建时刻混为一谈。
  3. 逐对象时间缺失:台账卡(/monitoring/distribution 的 Marker)与异常设备(/monitoring/situation 的 AbnormalEquipment)没有逐对象时间字段;distribution 甚至把快照里的 statusTime 丢弃在响应外,前端无法展示“这台设备/这个点位的记录时间”。
  4. 空态不明确:无 create_time 或集合为空时,必须显式返回 null/未知,不得用响应时间冒充。

Solution

从值班人员视角:监测概览展示一个“数据时间”(范围内最新一条真实记录创建的 create_time,跨类型取 max);台账卡与异常设备各带自己的“数据时间”;前端“数据时间”与设备级“采样时间”两套标签各归其位,互不冒充;无数据时明确显示未知,不编造时间。

核心语义(详见决策票 03 的 Answer):

  • createdAt=记录创建时间(create_time),不是采样/上报时刻。
  • 三端点字段落点:
    • /monitoring/overview:分区级 createdAt(信封一个读数,跨类型 max create_time)。
    • /monitoring/distribution:信封级 createdAt + 台账逐对象级 createdAt(点位 marker 用 monitor_point.create_time、设备 marker 用 equipment_base.create_time)。
    • /monitoring/situation:信封级 createdAt + 异常设备逐对象级 createdAt(用其来源表 create_time)。
  • map-snapshot 不加 createdAt。
  • sampledAt(采样/上报时刻)与 createdAt(记录创建时刻)并存分离;status_update_time(状态更新时刻)设备级承载,不与 createdAt 混。
  • 空态:无 create_time 或集合为空 → createdAt 显式 null/未知,前端“—”或“数据时间未知”;不用响应时间/envelope updatedAt/serverUpdatedAt 冒充。
  • 前端“数据时间”(=createdAt)与“采样时间”(=sampledAt/installTime/status_update_time 按其语义)两套标签。

User Stories

  1. 作为值班人员,我想在监测概览看到“数据时间”(范围内最新真实数据记录时间),以便知道这批数据写到什么时候。
  2. 作为值班人员,我想“数据时间”不是设备采样时刻也不是服务响应时间,以便不会被“看起来像是实时”误导。
  3. 作为值班人员,我想台账卡上的每台设备/每个点位带自己的“数据时间”,以便知道该对象的数据到什么时候。
  4. 作为值班人员,我想异常设备清单中每台设备带自己的“数据时间”,以便判断异常信息的新旧。
  5. 作为值班人员,我想没有 create_time 时界面明确显示未知(“—”),而不是把响应时间当数据时间,以便不编造时间。
  6. 作为值班人员,我想设备级指标/详情展示“采样时间”(真实采样/上报时刻),以便与面板的“数据时间”区分。
  7. 作为值班人员,我想“数据时间”与“采样时间”标签不混用,以便不会把记录创建时刻误当设备采集时刻。
  8. 作为部署/维护者,我想三端点的 createdAt 字段名与语义统一(都是记录创建时间),以便契约自洽、前端不猜。
  9. 作为维护者,我想监测概览的 createdAt 按跨类型 max(create_time) 计算,以便异构设备类型统一成单一时间读数。
  10. 作为维护者,我想执行票逐表核验 create_time 存在性、某表无则如实标缺口,以便不硬凑数据来源。
  11. 作为维护者,我想 map-snapshot 不加 createdAt,以便空间摘要不携带无人消费的时间字段。
  12. 作为维护者,我想刷新/重新取数时机不在本规格定义(归 real 生命周期),以便时间语义与刷新调度解耦。

Implementation Decisions

后端契约(供后端执行票)

  • monitoring/overview:响应新增分区级 createdAt(跨类型 max create_time,来自聚合源各表真实 create_time)。
  • monitoring/distribution:响应新增信封级 createdAt + Marker 逐对象 createdAt(点位 marker=monitor_point.create_time、设备 marker=equipment_base.create_time;把当前丢弃的 statusTime 抛离,只带 create_time 语义的 createdAt)。
  • monitoring/situation:响应新增信封级 createdAt + 异常设备逐对象 createdAt(用其来源表 create_time)。
  • 三端点 mapFilter/信封不新增其它时间字段;updatedAt(快照加载时刻)与 serverUpdatedAt(响应生成时刻)保留原语义。
  • archive 端点不加 createTime(现状有 installTime/productionDate,详情时间按“采样时间/安装时间”展示)。
  • sampledAt 保持现状(GAS report_time 优先、WATER timestamp_since 优先、create_time 兜底),不改。

前端

  • domain/monitoringPanels.js:新增 createdAt 读取(分区级 + 逐对象级);空态 null → “—”;“数据时间”标签映射;与“采样时间”标签分离。
  • services/monitoringApi.js:三端点透传 createdAt(只读不筛),不新增入参。
  • 组件(PanelBlocks / 台账卡 / 设备详情):监测概览“数据时间”读数、台账卡时间、异常设备时间;设备级详情显示“采样时间/安装时间”(现有字段)。
  • METRIC_FRESHNESS_GAP 措辞改为“数据时间=记录创建时间,不是设备采样时刻”。

Testing Decisions

  • 好测试的定义:只测外部行为与契约语义——createdAt 读取/空态、“数据时间/采样时间”标签不混、服务层不新增入参、不把 updatedAt/serverUpdatedAt 冒充 createdAt。
  • 主接缝:领域纯函数(domain/monitoringPanels.js 的时间适配)+ 服务层守卫(services/monitoringApi.js)。先例:.scratch/cockpit-shell-panel-layout/verify/t18-monitoring-panels.mjs、t05-adapter.mjs(静态守卫 + 变异测试确认有牙)。
  • 浏览器走查(-walkthrough.mjs + data-*):监测概览“数据时间”读数、台账卡时间、空态“—”、设备详情“采样时间/安装时间”,断言时间标签不混。
  • 后端执行票验收:三端点响应含 createdAt(信封 + 逐对象)、空态 null、跨类型 max(create_time) 语义;map-snapshot 与 archive 不含 createdAt。

Out of Scope

  • sampledAt 的语义变更(保持现状复合映射,不改)。
  • 刷新/重新取数时机(归决策票 04,real 生命周期);本规格只定字段语义与展示。
  • map-snapshot 的筛选与命中设备子集(归决策票 02 / 规格 07)。
  • 设备级状态词表、异常统计(归决策票 06)。
  • 后端实现与真实联调(后端执行票在相关决策收口后创建)。
  • 移动端、UE5、Docker、国产化认证及非驾驶舱领域。

Further Notes

  • 本规格依赖决策票 03(已 resolved);后端契约改动需在决策票 04(real 生命周期)、05(联调基线)、06(业务语义)收口后进入后端执行票。
  • 领域词汇已同步 CONTEXT.md:新增「采样时间」词条并修订「数据时间」。
  • 未运行 build/debug 验证(遵循仓库 AGENTS.md 规则);本规格只交付实施输入。