Files
FT546-WCS/docs/superpowers/specs/2026-07-30-wcs-real-queue-history-replay-design.md

294 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WCS 真实队列历史离线回放测试设计
## 1. 背景
现有 `javaTest` 已具备纯内存 P0-B1 SHADOW 领域内核和 60 条人工安全场景,但人工场景不便于业务人员理解,也不能体现 FT546 现场队列的真实任务号、车辆、站点、路径和时间分布。
`FT546-wcs` 数据库中 `dbo.wcs_srgv_queue_finish` 当前包含 17,136 条四向车历史队列记录,时间范围为 2026-03-01 至 2026-07-21,涉及 3 台车、531 个起点和 484 个终点;其中 11,943 条包含非空路径。该数据量足以建立真实历史队列离线回放,但历史表没有保存每个调度周期的完整 PLC 快照、资源账本和 LEGACY 决策,因此结果不能描述为真实现场 SHADOW 验收。
## 2. 目标
在不修改生产模块、不写数据库、不连接 PLC 的前提下:
1. 只读提取 FT546 四向车真实历史队列记录。
2. 保留原始任务号、车辆号、站点号和路径,便于数据库回查。
3. 对全部历史记录执行数据质量、时间一致性和安全风险扫描。
4. 从路径完整记录中确定性选取不少于 200 条代表性任务,重建历史并发窗口。
5. 把历史路径转换为 SHADOW 可理解的节点和无向边资源,执行离线冲突分析与确定性回放。
6. 生成业务人员可读的表格,明确区分数据库事实、推导事实和算法结果。
7. 保留现有 60 条人工边界场景,真实历史回放作为补充而不是替代。
## 3. 明确边界
### 3.1 范围内
- 数据库只读查询。
- `wcs_srgv_queue_finish` 全量统计和确定性样本导出。
- `wcs_srgv_map` 站点存在性校验。
- 原始任务号、车辆号、站点号、路径、状态和时间保留。
- 历史任务生命周期、路径节点、无向边、并发窗口和潜在冲突推导。
- 纯内存离线 SHADOW 分析。
- JSON/CSV/Excel/Markdown 证据输出。
### 3.2 范围外
- 对 `FT546-wcs` 执行 INSERT、UPDATE、DELETE、DDL 或存储过程写操作。
- 使用当前 `device_srgv` 三行实时状态冒充历史 PLC 快照。
- 推断历史记录中不存在的 bootId、ACK、故障、载货寄存器或资源释放事实。
- 根据“任务最终完成”反推当时某轮调度决定一定正确。
- 现场 SHADOW、PLC 模拟器、HIL、ACTIVE 或生产验收。
- 修改 `ruoyi-*` 生产代码。
## 4. 方案选择
采用“只读导出快照+版本化离线回放”:
```text
FT546-wcs 只读查询
│
▼
原始历史快照 JSON/CSV
│ SHA-256、查询口径、抽取时间
▼
历史记录规范化
│
├── 数据质量扫描
├── 时间窗口重建
├── 路径节点/无向边资源化
└── 确定性代表样本选择
▼
纯内存 SHADOW 历史回放
│
▼
可读报告和机器可审计结果
```
不采用测试运行时直接依赖数据库的方案,因为数据库内容持续变化会导致测试结果不可复现。数据库查询只负责生成带摘要的输入快照;Maven 测试只读取已固化快照。
## 5. 数据来源与只读约束
### 5.1 主数据表
`dbo.wcs_srgv_queue_finish` 使用以下字段:
- 标识:`guid`、`task_no`、`agv_id`
- 分类:`task_type`、`priority`、`cargo`、`issued`、`execution_status`
- 路径:`start_site`、`end_site`、`the_floor`、`path_info`
- 时间:`create_date`、`start_date`、`finish_date`
- 业务补充:`cargo_pick_site`、`cargo_place_site`、`trun_path`、`up_down_site`、`default02` 至 `default08`
### 5.2 地图校验表
`dbo.wcs_srgv_map` 使用:
- `site_id`
- `x`、`y`、`z`
- `axy`
- `warehouse`、`space_area`
地图表只用于判断路径站点是否存在和提供可读坐标,不据此自动推断交通容量、冲突资源或安全等待点。
### 5.3 查询安全
- 仅允许单条 `SELECT` 或 CTE。
- 查询账户和工具保持只读。
- 禁止存储过程、临时写表、锁表提示和破坏性并发测试。
- 每次抽取记录数据库名、表名、查询口径、抽取时间、行数和 SHA-256。
- 原始快照不得包含数据库口令、IP、Token 或连接串。
## 6. 历史记录规范化
新增独立历史回放包,不把数据库字段直接泄漏到 SHADOW 领域模型:
```text
com.ft546.wcs.shadow.history/
├── HistoricalQueueRecord
├── HistoricalQueueDataset
├── HistoricalQueueNormalizer
├── HistoricalWindowBuilder
├── HistoricalPathProjector
├── HistoricalReplayAnalyzer
└── HistoricalReplayResult
```
### 6.1 字段语义
- `task_no + agv_id + create_date + start_site + end_site` 形成可读记录标识;`guid` 保留用于回查。
- `path_info` 按逗号拆分,去除空尾项,但不改变节点顺序。
- 路径第一个和最后一个有效节点分别与 `start_site`、`end_site` 比较并记录差异。
- `create_date` 和 `finish_date` 按固定格式解析;无法解析时标为数据问题,不伪造时间。
- `start_date` 为空不阻断回放,因为现有历史记录普遍缺少该值;并发窗口使用 `[create_date, finish_date)`,并明确标记为推导口径。
- 同一 `task_no` 的多条记录按时间和路径段分别保留,不擅自合并成一条物理行程。
### 6.2 路径资源投影
每条完整路径转换为:
- 每个路径点:`NODE:{siteId}`
- 每对相邻点:规范化 `EDGE:{smallerSiteId}:{largerSiteId}`
历史地图没有正式发布的冲突资源容量和安全点签字,因此不自动生成 `CONFLICT`、提升机容量或 YIELD 安全点。`end_site=tsj` 且路径为空的记录只参与数据质量和生命周期统计,不参与路径冲突裁决。
## 7. 并发窗口和样本选择
### 7.1 并发窗口
若两条记录满足以下条件,则视为“历史生命周期可能重叠”:
```text
A.create < B.finish && B.create < A.finish
```
并发窗口是根据队列生命周期推导的候选集合,不等同于两车在同一秒真实占用对应路径节点。报告必须使用“潜在并发”“路径交集”或“离线推演”,不能写成“现场发生碰撞”。
### 7.2 全量扫描
全部 17,136 条记录至少检查:
- 必填标识缺失;
- 时间无法解析、完成早于创建;
- 同一车辆生命周期重叠;
- 起终点与路径首尾不一致;
- 路径节点不在地图中;
- 相邻重复节点和路径自环;
- 空路径占比和场景分布;
- 任务类型、车辆、楼层、起终点和时长分布。
### 7.3 代表样本
从路径完整记录中确定性选择至少 200 条:
1. 每台车均有覆盖。
2. 每种实际任务类型均有覆盖。
3. 不同楼层、路径长度和任务时长分层覆盖。
4. 包含并发窗口、共享节点、共享无向边和无冲突样本。
5. 包含同一任务号多段记录。
6. 固定排序和选择规则,重复抽取产生相同样本。
若某类真实数据不足,报告显示实际数量,不复制记录凑数。
## 8. 回放分析
历史回放不直接把一条已完成任务标成 `GRANT`。每个并发窗口执行:
1. 冻结窗口内记录和地图站点集合。
2. 按数据库原始优先级、创建时间、任务号、车辆号稳定排序。
3. 把路径前缀投影为候选节点和无向边资源。
4. 使用内存账本依次检查资源容量 1 的节点和无向边。
5. 输出:
- `NO_CONFLICT`:与窗口内其他记录无路径资源交集;
- `POTENTIAL_NODE_CONFLICT`:共享节点;
- `POTENTIAL_OPPOSITE_EDGE`:对向使用同一无向边;
- `SAME_VEHICLE_OVERLAP`:同车生命周期重叠;
- `INSUFFICIENT_DATA`:路径或时间不足;
- `REPLAY_GRANT/HOLD`:在明确投影口径下的 SHADOW 推演结果。
6. 对完全相同输入执行两次,决策和原因必须一致。
算法输出与历史事实分别保存。历史事实是“数据库记录已完成”;SHADOW 输出是“按当前离线模型推演的决定”。两者不建立虚假的正确率比较。
## 9. 可读报告
报告至少包含四张表:
### 9.1 总览
- 数据库、表、时间范围和抽取时间
- 总记录数、完整路径数、车辆数、站点数
- 代表样本数、并发窗口数
- 数据质量问题数
- 潜在节点/对向边/同车重叠数
- 回放 GRANT/HOLD 数和确定性结果
### 9.2 业务可读明细
| 时间 | 车辆 | 任务号 | 从哪里到哪里 | 实际历史结果 | SHADOW 推演 | 原因 |
| --- | --- | --- | --- | --- | --- | --- |
### 9.3 路径与冲突明细
- 原始完整路径
- 路径长度
- 同期车辆和任务号
- 共享节点或边
- 数据来源字段
### 9.4 数据问题
- 记录标识
- 问题类型
- 原始值
- 是否影响回放
- 处理方式
表格保留筛选、冻结表头、中文说明和原始编号。报告首页必须醒目标注“真实历史队列离线回放,不是现场 SHADOW 验收”。
## 10. 错误处理
- 数据库不可用:停止抽取,不使用空数据生成成功报告。
- 返回 0 行:测试失败。
- 快照行数、摘要或字段结构变化:测试失败并提示重新抽取。
- 日期解析失败:记录数据问题,不猜测时间。
- 路径节点未知:标为 `UNKNOWN_MAP_SITE`,不把未知资源视为空闲。
- 路径为空:标为 `INSUFFICIENT_DATA`,不进入路径裁决。
- 同一原始记录重复:按 `guid` 和业务复合键报告,不静默删除。
- 报告生成失败:保留机器可读结果和错误日志。
## 11. 测试策略
新增测试至少覆盖:
1. 快照结构、行数和 SHA-256 校验。
2. 真实日期、空日期和非法日期解析。
3. 逗号尾项、空路径、重复节点和未知站点。
4. 同任务号多段记录保持独立。
5. 生命周期重叠和边界不重叠。
6. 共享节点、同向边、对向边和无交集路径。
7. 同车重叠检测。
8. 200 条以上代表样本覆盖约束。
9. 相同输入两次回放结果一致。
10. SHADOW 回放零数据库写、零 PLC 写、零业务状态写。
11. 现有 60 条人工安全场景继续通过。
验证命令:
```bash
mvn -f javaTest/pom.xml clean test
```
验收读取 Surefire XML,要求测试数大于 0、Failures 为 0、Errors 为 0,并单独汇总真实历史回放用例数。
## 12. 交付物
```text
javaTest/src/test/resources/shadow/history/
├── manifest.json
├── queue-history.json
└── map-sites.json
javaTest/src/main/java/com/ft546/wcs/shadow/history/
javaTest/src/test/java/com/ft546/wcs/shadow/HistoricalQueueReplayTest.java
outputs/wcs-shadow-history-replay-{runId}/
├── summary.json
├── readable-report.xlsx
├── replay-results.csv
├── data-quality-issues.csv
└── manifest.sha256
```
原始快照可保留原始业务编号,但不包含数据库连接信息。输出目录按运行 ID 新建,不覆盖先前失败证据。
## 13. 验收标准
1. 数据库查询全程只读,生产表无写入。
2. 快照记录数和 SHA-256 可复核。
3. 全部历史记录完成数据质量和风险扫描。
4. 至少 200 条真实路径记录完成确定性离线回放。
5. 原始任务号、车辆号、站点号和路径可在报告中回查。
6. 数据库事实、推导事实和算法结果清晰分栏。
7. 未知或缺失数据不会产生虚假 GRANT。
8. 现有 60 条人工边界场景和全部原有测试无回归。
9. 报告不把离线历史回放描述为真实现场 SHADOW、HIL 或 ACTIVE 证据。
10. 不修改 `ruoyi-*` 生产代码。