Files
shanxia2.0/openspec/changes/pl-contract-cert-quota-control/tasks.md
T

174 lines
23 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.
# 实施与验收清单
状态:本地实现与独立业务审查已完成;MySQL5.7事务实机验证由用户明确延期,未部署或关闭工单。第1–6节保留初始验收清单,第10节记录本次交付边界。实施目标集成分支沿用项目V3.0配置。易制爆合法使用证明后补且不影响安排已由用户确认,见design第9节。
## 1. 档案与SQL
- [ ] 根据docs/sql/designs/2026-10-25-purchase-transport-cert-draft.sql新增正式迁移;在隔离MySQL5.7验证8表、UUID与公共字段,不直接执行设计草案到业务库。
- [ ] 新增backend/app/models/pl_cert_models.py、app/schemas/pl/cert.py、app/services/pl_cert_service.py及app/api/pl/cert.py;注册两个路由入口。核心档案字段、可空附件、entry_mode、allocation_seq在读写schema与前端一致。
- [ ] 新增backend/tests/test_pl_cert_archive.py:覆盖两种建档、全部子字段、重复证号、跨租户拒绝、补图不改余额和原ID。
- [ ] 接入既有图片解析能力,先确认可用服务;只返回白名单候选字段,数量单位可编辑,不自动启用。验证失败手填、重新解析不覆盖、多个车牌和引用号。
## 2. 合同绑定与候选
- [ ] 新增app/services/pl_contract_cert_service.py及test_pl_contract_cert_scope.py,验证多对多、同合同产品归属、范围版本和引用保护,遗漏/空集合、无变更ID保留和非法ID全回滚。
- [ ] 合同选择校验与实际装送客户分开,保持租户/权限/合同状态及业务方向约束。针对A签约B收货及供应商直送添加回归,不放宽产品归属。
## 3. 分配、预占与核销
- [ ] 新增app/services/pl_cert_allocation_service.py、pl_cert_usage_service.py;前者计算候选和可行分配,后者在调用方事务内执行,不能自行commit。
- [ ] 新增test_pl_cert_allocation.py:30拆20+10、两规格共享、稀缺证优先、重分配可行、运输引用不匹配、不同单位人工确认、车牌不匹配。
- [ ] 新增test_pl_cert_usage_transactions.py,在隔离InnoDB实际验证跨车并发锁、两证整体回滚、同operation_id重试、修改请求冲突、改派失败保留原占用。
- [ ] 新增test_pl_cert_settlement.py:29按20+9、18按18+0、超过30补分配/不足异常、多产品逐项实际量、异单位不按比例、重复归档、调整差额与取消释放。核对明细/汇总/流水/主档余额一致。
- [ ] 将预占接入plan_service.py、api/pl/transport.py、api/pl/plan.py的安排、直接创建运输和确认归档入口;覆盖全部旁路,临时归档保存不冒充正式结转。
## 4. 齐备逻辑退出与界面
- [ ] 移除design第6节列出的四个齐备服务函数的业务调用,替换所有放行判断。已上传附件与ready=1仍须通过额度校验。
- [ ] 旧hazard-cert-ready接口改为410并撤销写权限入口;旧字段留历史审计但不参与业务。更新schema、列表筛选、导出、角标、待办通知及小程序接口检查。
- [ ] 更新Web/H5计划用证页面和共享composable:删除确认/取消/批量齐备按钮;返回动态缺口与原因,展示两类分配列表及已预占/已核销。移除“先齐备再补图”的提示。
- [ ] 两种建档方式共用表单,按当前Web视觉规范/参考页选型;选择P01-P27具体模式并记录后再开始UI实现,小程序遵循自身规范。
- [ ] 增加前端与API回归:旧齐备不存在、无图手工证可按额度使用、解析值可改、异单位需要填量、余额变化需重校验、旧客户端不旁路。
## 4A. 合法使用证明独立资料界面
- [ ] 新建独立Web/H5资料维护界面并提供小程序入口,列出计划与易制爆产品明细、附件、待上传/已上传;统一业务名称“合法使用证明”,无齐备按钮、无额度分配。
- [ ] 独立附件维护接口复用既有`legal_use_cert_url`,保存原明细ID及历史附件,服务端按租户/权限/计划产品归属校验,允许安排后补传,不通过重建计划或子行实现;补图不改占用、实际量、归档及库存。
- [ ] 上传情况筛选和待补资料角标独立于运输用证缺口,图片缺失不进入安排失败原因;移除后端所有合法使用证明运输前置检查。
- [ ] 新增`backend/tests/test_pl_legal_use_document.py`:纯易制爆未上传可安排、混合产品两证不足仍拒绝、两证充足且未上传可安排、安排/归档后补图保持ID及额度不变、跨租户/错误产品归属拒绝、遗漏附件不变、显式清空授权校验。
- [ ] 前端回归独立入口可达、待上传筛选、补传/预览/下载、权限按钮;旧附件可见,资料补充不回写已废弃齐备状态。
## 5. 数据切换与验证
- [ ] 按design第8节清点历史档案、期初及在途占用;有数据缺口不虚构额度,冻结受影响新安排直至补齐。已关联工单#4,远端回写仍按会话授权执行。
- [ ] 在受控测试环境运行新增专项pytest;命令在测试文件创建后执行:`cd backend && venv/bin/python -m pytest tests/test_pl_cert_archive.py tests/test_pl_contract_cert_scope.py tests/test_pl_cert_allocation.py tests/test_pl_cert_usage_transactions.py tests/test_pl_cert_settlement.py -q`。
- [ ] 执行受影响既有计划/运输/归档测试;`cd web-admin && pnpm build:typecheck`,Web/H5人工验证两证20+10到20+9、多车共享、无齐备按钮;小程序验证实际入口而非占位测试。
- [ ] 验证纯易制爆缺合法使用证明仍可安排,混合产品按需满足两证额度且不受该证明缺失阻断,完成后切换公共门槛。不执行graphify,不默认部署/启停服务、不自动关单验收。
## 初始方案检查记录(实施前历史记录)
只读核对旧函数、调用入口、前端按钮及列表/角标;DDL和规格执行静态一致性检查。没有运行应用测试、数据库迁移或外部识别服务。方案尚未实施。
## 6. 工单 #4 核对后补充的实施前置项(初始清单;最新证据见第8–9节)
- [ ] 确认design第10节候选技术方案:在8张领域表之外增加请求级幂等记录,或提供满足同等约束的持久化方案;正式DDL前确定。
- [ ] 覆盖同operation_id跨计划、改选不同证件、不同动作、同号不同载荷及无需两证安排的重试;成功结果必须可恢复,失败无部分结果。
- [ ] 明确有效次数的可执行策略、次数事件身份与期初一次已用标记;覆盖零实际量但已有执行证据、多产品共用一次、取消后恢复与已执行不得恢复。
- [ ] 落实装送来源配对及唯一计量侧;覆盖一装多送、多装一送、同SKU多合同及来源无法配对,不能仅靠usage item唯一键宣称已去重。
- [ ] 确认超量异常处理:保存真实发生及异常、保留原占用,额度不足不能成功结转;覆盖回滚后事实仍可追溯与补证后重试。
- [ ] 对联合分配增加购买证与运输证引用反例、稀缺产品反例及计算资源限额处理;限额返回与业务额度不足区分。
- [ ] 更新H5 `model.test.ts`、小程序卡片字段测试及`mp_api_smoke.py`的旧齐备成功期望,补充所有安排入口拒绝旁路的回归。
- [ ] 合法使用证明独立接口覆盖同批次重复ID、非法ID全回滚、附件遗漏保持、归档后补传、无库存/用证副作用。
2026-11-01补充记录:工单正文及全部评论已读(0评论、无图片);代码与草案静态核对完成,未连接数据库。本节记录待开发事项,不勾选功能完成。
## 7. 已确认实施顺序(2026-11-01)
用户已确认第10节方案并同意进入开发。任务分支`codex/gitea-issue-4`,worktree为`/Users/zlwu/.codex/worktrees/gitea-issue-4/shanxia2.0`;默认Agent测试。原工作目录未提交改动保留。以下执行步骤补充上述验收清单,不另复制需求。
### A. 持久化与档案基础
- [x] 先新增`backend/tests/test_pl_quota_cert_archive.py`,使用内存SQLite独立建表,覆盖无图建档、Decimal、字段遗漏/显式清空、跨租户/越权、历史用量保护与子行差量保存。
- [x] 从草案实现`backend/app/models/pl_quota_models.py`及正式迁移`docs/sql/2026-11-01-pl-contract-cert-quota.sql`,包含8张领域表与请求操作表;保留公共字段顺序,增加期初一次有效已使用标记。
- [x] 实现`backend/app/schemas/pl/quota_cert.py`和`backend/app/services/pl_quota_cert_service.py`,避免覆盖已有`pl_cert_service.py`。服务由调用方提交事务。
- [x] 测试命令:在backend执行项目venv的`python -m pytest tests/test_pl_quota_cert_archive.py -q`;先确认缺失实现导致失败,再实现并验证通过。
### B. 纯计算分配与结转
- [x] 在`test_pl_quota_allocation.py`先写20+10、稀缺产品、双证引用反例、单位不一致、29/18实际量、非法Decimal与计算限额测试。
- [x] `pl_quota_allocation.py`以不可变输入表示来源、候选证和引用关系,联合求解可行分配;不得访问数据库或修改余额。
- [x] 每一来源按allocation_seq结转,分别输出reserved释放与used新增;不足返回明确缺口,异单位要求显式确认。
### C. 原子账本与业务接入
- [ ] `pl_quota_usage_service.py`统一处理预占/释放/调整/归档,证件、来源与范围锁顺序一致;request操作记录和逐证日志在同事务完成。
- [ ] 在`test_pl_quota_usage.py`覆盖同号同载荷、同号异载荷、跨计划重用、改派失败保持原账、余额对账及无两证需求。
- [ ] 在隔离MySQL5.7中验证并发及失败回滚,SQLite测试不可替代锁语义验证。
- [ ] 修改plan/transport各安排入口及归档入口,明确来源配对;旧齐备写接口410,旧字段不作为放行依据。
### D. API与资料后补
- [ ] 新建`backend/app/api/pl/quota_cert.py`并在两个注册入口接入,复用认证、租户与数据范围过滤;API暴露档案、合同绑定、预览及已有占用查询。
- [ ] 独立合法使用证明接口允许安排/归档后按原产品ID更新,先验证整批身份再写,遗漏保持,无库存/运输副作用。
- [ ] 复用图片解析基础设施返回白名单候选,解析不保存、不启用;失败允许手填。
### E. 界面与旧入口退出
- [ ] 按UI规范建立Figma原型并确认,随后实现档案/合同范围/动态分配与合法使用证明界面。
- [ ] 替换Web、H5、小程序入口及类型、菜单、筛选、角标、导出和通知,更新旧测试期望。
### F. 审查与交付
- [ ] 每阶段先规格审查,再代码质量审查;修复发现后复测。
- [ ] 新增专项与受影响既有测试、Web类型构建、各端视觉检查及隔离数据库验证全部完成后记录可交付结果。
- [ ] 保留工单开启状态;未经授权不push、合并、执行生产迁移或部署。
基线:backend内`test_pl_plan_product_certs.py`及`test_pl_scan_cert_expiry.py`共8项通过(现有依赖弃用警告10条);初次从仓库根目录运行因测试相对路径错误未执行,已纠正目录重跑。
### 接入审查追加(初始清单;已接线并通过专项回归)
- [ ] `api/pl/transport.py:create_transport`整批plan_ids需租户和权限预校验,draft与正式安排明确区分;正式安排必须走统一用证事务。
- [ ] 阻止通用`PlanUpdate.transport_status`及旧`create_plan`的transport_status/archive_status客户端字段绕过安排或归档,状态转换只接受对应业务接口。
- [ ] `force_void_plan`区别未执行释放与已有执行证据,不恢复已消费的一次有效次数。
- [ ] `archive_plan(payload=None)`从明确计量来源读取已保存事实,实际量缺失拒绝结转;不得读取按计划量回退的合同统计值。
- [ ] 零实运量不能读可能残留旧值的`PlPlanProduct.actual_qty`;优先明确来源段行实际数量,包括真实0。
## 8. 当前开发证据(2026-11-01,持续更新)
- 用户已确认Figma合同关联v2(11:2),按该流程开发;不再等待原型批准。MySQL容器明确暂不启动;事务并发实机验证保持待办。
- 档案基础、纯分配器、DeepSeek候选解析、合同差量绑定、账本核心与合法使用证明独立服务已完成阶段规格和质量审查。账本128项通过;随后档案锁顺序/current-read收口仍在复测与后续整合审查范围。
- 正式安排/改派、审批、取消/强制作废、归档/实际纠错接线已实现。整业务操作号重放、MySQL1213整事务有限重试;归档额度失败保留真实数量及占用、返回quotaSettlementError,库存仅在成功结转后更新。规格审查发现审批autoflush、强制作废资格、普通写并发旁路3项,修复后相关组合216 passed(仍非MySQL锁验证)。等待复审与质量审查。
- 新Web档案、合同关联v2、合法使用证明页面及CRM合同入口已编码并阶段审查通过。合成浏览器验证合同保存保留link1/scope1,详情响应乱序和旧图片解析不能污染新表单;附件按编辑会话隔离,保存时禁止改动与关闭。
- Web/H5计划用证配置含唯一计量侧、装送配对、选证、逐证参与方/路线确认、异单位安排换算及预览;目标车辆只影响预览快照,不写DB。合成browser检查通过,390px截图已人工检查。计划列表按真实预占、结转、异常及配置状态筛选;原齐备UI入口被替换。
- Web/H5合法使用证明支持安排/归档后补传,显示授权可见合同与实际装送单位,H5支持上传状态筛选,小程序入口已接线。新增加关系上下文和动态列表回归;planning/sources/legal/api组合34 passed。限定规格复审PASS,质量审查中。
- 新增总量更正API/流水查看与异单位实际用量核对弹窗;总量API测试先404失败,补实现后4 passed。实际量纠错必须理由及依据。此新增范围仍须独立审查及界面验证。
- 最新Web构建曾通过39.70秒;后续修改需最终重跑。全量vue-tsc既有大量错误(/tmp/shanxia-issue4-typecheck.log);新模块未出现报错,不能称全库类型检查通过。Frontend模型/卡片字段测试7 passed。
- 尚未完成:超原预占补量与对应缺口诊断、最终全链路回归/审查、全部新界面视觉验收及SQL人工核对。旧字段最终检索与通知/导出核对仍需收口;不能宣称整单交付。
- 临时Vite任务worktree预览127.0.0.1:5176,仅合成接口;未启动后端、MySQL或业务数据库。主目录node_modules软链接复用,无依赖安装。收尾停止本次预览进程。
- DeepSeek仅以合成测试图片验证成功,未上传真实业务证件。密钥未进入Git。
- SQL迁移未执行,新菜单不自动授予新写权限。远端工单写入、push/合并、部署均未执行。
## 9. 补分配及收口证据(2026-11-01)
- 业务接入质量复审PASS:阻止终态计划被旧审批重新占用;审批使用当前租户有效车辆主数据并校验指定审批人;单计划调整共享运输须先拆分,不能只重算其中一单。独立业务回归66 passed;两处产品查询补齐租户与计划条件。
- 档案当前读/锁顺序复审PASS,35项通过;确认/复核重放读取当前证件及期初流水,重复操作失败整体回滚。未运行MySQL并发。
- 补分配已编码:显式quotaAllowSupplement,候选及人工条件随归档同一请求提交;保留原分配容量、顺序、ID,同证/新证补量、异单位证面补差、明确人工拆分换新证,实际量不改写。当前source_snapshot记录本次补量,逐证日志保存原段/补段和人工依据;失败保留已保存事实与原账。待独立规格、质量复审。
- 预览返回按证种和单位的需求、余额上界和缺口下界,共享池只计一次。异单位不直接相加;余额足但产品/引用约束不可行时提示核对条件,不能当作可安排。
- Web/H5实际量核对界面已接补候选选择,原来源及装送配对锁定,原段与补段人工量分开。合成浏览器校验返回补量意图、两证条件及理由/依据,未调用业务后端。H5合法使用证明Vant筛选循环更新已修复,合成保存保留原产品ID;总量更正浏览器回归通过。
- 用证弹窗保存/预览旧回包跨会话问题已按独立规格反馈修复;2项真实生产handler回归先失败再通过,限定复审PASS。新增实际量补充候选回包和关闭意图测试3 passed。
- 最新后端组合449 passed、14既有警告(全部quota模块、独立合法证明、库存差量归档、作废、计划筛选、角标、旧产品附件和证件到期扫描)。日志/tmp/shanxia-issue4-final-backend.log。
- 新前端模型/卡片/移动状态/归档/配置/补量提交回归37 passed。首次使用Node原生strip-types跑含扩展名省略import的模型测试出现模块解析失败,改为项目已有tsx后37项全部通过。日志/tmp/shanxia-issue4-final-ui.log。
- 迁移后旧移动组合85项中81 passed、4 failed;4项均为原主目录同样存在的voidForce测试桩错误,主目录基线120项中116 passed、4 failed。本次未修复无关基线。
- SQL静态核对:9表字段及顺序逐一与SQLAlchemy模型一致;utf8mb4索引上界均不超过3072字节,DDL使用InnoDB/DYNAMIC。菜单DML已合并为一个事务。此为静态检查,不替代MySQL5.7实际执行。
- 最近Web构建通过38.17秒;之后补分配UI待最终重跑。vue-tsc全库仍有既有错误,新quota/legal模块无报错;不能宣称类型检查通过。
- 未执行迁移、真实数据库连接、容器、生产服务动作、远端工单写入、提交、push或合并。当前仍为开发/审查中,整单未验收关闭。
## 10. 本地实现收口(2026-11-01)
- [x] 用户批准的合同关联v2:合同→合同产品行→购买证/运输证各自适用产品,合同与档案两侧维护;绑定不扣额度,同证共享余额。
- [x] 无图手工建档、图片候选解析后确认、期初与复核、总量更正及流水;差量保留档案引用与合同产品范围ID。
- [x] 动态来源配对与逐证条件确认、双证联合分配、原子安排/改派/审批/取消、实际量归档与纠错、超量补分配;旧齐备状态不放行,旧写入口410。
- [x] 易制爆合法使用证明独立Web/H5及小程序入口,允许安排/归档后补图;独立资料待补角标,不参与运输额度判断。
- [x] 规格与质量审查完成;最终质量独立运行271 passed。计算未完成保留真实数量;历史异单位零原容量不能影响同单位原顺序,覆盖补量开关两种路径。
- [x] 最终受影响后端459 passed(14条现有警告)。前端专项37 passed、补充共享/模型11 passed、端到端元数据持久化20 passed;浏览器全部合成API,合同ID往返/乱序、计划配置、H5合法资料、总量更正、补分配提交检查通过。
- [x] 最新生产构建通过52.18秒。主目录vue-tsc基线505条错误,本worktree499条;按错误内容归一化行号及工作目录后,本次新增错误为0。全库类型检查仍未通过。
- [x] 9表SQL与模型字段/顺序及索引长度静态核对,菜单DML同事务;SQL未执行。
- [ ] MySQL5.7 InnoDB并发、锁顺序/死锁重试及真实事务回滚验证:用户明确“暂不启动容器,保留事务验证待办”。SQLite不替代该项。
- [ ] 历史真实数据期初/在途对账、数据库迁移、真实小程序WebView联调及部署验收未执行;不得从旧齐备或附件推算额度。
- [ ] 全库既有TypeScript与移动测试基线问题未纳入本工单修复,扩展移动回归的最终对比见下方更新。
保留分支`codex/gitea-issue-4`与本地worktree供审阅,未提交、推送、合并、回写或关闭工单。DeepSeek只做过合成图验证,未上传业务证件;本地密钥不进入Git。
最终移动基线对比:排除在主目录和worktree均挂起的`mobile-pl-plan-load-state.test.ts`后,主目录391项(361通过、30失败),worktree341项(311通过、30失败),失败用例名称集合一致,无本次新增失败。退休齐备父页面22项测试已移除,保留普通计划及旧子组件独立回归,单文件60/60通过;新quota/legal真实组件会话验证在专用测试中覆盖。日志`/tmp/shanxia-issue4-mobile-final-baseline.log`与`/tmp/shanxia-issue4-mobile-final.log`。先前worktree缺少venv导致的3项元数据用例已通过临时复用主目录venv重新验证(20/20),未安装依赖,临时symlink已清理。
本次127.0.0.1:5176合成预览已停止;原有应用服务未操作。最后`git diff --check`通过。以上测试不包含真实DB/小程序运行环境,工单保持开放。
## 11. 本地主分支转测(2026-11-01)
- 用户要求“请把代码合并到主分支,我来测试下”,本轮范围为本地提交并合入项目集成分支 `V3.0`;测试责任转为用户,不推送远端、不关闭工单、不启停服务、不执行数据库迁移。
- 合并前已 fetch,远端及本地主分支均为 `428a09b82`。任务基线之后两项改动为派车日历车辆配色、三方车辆承运商必填;与本工单文件无代码重叠。合并结果做 Git 核对,上一节为此前实际测试证据,本次集成运行验收待用户测试。
- 主目录已有个人开发流程升级等未提交改动须完整保留;两份重叠草案内容与任务分支一致,OpenSpec 初始方案由本次实现记录接续,合并前单独备份。保留任务 worktree 供测试反馈修复。
- 测试前需在目标测试数据库按顺序应用 `docs/sql/2026-11-01-pl-contract-cert-quota.sql`、`docs/sql/migrations/2026-11-01-pl-quota-plan-configuration.sql`、`docs/sql/migrations/2026-11-01-pl-quota-cert-menus.sql`,并按测试账号分配新增菜单权限;本次未执行。DeepSeek 配置仅在任务 worktree 的忽略文件中,未随 Git 合并复制到主目录。
## 12. 测试数据库迁移(2026-11-01)
- 用户明确授权在测试库执行,并确认目标为主目录 `backend/.env` 所指 `47.99.164.66:3306/shanxia2.0`;实际版本 MySQL 5.7.36。生产配置未连接。
- 预检查确认9张新表与 `pl_plan.cert_configuration` 均不存在。目标库的旧 `PL_GROUP_CERT` 分组已软删除,原菜单脚本会跳过Web菜单;修正为有有效分组时挂分组,否则挂有效的运输根目录,不恢复软删除分组。内存SQL回归先复现漏建,再验证两种目录状态及重复执行不重复插入。
- 已按顺序执行9表DDL、计划JSON字段、菜单DML。9表字段名称及顺序逐项与DDL一致,新表均为空;JSON字段可空。菜单事务新增2个Web入口、1个维护权限与1个小程序入口;2个旧入口改名,1个齐备按钮隐藏停用。读取验证父节点有效,旧分组仍软删除,角色菜单关系数量未变。
- 执行前备份现有 `pl_plan`/`sys_menu` 建表结构和本租户菜单数据,未声称完整业务库备份。实际SQL副本、SHA256与逐语句执行/验证记录位于主目录忽略路径 `.local/agent/backups/issue4-test-db-20261101-190227/`,目录0700、文件0600。
- 以上证明测试库迁移已执行,不替代额度并发、死锁重试、业务事务回滚或完整应用验收。未改角色授权、录入业务数据、启动容器、启停服务、推送远端或关闭工单;仍待用户测试。测试账号需要分配新菜单/维护权限并重新登录。