Type: spec Status: ready-for-agent Label: ready-for-agent Blocked by: 03 Category: spec
本规格固化决策票 03的维护者确认结果,作为同一张 map的子规格单。它是运行监测真实数据「数据时间」契约的实施输入;不覆盖 .scratch/cockpit-shell-panel-layout/spec.md。
规格文档已发布为 ready-for-agent 并挂到同一决策 map;100% 仅指规格交付,不表示 createdAt 字段、前端时间标签或后端契约已实现。后端契约改动(三端点加 createdAt)需按地图约定在决策收口后进入后端执行票;前端接线边界在本规格内。
运行监测模式的三个面板级聚合端点当前没有统一的“数据时间”表达,导致三处问题:
/monitoring/overview 只有信封级 updatedAt(快照加载时刻)与 freshness.serverUpdatedAt(响应生成时刻),没有“这批数据记录写到什么时候”的表达;前端只能以“数据时间”呈现 updatedAt 并写明区别(METRIC_FRESHNESS_GAP),无法证明它是真实数据记录时间。sampledAt(复合语义:GAS report_time、WATER timestamp_since 优先,create_time 兜底)与 equipment_status.status_update_time;若面板直接把 sampledAt/updatedAt 当“数据时间”,会把采样时刻、状态更新时刻、记录创建时刻混为一谈。/monitoring/distribution 的 Marker)与异常设备(/monitoring/situation 的 AbnormalEquipment)没有逐对象时间字段;distribution 甚至把快照里的 statusTime 丢弃在响应外,前端无法展示“这台设备/这个点位的记录时间”。create_time 或集合为空时,必须显式返回 null/未知,不得用响应时间冒充。从值班人员视角:监测概览展示一个“数据时间”(范围内最新一条真实记录创建的 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 冒充。create_time 时界面明确显示未知(“—”),而不是把响应时间当数据时间,以便不编造时间。createdAt 字段名与语义统一(都是记录创建时间),以便契约自洽、前端不猜。createdAt 按跨类型 max(create_time) 计算,以便异构设备类型统一成单一时间读数。create_time 存在性、某表无则如实标缺口,以便不硬凑数据来源。map-snapshot 不加 createdAt,以便空间摘要不携带无人消费的时间字段。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(响应生成时刻)保留原语义。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 措辞改为“数据时间=记录创建时间,不是设备采样时刻”。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。sampledAt 的语义变更(保持现状复合映射,不改)。map-snapshot 的筛选与命中设备子集(归决策票 02 / 规格 07)。CONTEXT.md:新增「采样时间」词条并修订「数据时间」。