档口入库码:数据模型、迁移与 Excel 导入 #119

Closed
opened 2026-08-27 23:30:17 +08:00 by ila · 4 comments
Owner

所属与来源

  • 父 MVP:#117。
  • 来源:用户于 2026-08-27 要求先按已确认的全栈分析方案建单并制作总原型,审核通过后才能实施。
  • 前置依赖:#118 原型经用户明确审核通过。
  • 可与 #120 并行:否;#120 依赖本工单的数据契约。

目标

在 GoAuto 建立档口入库码的持久化模型、加法迁移、导入解析和本地查询 API;本工单不访问任何 SYB 写接口。

方案

  • 新增业务记录、单件码和执行批次模型;业务唯一键保持 business_date + order_number + stall + spec_key。
  • 一件一码持久化并保存原始 Excel 行顺序,日期内单件入库码唯一。
  • 保留 spec_raw、确定性的 spec_key、原始 SKU、档口、店铺、打印序号和来源行。
  • Excel 表名兼容“标签入库码映射”;文件上限 10MB、数据行上限 5000、表头仅在前 10 行查找。
  • 兼容源模块的合并/拆分档口列与规格列别名,拒绝控制字符、逗号码、超长字段和业务冲突。
  • 不保存 Excel 原文件;同日重新生成文件只有在旧快照全部处于安全未处理状态时,才允许事务性整批替换。
  • 所有修改请求使用 UUID requestId 幂等;导入事务成功后自动创建 #120 的只读匹配任务并立即返回批次标识,不等待匹配完成;删除采用批量物理删除,不设计 deleted_at、回收站或恢复。
  • 新模型同时进入 MigratedModels、版本化迁移和迁移完整性测试。

批量物理删除

  • API 接收 UUID requestId 和去重后的记录 ID 列表,在一个事务中完成。
  • 确认后物理删除业务记录、关联单件码和匹配计划。
  • queued、applying、needs_check 任一命中时拒绝整次删除并返回阻塞记录,不做部分成功。
  • 其他状态均允许删除;匹配 worker 对已删除记录的后续更新按“记录已取消”结束,不能重新插入。
  • 数据库外键对单件码和匹配计划使用级联删除,对活动回写证据使用限制约束。
  • 不实现软删除、恢复和回收站。

非目标

  • 不请求 SYB、不做匹配、不写入远端。
  • 不迁移源数据库历史记录。
  • 不实现最终 Vue 页面,只提供 #122 需要的 JSON API。

验收标准

  • 合法单件和多件 Excel 正确导入并保留顺序。
  • 日期内单件码和业务键唯一性由数据库与服务共同保证。
  • 同日安全替换成功;存在匹配或执行证据时明确拒绝。
  • 大小、行数、表头、字段、重复和事务回滚边界均有测试。
  • 导入文件内容不进入数据库或日志。
  • 导入成功后只创建一个幂等匹配任务并返回批次标识;页面不需要人工点击批量匹配。
  • 列表、详情、导入、批量物理删除 API 使用统一错误码和 requestId。
  • queued、applying、needs_check 删除被拒绝;其他状态批量物理删除成功且关联数据无残留。
  • MySQL 迁移、模型约束和受影响 Go 测试通过。

验证

  • 单元测试:导入解析、规范化、聚合、多件顺序、冲突与重放。
  • Repository/MySQL:唯一约束、批量物理删除、外键级联和版本迁移。
  • API:multipart 上限、权限、幂等和错误响应。

风险与文档

涉及数据库迁移,实施和应用迁移前必须按高风险门禁再次确认。完成后更新数据结构、架构、业务规则、接口与验证 Wiki。

## 所属与来源 - 父 MVP:#117。 - 来源:用户于 2026-08-27 要求先按已确认的全栈分析方案建单并制作总原型,审核通过后才能实施。 - 前置依赖:#118 原型经用户明确审核通过。 - 可与 #120 并行:否;#120 依赖本工单的数据契约。 ## 目标 在 GoAuto 建立档口入库码的持久化模型、加法迁移、导入解析和本地查询 API;本工单不访问任何 SYB 写接口。 ## 方案 - 新增业务记录、单件码和执行批次模型;业务唯一键保持 `business_date + order_number + stall + spec_key`。 - 一件一码持久化并保存原始 Excel 行顺序,日期内单件入库码唯一。 - 保留 `spec_raw`、确定性的 `spec_key`、原始 SKU、档口、店铺、打印序号和来源行。 - Excel 表名兼容“标签入库码映射”;文件上限 10MB、数据行上限 5000、表头仅在前 10 行查找。 - 兼容源模块的合并/拆分档口列与规格列别名,拒绝控制字符、逗号码、超长字段和业务冲突。 - 不保存 Excel 原文件;同日重新生成文件只有在旧快照全部处于安全未处理状态时,才允许事务性整批替换。 - 所有修改请求使用 UUID `requestId` 幂等;导入事务成功后自动创建 #120 的只读匹配任务并立即返回批次标识,不等待匹配完成;删除采用批量物理删除,不设计 `deleted_at`、回收站或恢复。 - 新模型同时进入 `MigratedModels`、版本化迁移和迁移完整性测试。 ### 批量物理删除 - API 接收 UUID `requestId` 和去重后的记录 ID 列表,在一个事务中完成。 - 确认后物理删除业务记录、关联单件码和匹配计划。 - `queued`、`applying`、`needs_check` 任一命中时拒绝整次删除并返回阻塞记录,不做部分成功。 - 其他状态均允许删除;匹配 worker 对已删除记录的后续更新按“记录已取消”结束,不能重新插入。 - 数据库外键对单件码和匹配计划使用级联删除,对活动回写证据使用限制约束。 - 不实现软删除、恢复和回收站。 ## 非目标 - 不请求 SYB、不做匹配、不写入远端。 - 不迁移源数据库历史记录。 - 不实现最终 Vue 页面,只提供 #122 需要的 JSON API。 ## 验收标准 - [ ] 合法单件和多件 Excel 正确导入并保留顺序。 - [ ] 日期内单件码和业务键唯一性由数据库与服务共同保证。 - [ ] 同日安全替换成功;存在匹配或执行证据时明确拒绝。 - [ ] 大小、行数、表头、字段、重复和事务回滚边界均有测试。 - [ ] 导入文件内容不进入数据库或日志。 - [ ] 导入成功后只创建一个幂等匹配任务并返回批次标识;页面不需要人工点击批量匹配。 - [ ] 列表、详情、导入、批量物理删除 API 使用统一错误码和 `requestId`。 - [ ] `queued`、`applying`、`needs_check` 删除被拒绝;其他状态批量物理删除成功且关联数据无残留。 - [ ] MySQL 迁移、模型约束和受影响 Go 测试通过。 ## 验证 - 单元测试:导入解析、规范化、聚合、多件顺序、冲突与重放。 - Repository/MySQL:唯一约束、批量物理删除、外键级联和版本迁移。 - API:multipart 上限、权限、幂等和错误响应。 ## 风险与文档 涉及数据库迁移,实施和应用迁移前必须按高风险门禁再次确认。完成后更新数据结构、架构、业务规则、接口与验证 Wiki。
Author
Owner

开始实施。前置 #118 已验收关闭;本工单按已确认方案进行数据模型、加法迁移、Excel 导入、本地列表/详情及批量物理删除 API。此次实施包含迁移代码和测试,不连接或写入真实 SYB。工作区已有无关未跟踪文件 gitea.zip,将保留且不纳入提交。

开始实施。前置 #118 已验收关闭;本工单按已确认方案进行数据模型、加法迁移、Excel 导入、本地列表/详情及批量物理删除 API。此次实施包含迁移代码和测试,不连接或写入真实 SYB。工作区已有无关未跟踪文件 `gitea.zip`,将保留且不纳入提交。
Author
Owner

实施完成,待用户验收

实现提交:5c6655f(与 #120、#121 共享后端契约);文档提交:fd15ce0、68395ca、2f54155。

  • 新增加法迁移和 Excel 业务记录/逐件码/计划/批次/检查点/租约/幂等模型;Excel 限制 10MB、5000 行、前 10 行表头、单营业日期、日期内单件码唯一。
  • 按营业日期+订单号+档口+规范化规格聚合并保留源行顺序;同日只允许替换全部仍待匹配的安全快照。
  • 导入事务成功后自动创建唯一匹配任务;列表、详情、关键词查询、导入和批量物理删除 API 已注册采购员权限。
  • 删除对 queued/applying/needs_check 整批拒绝并返回阻塞项;其他状态在同一事务物理删除逐件码、计划、终态检查点和执行项。
  • 单测覆盖聚合顺序、幂等、安全替换、重复码、关键词、原子删除及关联残留。未应用生产数据库迁移。

共同验证与文档证据

  • .\scripts\verify.ps1 -Component all:通过(服务端 go test ./... 与构建、Web lint/生产构建、Android 单测与 debug APK 构建);Web lint 仅有 30 条存量 warning,0 error。
  • 专项浏览器验收:npx playwright test tests/e2e/syb-inner-codes.spec.ts,1 passed。
  • 线上 Wiki revision:架构 6ed5b970878ff0211946fbba02c64eaccfe8d8bb;业务规则 4236dd1d219cc6235537adfd8d0411308c449971;产品索引 0d9924b4566e567edf167ba678fedde28a41cfd3;SYB 契约 f596931468caf524cbd9d90b3c299b32a8cf8228。
  • harness.py sync 已完整导出。独立 sync --check 因 Gitea 直连读取超时未返回成功码;随后通过 Gitea MCP 对上述四页逐字比较正文并核对镜像 revision,四页均 content_equal=true、revision_equal=true。
  • 保留无关未跟踪文件 gitea.zip,未纳入提交。
## 实施完成,待用户验收 实现提交:`5c6655f`(与 #120、#121 共享后端契约);文档提交:`fd15ce0`、`68395ca`、`2f54155`。 - 新增加法迁移和 Excel 业务记录/逐件码/计划/批次/检查点/租约/幂等模型;Excel 限制 10MB、5000 行、前 10 行表头、单营业日期、日期内单件码唯一。 - 按营业日期+订单号+档口+规范化规格聚合并保留源行顺序;同日只允许替换全部仍待匹配的安全快照。 - 导入事务成功后自动创建唯一匹配任务;列表、详情、关键词查询、导入和批量物理删除 API 已注册采购员权限。 - 删除对 `queued/applying/needs_check` 整批拒绝并返回阻塞项;其他状态在同一事务物理删除逐件码、计划、终态检查点和执行项。 - 单测覆盖聚合顺序、幂等、安全替换、重复码、关键词、原子删除及关联残留。未应用生产数据库迁移。 ### 共同验证与文档证据 - `.\scripts\verify.ps1 -Component all`:通过(服务端 `go test ./...` 与构建、Web lint/生产构建、Android 单测与 debug APK 构建);Web lint 仅有 30 条存量 warning,0 error。 - 专项浏览器验收:`npx playwright test tests/e2e/syb-inner-codes.spec.ts`,1 passed。 - 线上 Wiki revision:架构 `6ed5b970878ff0211946fbba02c64eaccfe8d8bb`;业务规则 `4236dd1d219cc6235537adfd8d0411308c449971`;产品索引 `0d9924b4566e567edf167ba678fedde28a41cfd3`;SYB 契约 `f596931468caf524cbd9d90b3c299b32a8cf8228`。 - `harness.py sync` 已完整导出。独立 `sync --check` 因 Gitea 直连读取超时未返回成功码;随后通过 Gitea MCP 对上述四页逐字比较正文并核对镜像 revision,四页均 `content_equal=true`、`revision_equal=true`。 - 保留无关未跟踪文件 `gitea.zip`,未纳入提交。
Author
Owner

后续缺陷 #125 已修复 #119 新迁移的版本号冲突:提交 7b55745 已推送;本机迁移成功,Supervisor API Running,8010 健康检查 200。#119 的业务实现不变,继续等待用户验收。

后续缺陷 #125 已修复 #119 新迁移的版本号冲突:提交 `7b55745` 已推送;本机迁移成功,Supervisor API Running,8010 健康检查 200。#119 的业务实现不变,继续等待用户验收。
Author
Owner

用户于 2026-08-28 明确确认本工单验收通过。按项目流程记录验收结论并关闭工单;本次仅更新工单状态,无新增长期文档事实,不重复同步 Wiki。

用户于 2026-08-28 明确确认本工单验收通过。按项目流程记录验收结论并关闭工单;本次仅更新工单状态,无新增长期文档事实,不重复同步 Wiki。
ila closed this issue 2026-08-28 15:07:24 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#119