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

5.4 KiB
Raw Blame History

名单模板尾行兼容修复

  • 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 写入成功;本任务不写共享索引或集成快照。