Files
LWLT-AIBOT/.project-docs/30-worklog/tasks/20260911-roster-template-tail-01a0858b.md
T
2026-09-11 12:08:51 +08:00

60 lines
5.4 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.
# 名单模板尾行兼容修复
- Task ID: `20260911-roster-template-tail-01a0858b`
- Mode: Feature
- Status: Complete (local implementation and validation)
- Authorization: 用户明确要求保留原始表格,通过修改程序兼容没有旅客资料的表尾模板行。
## Concurrent Worktree Check
- Branch: `main`
- Worktree: `/Users/andy/IdeaProjects/LWLT-AIBOT`
- Base commit: `07b23fce9e96badbd266bbda682fd16cd6733e22`
- Existing changes: 未跟踪 `.idea/` 和上一任务生成的 `dist/ltjt-order-assistant-0.5.173.zip`,均保留且不涉及;已有忽略的 Finder 文件也保留。
- Other local worktrees: 无。
- Overlap result: Clear;服务端名单 normalizer 及测试无既有改动。
## Scope and constraints
- 服务端只在读取时识别表尾的无旅客资料模板行,原始 XLS 不修改、不复制进仓库。
- 有实际旅客信息、位于名单中间或无法确定用途的行继续严格校验;保留全局不安全公式/外链/宏及隐藏数据检查。
- 本次不修改插件、多关键词搜索、数据库或 canonical 项目记忆;不部署、重启、访问或写入 ERP、发送外部通知。
- 使用合成测试夹具;本地原始 XLS 复验只输出结构、计数及哈希,不输出旅客信息。
- 遵守仓库不经用户同意不使用子 Agent 的约束,本任务自行实现与复核。
## Findings
- 原文件与生产日志的大小/哈希一致。表头在第 2 行,第 3–30 行共 28 条已填写名单。
- 第 31、32 行没有姓名和护照数据,但保留序号 29/30 及性别、出生日期、有效期公式;D31/E31/D32/E32 含失效 `#REF!` 引用。
- 当前 normalizer 在识别实际数据范围前校验整张工作表必需列的公式,因此在 D31 返回 `roster_workbook_formula_not_allowed`。
- 第 33–34 行是跨越全部名单列的合并备注区;只处理空公式行仍会把该备注当成名单,因此纳入有明确标签的表尾说明识别。
## Implementation
- Normalizer 更新为 `ltjt-passenger-roster-workbook-v1.5.0`;接口、数据库及 canonical TSV 格式保持原样。
- 从表尾倒序确定数据结束行,仅裁掉连续尾部空行、正整数序号占位行、没有任何实填旅客字段且仅含已知模板公式的行,以及覆盖全部导入列、带明确备注/说明标签且没有独立附加单元格内容的合并说明行。
- 对失效身份证派生的性别/出生日期公式仅识别原模板的确切公式形式;已有同一行 `EDATE` 日期派生公式仍可作为空模板标识。任意其他公式或任一实填字段都会保留该行为数据并严格校验。
- 识别只发生于连续尾部,不能越过有旅客信息或未知内容的行。名单中间仅有序号的占位行现在明确报 `roster_workbook_incomplete_row`;中间空行、公式错误和无效序号继续阻断。
- 全工作簿的宏、外链、危险公式、超链接、隐藏行/列检查仍保留,尾部识别不会绕开这些检查。
## Verification
- 回归先行:新增 8 项测试在旧实现上有 6 项失败,重现实际模板尾部问题;修复后新增和已有名单测试合计 20/20 PASS。
- 定向验证覆盖原始布局、列重排、序号占位、跨行合并备注、全空模板、实填部分数据、名单中间占位/空行/备注、未知公式和跨工作簿安全检查。
- 原始 XLS 只读链路 PASS:生产转换器 → normalizer → Program Parser → 插件派发校验;表头第 2 行,28 条完整 13 列记录,序号 1–28 原样保留,原文件哈希不变。未访问 ERP。
- `node --run check`:PASS;`node --run build`:PASS;`node --run test:control-plane`:202/202 PASS。
- `node --run check:repo`:原工作目录 8/10,通过项包含发布文件与哈希;两项失败仅为既有 `.idea/`/Finder 文件,已保留。在 `/private/tmp/ltjt-roster-tail-verify-f4emlqgc` 的当前源码与发布物副本中,排除上述杂项及秘密后 10/10 PASS。
- `node --run test:legacy`:累计 290/290 PASS。首次 288 项通过,另两项因沙箱禁止本地 127.0.0.1 监听而失败;单独申请权限时自动审批超时,按工具允许重试一次后获准,两项 HTTP 边界测试均通过。
- `git diff --check`:PASS。源码改动只涉及一个服务端 normalizer;新增测试和本任务记录,不改动现有插件与交付物。
- 最终自行复核完成:本任务仅涉及上述源码、新增测试及任务记录三个文件,既有改动均保留;未执行部署、外部发送或 ERP 操作。
## Outcome and follow-ups
- 原表无需编辑;服务端镜像重建并部署后,可在当前等待附件的任务中重新上传同一文件。现有接收逻辑会重新校验之前 rejected 的同一 SHA-256 附件,无需更换文件名或新建任务。
- 本次不需要更新插件或数据库。部署后的附件校验日志应显示 normalizer `v1.5.0` 和 `row_count: 28`。
- 生产部署及实际 ERP 验收由用户后续执行,本任务不自动重试业务任务或写入 ERP。
## Promotion Candidates
- Target: canonical current state / 名单输入契约。集成时登记 normalizer `v1.5.0` 对连续表尾空模板与明确合并备注的有限兼容,以及中间占位行错误码。证据为本任务合成回归和用户原始文件只读全链路验证。不等同于放开任意公式、跳过不完整旅客或声明 ERP 写入成功;本任务不写共享索引或集成快照。