docs: design real queue history shadow replay
This commit is contained in:
@@ -0,0 +1,293 @@
|
||||
# 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-*` 生产代码。
|
||||
|
||||
Reference in New Issue
Block a user