# 自助棋牌室系统开发总纲(V5.7) > 文档版本:V5.7(中文 Git 提交门禁 + `fd6be4f` 最新源码校准 + M09-D1 在制恢复 + 持续工程开发版) > 更新日期:2026-08-11(Asia/Shanghai) > 直接前序版本:V5.6;本文完整继承 V5.6 的全部功能、架构、协议、部署、安全、测试、验收和持续开发要求。 > 最新已审计提交证据:`fd6be4f9b98bb9213e95973069c402915a8ba6f2`,且上传快照中 `HEAD == origin/main`;其后的 M09-D1 工作区代码尚未提交、尚未通过全部门禁。 > 默认执行起点:保护并继续完成当前 M09-D1 在制工作;通过编译、全量测试、真实 MySQL 往返和静态门禁并以中文提交推送后,才能进入 `M09-D2 → M09-D3 → M09-D4 → M09-REGRESSION → M10-A/B/C/D → M10-RC1`。 > 唯一交接目标:Codex 只阅读根目录 `V5.7.md`,即可保护当前工作区,直接继续工程编码、测试、中文提交、推送和远端校验,自动推进至 `CODE_COMPLETE`,外部条件具备后继续至 `PRODUCTION_ACCEPTED`。 > **V5.7 最高优先级控制规则:** 本文开头“V5.7 增量控制层”和全文最后“第 30 章 V5.7 最终固定游标”共同构成唯一当前执行入口,优先于中间完整继承的 V5.6/V5.5/V5.4 历史标题、旧 HEAD、旧队列、旧示例和旧入口。中间历史正文继续作为完整需求与验收依据,但不得据此把执行游标回退到已经有工程证据的阶段。 --- # V5.7 增量控制层 ## V5.7-0 M09-D1 收口覆盖层(2026-08-11 最新真实仓库) 本节记录 `fd6be4f + M09-D1 在制工作区` 之后的真实工程进展,优先于下方审计快照中的 M09-D1 `DOING`、缺失断言和旧 HEAD 描述: - Git 中文提交门禁已由 `2de796143ff418d681fdb972040b8555a8e058d1` 以 `chore(V5.7): 增加中文提交信息校验门禁` 提交并推送,`HEAD == origin/main`,后续业务提交继续强制中文标题。 - M09-D1 当前工作树已完成 9 张商品/库存表、分类/商品/SKU/门店售卖、跨日营业时段、库存策略、可用/锁定/损耗库存、幂等请求和不可变流水;商品/库存 API、RBAC 与租户/门店范围已接线。 - 迁移 runner 已按单个 marker/checksum 增量执行 pending 迁移,interrupted up/down DDL 可原地重试,同库 up/verify/down 由专用连接上的数据库命名锁串行化;包含触发器的迁移会在任何触发器 DDL 与建表前检查生产前置,binlog 开启时要求 `log_bin_trust_function_creators=1` 和独立迁移身份。 - `assertProductInventoryFoundation` 已实现并调用;M09-D1 静态门禁、后端 build/full test、管理端 build/test 已通过。WSL MySQL 8.4.10 的 `up → verify → down → up → verify` 通过,计数为 179 up、141 verify、171 down,增量/崩溃重试与 cleanup probe 通过。 - M09-D1 工程与本文档伴随记录待以 `feat(M09-D1): 完成商品目录与库存流水底座` 中文业务提交取得 SHA;文档不得虚构尚未产生的提交号。 - 唯一执行游标已推进到 `M09-D2`,下一目标为商品订单、订单项快照、支付衔接,以及库存锁定、扣减、释放和取消回补。M09-D1 若出现回归只做针对性修复,不得删除重做。 ## V5.7-1 本次升级的唯一事实边界 1. V5.7 以用户提供的 `V5.6(2).md` 为完整需求底稿;底稿共 `6734` 行,SHA-256 为 `8fe7171ab5b7782d56345c426432cbf349da0956da2bac56d348f360665fd803`。本文件继续完整继承该正文,但当前状态和执行入口以 V5.7 文首控制层及文末第 30 章为准。 2. 最新工程快照为用户上传的 `qipai - 副本(2).zip`:`55177129` 字节、`1196` 个压缩条目,SHA-256 为 `cc802fecbea399698e0a9c1b38127bc12ff260d8f4d6a084828108307f557d6f`;压缩数据完整性检查通过。 3. 快照包含完整 Git 元数据:`HEAD == origin/main == fd6be4f9b98bb9213e95973069c402915a8ba6f2`,分支为 `main`,最新提交时间 `2026-08-11T02:13:17+08:00`,标题为英文 `docs(M09-C): record settlement closure and advance cursor`。 4. `fd6be4f` 的上一工程提交为 `1f1071501f4954ad0440d79c2a38e7210393e928`,标题同样为英文 `feat(cleaning): close settlement integrity and reconciliation`;该提交真实完成 M09-C 工程,随后 `fd6be4f` 回填状态并把游标推进至 M09-D1。两项已推送英文提交均保留历史,禁止擅自改写共享 `main` 或强推。 5. 快照已跟踪 `544` 个文件;现有后端 `84` 个 TypeScript 源文件、`48` 个 MJS 测试,数据库迁移目录 `109` 个文件,`docs/` `125` 个文件。上述数量只用于识别本快照,不是完成度指标。 6. M09-D1 当前不是空白待办,也不是已完成阶段:工作区已有商品分类、商品、SKU、门店售卖配置、跨日营业时段、库存策略、可用/锁定/损耗库存、不可变流水、路由、权限、迁移和测试等约 `4690` 行在制文件,但尚未提交。 7. 本次独立运行 `node scripts/check-m09-d1-product-inventory.mjs` 实际失败:脚本要求 `backend/tests/mysql-migration-roundtrip.test.mjs` 包含 `assertProductInventoryFoundation`,当前文件尚未实现该函数。依赖安装在审计环境中因 npm 包传输/目录错误失败,因此未把“后端全量测试、后台构建”虚报为通过;Codex 必须在真实开发环境重新安装锁定依赖并完成全部验证。 8. 两份协议原件已再次核验: - 4G(标准版)智慧插座 MQTT 协议文档:`33` 页,SHA-256 为 `a143385c1f83ed08c8c8d63c1c5541dd803f84e620e90fc6ff2e34bb91102d21`; - 4G 智能门禁控电箱 MQTT 协议文档:`48` 页,SHA-256 为 `ce89590dc4eabb338a20ec351be7b400f8ec100eecc1305eb5367a53b2854a3c`。 9. Codex 在真实 `D:\qipai` 接管时仍必须重新读取当前 HEAD、`origin/main`、工作区差异、模块游标和测试结果;真实仓库若晚于 `fd6be4f`,只能按有效工程证据向后推进,不能用本快照覆盖更晚进度。 ## V5.7-2 与 V5.6 相比的强制变化 | 编号 | V5.6 存在的问题 | V5.7 强制修正 | |---|---|---| | V57-GIT-01 | 规定了 `feat/fix/test/docs` 等类型,但没有要求标题正文必须为中文 | 冒号后的摘要必须包含中文并以中文表达;禁止全英文摘要 | | V57-GIT-02 | `git push` 后只校验 SHA 一致,未校验远端提交标题语言 | push 后同时校验 `origin/main` 的 SHA 和最新 commit subject 中文门禁 | | V57-GIT-03 | Codex 可能把终端英文输出直接当作用户回执 | 命令原始输出可保留,结论、提交说明、推送说明、阻塞原因和最终回复必须为中文 | | V57-GIT-04 | 缺少仓库级自动门禁 | 增加可跟踪的中文提交检查脚本、commit-msg hook、安装脚本和测试;不能只靠提示词自觉 | | V57-GIT-05 | 历史队列仍包含已闭环阶段,容易误回退 | 第 30 章只保留实际当前阶段及后续队列;更晚仓库证据可继续向后跳过 | | V57-DEV-01 | 文档升级后可能再次停留在 Markdown 回填 | V5.7 文档提交不计业务进度;下一普通开发必须先完成 Git 中文门禁工程,再立即进入当前业务阶段 | | V57-DEV-02 | 旧 V5.7 没有读取新副本,无法描述 M09-D1 未提交工程 | 固定 `fd6be4f + M09-D1 worktree` 恢复点,保护约 4690 行在制实现,禁止删掉重做或提前标记完成 | | V57-TEST-01 | M09-D1 静态门禁已经接入,但真实 MySQL 断言函数缺失 | 必须实现 `assertProductInventoryFoundation` 并跑完真实 MySQL 往返;禁止删断言、写空函数或只靠 Mock 过关 | | V57-GIT-06 | 历史总纲/参考资料删除与业务改动混在工作区 | M09-D1 只能显式暂存;未获用户确认前删除项保持未决,不提交、不恢复、不阻断独立工程 | ## V5.7-3 Git 中文提交与推送最高优先级门禁 ### V5.7-3.1 “推送为中文”的准确含义 `git push` 命令本身没有标题。Gitea 的推送动态、提交列表和版本记录展示的是 Git commit subject,因此必须从 `git commit` 源头强制中文: - 提交标题冒号后的功能摘要必须使用简体中文; - 提交正文、脚注、回滚原因和协作说明必须使用中文; - Codex 的阶段结果、push 说明、测试结论、阻塞原因和下一步必须使用中文; - 如后续使用 Pull Request/Merge Request,其标题、正文、Review 回复和合并说明必须使用中文; - Release 名称、更新日志和部署回执必须使用中文; - `feat`、`fix`、`refactor`、`test`、`build`、`chore`、`docs` 等 Conventional Commits 类型、模块编号、API/MQTT/MySQL 等技术专名允许保留英文;它们不构成“英文提交说明”。 ### V5.7-3.2 固定提交格式 ```text <类型>(<模块编号或稳定范围>): <中文摘要> ``` 推荐示例: ```text feat(M09-D1): 建立商品、SKU 与库存流水底座 fix(M09-D2): 修复并发支付导致的库存重复扣减 test(M09-D3): 补充寄存凭证并发领取测试 refactor(M10-A): 统一通知发件箱的渠道重试逻辑 chore(V5.7): 增加中文提交信息校验门禁 docs(spec): 升级开发总纲至 V5.7 并固定中文提交规则 ``` 禁止示例: ```text feat(cleaning): close settlement integrity and reconciliation fix(stock): handle race condition chore: update docs test(order): add tests ``` 附加约束: 1. 摘要必须说明可识别的工程结果,禁止只写“更新代码”“修复问题”“继续开发”“优化逻辑”。 2. 标题建议不超过 `72` 个可见字符;确需补充时使用中文正文说明原因、风险和验证。 3. scope 优先使用 `Mxx-X` 模块编号或稳定范围,禁止临时创造大量英文 scope 来替代模块游标。 4. `docs(spec)` 只用于用户明确要求的总纲升级;普通模块文档伴随工程提交,不拆成额外英文 docs-only 提交。 5. 自动生成的 Merge/Revert 标题也必须在提交前改成中文;不能把 Git 默认英文文本直接推送到 `main`。 ### V5.7-3.3 仓库级机器门禁 Codex 读取 V5.7 后,若仓库尚无等效实现,必须先完成一次 `V5.7-GIT-CN-GATE` 工程准备,再继续业务阶段。最小交付如下: - `scripts/check-commit-message.mjs`:读取提交消息文件或传入字符串,校验首行至少包含一个 CJK 统一表意文字,且符合允许的类型/模块格式; - `.githooks/commit-msg`:调用上述 Node 脚本,失败时返回非零并输出中文错误; - `scripts/setup-git-hooks.ps1`:在 Windows `D:\qipai` 执行 `git config core.hooksPath .githooks`,并验证配置生效; - `scripts/setup-git-hooks.sh`:供 WSL/Ubuntu 开发或验证环境安装同一 hook; - 对检查脚本增加正向、反向测试,至少覆盖中文摘要、全英文摘要、空摘要、Merge/Revert、含技术英文的中文摘要和多行正文; - 若仓库已有本地/CI 提交规范校验,原地扩展,不建立第二套互相冲突的规则。 注意:Git hook 不会仅因克隆仓库自动启用,所以安装脚本和 README 的一次性执行说明必须同提交落地;不能只提交 `.githooks/commit-msg` 就宣称所有电脑已经受保护。 `V5.7-GIT-CN-GATE` 可以独立形成一个工程工具提交,推荐标题: ```text chore(V5.7): 增加中文提交信息校验门禁 ``` 该提交成功推送后,同一 Codex 会话必须立即继续当前业务阶段;不得把工具门禁当作本轮结束理由,也不得再连续创建 V5.7 说明文档。 ### V5.7-3.4 提交前和推送后的双重校验 每次提交前必须对拟用标题运行中文检查。提交后、push 前再次读取本地标题: ```powershell $Subject = git log -1 --pretty=%s if ($Subject -notmatch '[\u3400-\u9FFF\uF900-\uFAFF]') { throw "提交标题不含中文,禁止推送:$Subject" } ``` push 后必须同时验证提交 SHA 和远端标题: ```powershell git push origin main if ($LASTEXITCODE -ne 0) { throw "推送失败,保留本地提交并停止前移游标" } git fetch origin main $LocalHead = git rev-parse HEAD $RemoteHead = git rev-parse origin/main if ($LocalHead -ne $RemoteHead) { throw "本地 HEAD 与 origin/main 不一致" } $RemoteSubject = git show -s --format=%s origin/main if ($RemoteSubject -notmatch '[\u3400-\u9FFF\uF900-\uFAFF]') { throw "远端最新提交标题不含中文:$RemoteSubject" } ``` 阶段回执必须增加: ```text COMMIT_SUBJECT=<实际中文标题> COMMIT_SUBJECT_CN=PASS PUSH_VERIFIED=PASS REMOTE_COMMIT_SUBJECT_CN=PASS USER_FACING_LANGUAGE=ZH_CN ``` ### V5.7-3.5 发现英文提交时如何处理 1. **尚未 push:** 若该提交只存在本地且确认没有其他协作者基于它开发,可以执行 `git commit --amend -m "<中文标题>"`,重新运行测试和中文门禁后再推送。 2. **已经 push 到共享 `main`:** 默认保留历史,不得擅自 `rebase`、`filter-repo`、修改旧 commit 或 `git push --force`。在状态记录中注明 `HISTORICAL_ENGLISH_COMMIT_PRESERVED`,从下一提交开始中文化。 3. **用户明确要求改写历史:** 必须先单独评估协作者、部署引用、tag、回滚点和备份,再取得用户明确授权;V5.7 本身不授予强推权限。 4. 已知 `1f10715` 与 `fd6be4f` 均属第 2 类。Codex 不得为了把它们改成中文而改写 `main`;V5.7 的修复目标是确保 `fd6be4f` 之后的提交和推送动态全部使用中文。 ## V5.7-4 最新状态自适应恢复规则 V5.7 的默认游标建立在本次已审计快照 `fd6be4f + M09-D1 未提交工作区` 上,但真实仓库仍具有最高优先级。Codex 必须按以下顺序恢复: 1. 确认工作目录为 `D:\qipai`,Git 根目录、`main` 分支和 `origin` 地址符合本项目约束。 2. 执行 `git status --short --branch --untracked-files=all`、`git log -20 --oneline --decorate`、`git fetch --prune origin` 和 `git rev-list --left-right --count main...origin/main`。 3. 保护所有未提交修改,按文件和模块识别归属;禁止 `reset --hard`、`checkout -- .`、`clean -fd`、无差别 `git add -A`、无差别 stash 和强推。 4. 检查 `fd6be4f` 是否为当前 HEAD 的祖先。是:只审计 `fd6be4f..HEAD` 与当前工作区;否:停止高风险操作并报告分叉,不能自行覆盖。 5. 读取 `docs/module-status.md`、`docs/feature-status.md`、`docs/current-baseline.md`、最近开发日志、迁移和测试;只有工程文件、测试和提交共同证明的阶段才允许跳过。 6. 若真实仓库仍为 `fd6be4f` 且存在下述 M09-D1 文件,必须原地续写,不能删除重做;若文件已由更晚提交闭环且验证通过,则进入第一个未闭环阶段。 7. 若 README 或固定状态文件仍写 V5.6,在当前 M09-D1 工程提交中伴随更新为 V5.7;不得为版本号同步再拆一个 docs-only 提交。 8. 历史英文提交只记录不改写;在第一次新提交前安装或验证中文门禁,新的提交标题必须为中文。 ### V5.7-4.1 必须保护的 M09-D1 在制范围 以下是上传快照中已经明确识别的 M09-D1 工程文件。列表用于恢复与显式暂存,不表示文件已经验收通过: | 范围 | 在制路径 | 当前结论 | |---|---|---| | 商品目录 | `backend/src/products/product-catalog-repository.ts`、`backend/src/routes/products.ts` | 已实现分类、商品、SKU、门店售卖设置/时段和版本冲突主体,必须复核租户/门店范围、软删除和并发更新 | | 库存领域 | `backend/src/inventory/inventory-service.ts`、`backend/src/routes/inventory.ts` | 已实现策略、入库、调整、盘点、损耗以及批量锁定/释放/扣减主体,必须完成真实 MySQL 并发与幂等验证 | | 应用接线 | `backend/src/app.ts`、`backend/src/server.ts`、`backend/package.json` | 已注册产品与库存路由并加入测试链,尚需编译和全量回归 | | 权限 | `backend/src/auth/auth-repository.ts`、`backend/src/auth/rbac-repository.ts`、`backend/src/routes/admin-auth.ts` | 已增加商品/库存权限和后台菜单,必须验证 STAFF/STORE_ADMIN/TENANT_ADMIN/PLATFORM_ADMIN 及跨门店拒绝 | | 数据库 | `database/migrations/2026081107_m09d1_product_inventory_foundation.{up,down,verify}.sql`、`backend/src/db/migration-runner.ts` | 已增加 8 张商品/库存表、权限和不可变流水触发器,必须执行 up/verify/down/second-up 真实往返 | | 自动化测试 | `backend/tests/product-*.test.mjs`、`backend/tests/inventory-*.test.mjs` 及既有迁移/RBAC/认证测试修改 | Mock/契约测试主体已写,不能替代真实数据库事务测试 | | 门禁与脚本 | `scripts/check-m09-d1-product-inventory.mjs`、Windows/WSL 检查脚本 | 已接入门禁,但当前静态检查失败,必须补真实测试而不是删除断言绕过 | ### V5.7-4.2 当前已知失败与 M09-D1 收口顺序 恢复后按以下顺序继续,不得只改状态文档: 1. 在 `backend/tests/mysql-migration-roundtrip.test.mjs` 中实现并实际调用 `assertProductInventoryFoundation`;至少覆盖租户/门店唯一性、跨日营业时段、目录/SKU 版本冲突、负库存拒绝、并发库存锁定单赢家、重复 requestId 幂等、冲突指纹拒绝、锁定→扣减/释放、损耗/盘点、流水 UPDATE/DELETE 被拒绝、down 后对象清理和 second-up 恢复。 2. 先运行 `node scripts/check-m09-d1-product-inventory.mjs`,当前断言必须真正通过;禁止删除 `assertProductInventoryFoundation` 检查、改成永真或仅添加未调用的空函数。 3. 在后端目录运行锁文件安装、`npm run build`、`npm test`;随后使用 WSL MySQL 8.4.x 执行 `npm run test:mysql:migration` 或仓库规定的完整往返脚本。 4. 运行后台 `npm run build`、`npm test`,并运行 Windows `scripts/dev/windows/test-all.ps1` 或等效完整门禁;M09-D1 即使主要改后端,也不得破坏后台、小程序静态检查和既有 M06/M08/M09-B/C 回归。 5. 审查 SQL 的复合外键、unsigned 边界、触发器、down 顺序和迁移 runner 的 verify 最小行数,不得用脆弱的固定数字掩盖缺失验证结果。 6. 仅在全部内部门禁通过后更新 README、`docs/current-baseline.md`、`docs/module-status.md`、`docs/feature-status.md` 和既有 changelog/devlog;这些状态更新必须随 M09-D1 工程提交,不得先提交“完成”文档。 7. 使用显式路径暂存 M09-D1 与中文门禁文件,核对 `git diff --cached --name-status` 后,以中文标题提交并推送。推荐业务标题:`feat(M09-D1): 完成商品目录与库存流水底座`。 ### V5.7-4.3 不得混入 M09-D1 的未决删除 快照仍显示 `V4.8.md`、`V5.0.md`、`V5.1.md`、`V5.2.md`、`V5.3.md`、`V5.4.md` 以及 `参考/env`、`参考/start.sh`、`参考/stop.sh`、`参考/xjar`、`参考/后台管理系统_20260427.zip` 被删除。V5.6 已把相同问题记为未决,本次新快照仍不能证明删除意图。 - 不主动恢复、不主动提交,也不让 `git add -A` 把它们混入 M09-D1; - 在真实 `D:\qipai` 核对是否为用户明确删除或打包差异;没有用户授权时保持 `WORKTREE_DELETION_UNRESOLVED`; - 该未决项不阻塞 M09-D1/M09-D2 内部开发,但必须在 M10-RC1 仓库完整性门禁前解决; - 若用户随后明确要求删除,应单独形成中文维护提交,并在提交前确认二进制参考资料已有可恢复备份。 ## V5.7-5 唯一当前推进队列 在真实仓库没有 `fd6be4f` 之后的更晚有效工程提交时,固定队列为: ```text V5.7-GIT-CN-GATE(一次性工程工具门禁,不计业务模块完成度) → M09-D1 → M09-D2 → M09-D3 → M09-D4 → M09-REGRESSION → M10-A → M10-B → M10-C → M10-D → M10-RC1 → CODE_COMPLETE → 外部条件具备后执行真实联调与生产验收 → PRODUCTION_ACCEPTED ``` 规则: - M09-A、M06-C-R1、M06-E-R1、M06-R-REGRESSION、M08-D-R1、M09-B、M09-C 已由 `fd6be4f` 及其祖先工程提交证明闭环,不得仅因中间历史章节再次出现而重做;只有新回归失败能够触发针对性修复。 - M09-D1 为 `DOING_WORKTREE`:先保护并完成现有实现。文件很多、代码很多或静态门禁脚本存在,都不等于完成;必须获得 build、全量测试、真实 MySQL、commit、push 五类证据。 - `V5.7-GIT-CN-GATE` 缺失时只允许显式暂存其独立文件;不得把历史删除或 M09-D1 半成品意外带入工具提交。完成门禁提交后必须在同一持续目标中立即返回 M09-D1。 - 当前真实仓库若已完成队列前部阶段,直接定位第一个缺少工程/测试/commit/push 证据的阶段。 - 每个业务阶段仍必须形成真实工程变化、相关测试、中文 commit、push 和远端 SHA/中文标题校验。 - 外部微信支付、团购授权、MQTT 生产账号、真实硬件、合法域名和生产 Ubuntu 未提供时,内部工程继续推进至 `CODE_COMPLETE/BLOCKED_EXTERNAL`,不能停在商品域或 M10 骨架。 - 同一会话资源足够时,完成一个阶段后自动进入下一阶段,不等待用户再次发送“继续”。 ## V5.7-6 Codex 第一轮强制动作 Codex 收到“请阅读 V5.7.md,按当前进度继续开发。”后必须执行: ```text LOAD_V57 → INSPECT_REAL_HEAD_AND_WORKTREE → PROTECT_USER_CHANGES → VERIFY_FD6BE4F_ANCESTRY_OR_NEWER_REAL_PROGRESS → RESUME_M09_D1_WORKTREE_WITHOUT_RESET → INSTALL_OR_VERIFY_GIT_CN_GATE → RUN_GATE_TESTS → COMMIT_AND_PUSH_WITH_CHINESE_SUBJECT(如门禁尚缺) → IMPLEMENT_ASSERT_PRODUCT_INVENTORY_FOUNDATION → PASS_M09_D1_STATIC_GATE → CONTINUE_AND_FINISH_M09_D1 → RUN_RELEVANT_AND_REGRESSION_TESTS → RUN_REAL_MYSQL_ROUNDTRIP → UPDATE_EXISTING_STATUS_FILES_ONLY → COMMIT_WITH_CHINESE_SUBJECT → PUSH → VERIFY_REMOTE_SHA_AND_CHINESE_SUBJECT → AUTO_CONTINUE ``` 第一轮禁止: - 创建新的计划、审计、总结、最终版、修订版 Markdown; - 只把 V5.6 字样改成 V5.7 后结束; - 把 `V5.7-GIT-CN-GATE` 当成业务阶段完成; - 重新初始化 backend/admin/miniapp/database; - 因缺生产账号或真实硬件而停止内部商品、通知、统计、测试和部署脚本开发; - 使用英文 commit subject、英文推送说明或英文最终回执。 ## V5.7-7 每阶段中文机器回执 ```text DOCUMENT_VERSION=V5.7 BASELINE_HEAD=<本阶段开始时HEAD> ENGINEERING_DELTA=YES|NO CURRENT_STAGE= STAGE_RESULT=DONE|PARTIAL_BLOCKED_EXTERNAL|BLOCKED_INTERNAL ENGINEERING_FILES=<实际工程文件> TEST_RESULT=PASS|FAIL TEST_COMMANDS=<实际命令> COMMIT= COMMIT_SUBJECT=<实际中文标题或NONE> COMMIT_SUBJECT_CN=PASS|FAIL|NOT_COMMITTED PUSH_VERIFIED=PASS|FAIL|NOT_PUSHED REMOTE_COMMIT_SUBJECT_CN=PASS|FAIL|NOT_PUSHED NEXT_STAGE= EXTERNAL_BLOCKERS=<真实外部阻塞或NONE> USER_FACING_LANGUAGE=ZH_CN ``` 只允许在用户明确要求“仅更新文档”的本次 V5.7 交付中出现 `ENGINEERING_DELTA=NO`。下一次普通继续开发若仍为 `NO`,不得声称项目取得工程进展。 ## V5.7-8 交给 Codex 的唯一入口 用户只需发送: ```text 请阅读 V5.7.md,按当前进度继续开发。 ``` Codex 不得要求用户再次粘贴 V5.6、模块队列、协议字段或中文提交规则;本文已经完整包含。 --- # V5.6 完整继承正文(只读需求基线,当前执行入口已由 V5.7 覆盖) > 下方从原 V5.6 第一行起完整保留,确保任何功能、数据库、协议、安全、部署、测试和验收细节不丢失。凡其中出现“V5.6 为最高优先级”“请阅读 V5.6.md”“当前队列从 M09-A 开始”等文字,均属于历史执行说明,当前必须由上方 V5.7 控制层和全文最后第 30 章覆盖。 # 自助棋牌室系统开发总纲(V5.6) > 文档版本:V5.6(最新源码接管 + 漏项纠偏 + M09/M10 连续收口 + 全量测试版) > 更新日期:2026-08-11(Asia/Shanghai) > 当前工程证据基线:`1f1071501f4954ad0440d79c2a38e7210393e928` > 当前执行起点:`M09-A/B/C` 与强制返工队列均已闭环;从 `M09-D1` 继续完成 `M09-D1/D2/D3/D4 → M09-REGRESSION → M10 → RC1`。 > 目标:Codex 只阅读这一份 `V5.6.md`,即可从现有仓库和未提交工作继续编码、测试、提交、推送、校验并自动进入下一阶段,直到所有可独立完成项达到 `CODE_COMPLETE`,再在外部条件具备后达到 `PRODUCTION_ACCEPTED`。 > **V5.6 最高优先级说明:** 本章和文末“V5.6 最终固定队列”优先于本文后续继承的 V5.5/V5.4 历史游标、历史“当前进度”和示例命令。后文仍完整保留旧版功能、架构、协议、部署、安全、测试和验收要求,但凡与本章的新 HEAD、新工作区状态、新队列或新缺陷结论冲突,必须以 V5.6 为准。不得因后文出现 `M08-C` 旧游标而回退;不得因 README 仍写 V5.4 而忽略本文件。 --- # V5.6 最新源码接管与强制纠偏 ## V5.6-1 证据基线 本版已实际读取并交叉核对以下资料,不是依据 README 或目录名称猜测: 1. 用户提供的最新工程快照 `qipai - 副本.zip`:`59040193` 字节、`1727` 个压缩条目,SHA-256 为 `d57906f8a939fdfa9e79d88811ddff43733b98e6600e8a8b1b1eea2ed3ab0f32`。 2. 快照内完整 Git 元数据:`HEAD == origin/main == b35af9037f256657f38f922e7b8a9bed9eb9aee9`,提交时间 `2026-08-10T13:58:49+08:00`,标题 `docs(M08-D): 回填后台登录与会话入口`。 3. V5.5 旧基线 `19d6734b68c18a1a79dd4f5b590768cfd4f0a0e5` 是当前 HEAD 的祖先;其后已有 `50` 个提交,累计 `142` 个文件变化、`13902` 行新增、`1013` 行删除,主要完成 M08-C、M08-D 功能垂直切片。 4. 用户提供的 `V5.5(1)(1).md`:`6283` 行,SHA-256 为 `1688533a3518997e60c7f359bbca8dab875c37402e874c4050f1ef20779af645`。本 V5.6 完整继承其正文,新增规则优先。 5. 4G 智慧插座 MQTT 协议 PDF:`33` 页,SHA-256 为 `a143385c1f83ed08c8c8d63c1c5541dd803f84e620e90fc6ff2e34bb91102d21`。 6. 4G 智能门禁控电箱 MQTT 协议 PDF:`48` 页,SHA-256 为 `ce89590dc4eabb338a20ec351be7b400f8ec100eecc1305eb5367a53b2854a3c`。 7. 当前已跟踪文件 `520` 个;后端 `80` 个 TypeScript 源文件、`44` 个 MJS 测试;后台 `18` 个 Vue 组件;小程序 `app.json` 注册 `16` 个页面;数据库有 `99` 个 SQL 迁移文件;`docs/` 有 `119` 个文件。 8. 最新工程快照根目录只存在 `V5.4.md`,用户提供的 V5.5 尚未纳入该快照;README、`docs/configuration.md`、`docs/current-baseline.md` 仍把 V5.4 写成权威总纲。这是状态同步缺陷,不代表代码应回退到 V5.4。 若 Codex 实际接管时 HEAD 晚于 `b35af90`: - 先执行 `git merge-base --is-ancestor b35af90 HEAD`;返回 0 才把新提交视为本基线的后继。 - 禁止 reset、rebase 覆盖、强推或恢复到 `b35af90`。 - 只审计 `b35af90..HEAD` 与当前未提交差异,按代码、迁移、测试、commit、push 证据跳过已真实完成项。 - 若分叉、远端领先或来源不明,保护所有修改,停止高风险 Git 操作并报告;不得自行选择一边覆盖。 ## V5.6-2 当前工作区不是干净快照 上传快照的 Git 工作区在 HEAD 之外还有修改,Codex 必须把它当作在制工作保护,不得执行 `git reset --hard`、`git checkout -- .`、`git clean -fd` 或无差别 `git add -A`。 ### 已识别的在制 M09-A 修改 | 路径 | 当前差异 | V5.6 结论 | |---|---|---| | `backend/src/cleaning/cleaning-task-repository.ts` | claim/assign/reject/reclaim/submit/状态迁移改为事务;加入 `FOR UPDATE`、`SKIP LOCKED`;事件与状态同事务;重指派和超时回收清理旧状态 | 明确属于 M09-A 在制工程,必须恢复并补完,不得丢弃 | | `backend/tests/mysql-migration-roundtrip.test.mjs` | 仅新增 `CleaningTaskRepository/CleaningTaskError` import,尚无对应测试正文 | 明确是未完成测试,单独 import 不能作为测试证据,必须补真实 MySQL 场景后再提交 | ### 不能混入 M09-A 提交的删除项 快照显示 `V4.8.md`、`V5.0.md`、`V5.1.md`、`V5.2.md`、`V5.3.md` 以及 `参考/env`、`参考/start.sh`、`参考/stop.sh`、`参考/xjar`、`参考/后台管理系统_20260427.zip` 被删除。无法仅凭压缩包判断这是用户有意删除、打包遗漏还是大文件排除。 强制处理: 1. M09-A、协议返工和后续模块统一使用显式路径 `git add <本阶段文件>`,不得把上述删除混入提交。 2. 不主动恢复,也不主动提交删除;先用真实 `D:\qipai` 工作区再次核对。 3. 若真实工作区也删除且用户未明确意图,登记为 `WORKTREE_DELETION_UNRESOLVED`,不阻塞独立工程开发;到 M10 仓库完整性收口前必须解决。 4. V5.6 文档必须新增为根目录 `V5.6.md`;V5.5 作为历史只读备份保留。旧版是否继续跟踪由真实仓库事实和用户决定,不得借版本升级批量删除历史总纲。 ## V5.6-3 实际验证结果 ### 已提交 HEAD `b35af90` 的验证 | 验证 | 结果 | 边界 | |---|---|---| | `backend/npm test` | PASS | TypeScript build 和 package 中串联的 43 个运行测试通过;不等于真实微信/硬件通过 | | `admin/npm run build` | PASS_WITH_WARNING | `vue-tsc` 与 Vite 构建通过;`element` chunk `923.28 KiB`,超过 500 KiB,必须在 M08-D-R1/M10 收口 | | 四个 `scripts/check-*.mjs` | 在无空格/中文路径 PASS | 逻辑门禁通过,但可移植性缺陷仍存在 | | Shell `bash -n` | PASS | 仓库内 shell 语法通过;未代表生产执行成功 | | `deploy-business.sh --dry-run .` | PASS | 生成 `DRYRUN-b35af90` manifest,明确 build/migration 未运行、`deployed=false` | | WSL MySQL 8.4.10 | 仓库日志记录 PASS | `0511008` 日志记录 144 up、124 verify、140 down;本次审计容器无 MySQL 客户端/服务,未重复实测 | ### 含未提交 M09-A 修改的验证 - `backend npm test`:PASS。 - `admin npm run build`:PASS_WITH_WARNING,仍为 `element 923.28 KiB`。 - 上述结果只证明当前差异可编译且未破坏既有模拟/契约测试;因为 MySQL 集成测试正文尚未编写,M09-A 仍是 `DOING`,不得提交“完成”文档。 ### 四个静态脚本的共同缺陷 以下文件都使用 `new URL('..', import.meta.url).pathname`,在包含空格或中文的路径中把 `%20/%E5...` 当作真实文件名,全部失败: - `scripts/check-miniapp-m08-a.mjs` - `scripts/check-miniapp-m08-c.mjs` - `scripts/check-admin-m08-b.mjs` - `scripts/check-admin-m08-d.mjs` 统一修复为 `fileURLToPath(new URL('..', import.meta.url))`,并增加带空格/中文临时目录回归。不得只修一个脚本。 ## V5.6-4 当前模块真实状态 | 范围 | V5.6 校准状态 | 说明 | |---|---|---| | M00 | PARTIAL/BLOCKED_EXTERNAL | 单仓库与脚本骨架存在;生产 Ubuntu、证书、EMQX、备份/恢复仍未现场验收。不得回到 M00 扩写审计文档,归入 M10 上线收口 | | M01-M04 | DONE | 已有工程、迁移、权限、订单和测试证据;仅做回归或被后续需求触发的兼容修复 | | M05 | PARTIAL_BLOCKED_EXTERNAL | 微信支付、团购、分账工程链路存在;真实商户和厂商授权未提供 | | M06 | PARTIAL_INTERNAL_REMEDIATION + BLOCKED_EXTERNAL | M06-A-F 原工程存在,但 V5.5 要求的协议原件一致性返工被跳过;M06-G 实物仍外部阻塞 | | M07 | DONE | 双余额、充值、优惠券/套餐和会员聚合已有证据 | | M08-A | PARTIAL_BLOCKED_EXTERNAL | 顾客端独立工程链路存在;真机合法域名、真实支付和实物开门待外部条件 | | M08-B | PARTIAL_BLOCKED_EXTERNAL_SCOPE_FROZEN | 保洁端功能已明显超出最小范围;禁止继续增加联调表格/导出/签署类功能 | | M08-C | PARTIAL_BLOCKED_EXTERNAL | 管理员/员工小程序功能垂直切片已提交;真实团购/微信/硬件待外部联调 | | M08-D | PARTIAL_INTERNAL_REMEDIATION | 页面/API 功能切片已提交,但没有 Vue Router、没有路由级懒加载、`App.vue` 仍静态导入全部域、Element chunk 923 KiB;不能把 V5.5 的 D1/D6 架构门禁标为完成 | | M09-A | DOING_UNCOMMITTED | 工作区已有事务化差异,MySQL 测试仅 import 未成形;必须先恢复完成 | | M09-B/M09-C | PARTIAL_EXISTING | 图片、验收、驳回、统计、结算已有大量 M08-B 代码;只做领域收口和缺口测试,不重建第二套 | | M09-D | TODO | 未发现商品分类、SKU、库存账、商品订单、寄存/取出正式领域表、服务、页面或测试 | | M10 | TODO/PARTIAL_FOUNDATION | 只有通用 outbox/worker 和部分统计/部署骨架;通知中心、完整口径、扩展、压测、生产发布与最终验收未闭环 | ## V5.6-5 V5.5 被跳过的 P0 协议返工仍未完成 代码证据仍显示: - `backend/tests/iot-protocol.test.mjs` 继续构造 `powerW: 3601, temperature: 82, overLoad: true`。 - `backend/src/devices/jilian-adapters.ts` 仍以单一过窄 `resultCode` 枚举解析全部命令。 - `docs/mqtt-protocol-mapping.md`、`docs/hardware-vendor.md`、`docs/unresolved-issues.md` 仍写“PDF 原件未提供”。 - `ISSUE-013` 仍是 `BLOCKED_EXTERNAL`,与本次已提供的两份 PDF 冲突。 - `b35af90` 之前的 M08-C/M08-D 新提交未包含 `M06-C-R1/M06-E-R1` 协议文件修改。 因此 M06 不能只写 `BLOCKED_EXTERNAL`。协议文档和 fixture 是内部可完成项,必须修正;只有实物行为才是外部阻塞。 ### 智慧插座原件必须落地的字段 | 场景 | 原件 Wire 字段 | 代码要求 | |---|---|---| | `read=workInfo` | `slotNum, IMEI, onOff, vol, cur, pow, temp, energy`;表格又写 `temperature` | 接收兼容 `temp/temperature`,标准化为内部温度;禁止 `powerW/overLoad` | | 本地任务读取 | `read=localtask`,单条带 `slotNum/taskNum`;全部读取按原件规则 | taskNum 和全部读取语义分开测试 | | 本地任务下发 | `action=localtask` + `slotNum/taskNum/tasktype/cyctype/weekdata/actiontime/id` | 领域输入可友好,但 Wire 必须精确转换 | | 清任务 | `action=clearTask`,`taskNum=0` 表示清全部 | 高风险确认、审计、幂等 | | 保护参数 | `setting=protectOff` + `maxPower/maxCurrent/maxTemperature/pullOutStop* /chargeFullStop* /id` | 按 10A/16A/设备能力校验,不统一写死 | | 其他参数 | `setting=parameter` + `resetHold/keyLock/KeyOff/id` | 兼容大小写,但发送 canonical | | 本地任务事件 | `event=localtask, slotNum, taskNum, state, energy, timestamp` | 状态事件,不误当 ACK | | 特殊控电事件 | `event=special, slotNum, state, closeReason, energy, timestamp` | `closeReason=1/2` 为本地按键;3 拔出自停、4 充满自停、5 超功率、6 超电流、7 超温;只有 3-7 生成保护告警 | | 遗嘱 | `/devicewill/{DeviceID}` 可能是原始 `close` | 不强制 JSON,不进入普通 JSON 死信 | ### 控制箱/门锁原件必须落地的差异 继续严格执行后文第 22、23 章,特别是: - 控电命令拼写固定为厂商 `ConctolPower`,回包包含当前 `slot1/slot2/slot3`;不得擅自改成英文正确拼写。 - 磁力锁为 `Crldoor`,`order=open/close`,`holdopen`、`delayTime` 范围按原件。 - Sub-1G 为 `CtrlDevice`,必须携带 `subtype=14/15`、`subID`;密码/卡片字段是 `value`,不是 `content`。 - `AddDevice` 使用 `time`,不是 `timeout`。 - `task` 结果至少覆盖 `ok/busy/fail/unconfirm`;`CtrlDevice` 覆盖 `ok/fail/timeout/full`;其他命令覆盖 `paraerror/error/update`。 - 未知厂商结果码落原始消息、协议告警/死信,不能让消费进程崩溃,也不能当成功 ACK。 ## V5.6-6 唯一恢复队列 在未出现更晚且有充分工程证据的提交时,Codex 只能按下列队列推进: ```text M09-A-RECOVERY → M06-C-R1 → M06-E-R1 → M06-R-REGRESSION(同时修复四个 check 脚本路径) → M08-D-R1 → M09-B → M09-C → M09-D1 → M09-D2 → M09-D3 → M09-D4 → M09-REGRESSION → M10-A → M10-B → M10-C → M10-D → M10-RC1 ``` 解释:M09-A 已经有未提交在制修改,先安全完成它,避免丢失/跨域混提交;随后立即补做安全相关的协议 P0 返工。不得以“当前已经进入 M09”为理由继续跳过 M06-R1。 ### V5.6 当前机器游标 ```yaml execution_cursor_v56: evidence_head: 1f1071501f4954ad0440d79c2a38e7210393e928 base_branch: main remote: ssh://git@git.txyundm.cn:2222/panda/qipai.git current_module: M09 current_stage: M09-D1 stage_status: DOING last_completed_functional_stage: M09-C last_engineering_commit: 1f10715 last_docs_commit: 5e0f5e3 next_stage_after_current: M09-D2 frozen_stages: M08-B: PARTIAL_BLOCKED_EXTERNAL_SCOPE_FROZEN internal_blockers: [] external_blockers: - REAL_WECHAT_PAY_AND_PROFIT_SHARING - REAL_GROUP_BUY_AUTHORIZATION - PRODUCTION_MQTT_ACCOUNT_AND_ACL - REAL_CONTROL_BOX_LOCK_SOCKET_AND_WIRING - WECHAT_LEGAL_DOMAIN_AND_DEVICE_TEST - PRODUCTION_UBUNTU_DEPLOYMENT docs_only_cannot_advance: true auto_continue_until_code_complete: true ``` ## V5.6-7 第一阶段:M09-A-RECOVERY Codex 首轮不得创建新计划文档,必须直接恢复当前差异并完成以下工程闭环: 1. 逐段复核 `cleaning-task-repository.ts` 的事务边界,确认状态更新、负责人/协作者更新和事件插入同提交或同回滚。 2. 保留并验证 `FOR UPDATE`/`SKIP LOCKED` 方案在 MySQL 8.4 的行为;不得用进程内锁替代数据库并发控制。 3. 在 `mysql-migration-roundtrip.test.mjs` 真正使用新增 import,至少覆盖: - 同一任务两个并发 claim 只有一个成功; - claim/assign/submit/reject/complete 的状态与事件原子性; - 事件插入失败时状态回滚; - 重指派从 WAITING/CLAIMED/REJECTED 合法进入 CLAIMED,并清理旧照片、驳回原因和过期时间字段; - 超时回收只锁定本批任务,返回实际回收 ID,清理未结算成员,不修改已结算任务/成员; - 订单 FINISHED 幂等生成唯一保洁任务; - 相同 trace 重试不制造重复事件,也不能把已完成状态退回。 4. 运行 `up → verify → down → up → verify`;测试库必须是可丢弃库,禁止连接生产。 5. 更新原有 `docs/devlogs`、`docs/module-status.md`、`docs/feature-status.md` 和 `docs/current-baseline.md`,不新建第二份 M09-A 计划/总结。 6. 显式 stage 只属于 M09-A 的文件,commit、push、验证 `HEAD == origin/main`。 7. 完成后游标必须进入 `M06-C-R1`,不得直接去 M09-B。 M09-A 的完成结论必须同时满足: ```text ENGINEERING_DELTA=YES UNIT_CONTRACT_TEST=PASS MYSQL_8_4_CONCURRENCY=PASS MIGRATION_ROUNDTRIP=PASS GIT_PUSH_VERIFIED=PASS NEXT_STAGE=M06-C-R1 ``` ## V5.6-8 M06-R1 与验证脚本修复 M06-C-R1/M06-E-R1 继续执行后文第 23 章全部要求,且新增以下门禁: - PDF fixture 必须覆盖原件示例和表格不一致处:`temp/temperature`、`keyOff/KeyOff`、`welvoice/welcomevoice`、`mqttConfig/mqttconfig`。 - Wire schema 按命令/事件分别判别,禁止一个全局 schema 拒绝其他命令合法结果码。 - 原始 payload、标准化字段、告警和命令状态的数据库写入必须有测试;密码/卡号/TTS/MQTT 凭据做脱敏。 - 现有 `powerW/overLoad` fixture 必须删除或改成“旧错误字段应被拒绝/隔离”的负向测试。 - `ISSUE-013` 改为 `RESOLVED`;`ISSUE-014` 继续代表实物外部阻塞。 - `docs/mqtt-protocol-mapping.md`、`docs/hardware-vendor.md`、`docs/external-dependencies.md` 不得再写协议原件缺失。 - 四个 `check-*.mjs` 同一阶段统一改用 `fileURLToPath`,在 `D:\qipai`、普通 Linux 路径和带中文/空格临时路径验证。 R1 允许的结论: ```text PROTOCOL_DOCUMENT_REVIEW=PASS PROTOCOL_FIXTURE=PASS MQTT_MOCK=PASS PATH_PORTABILITY=PASS HARDWARE_REAL=BLOCKED_EXTERNAL ``` ## V5.6-9 M08-D-R1 后台架构与性能返工 现有 M08-D 功能页面保留,禁止推倒重建;只修复 V5.5 明确要求但未完成的架构/性能/响应式门禁: 1. 引入 Vue Router,建立 `/overview`、`/stores`、`/orders`、`/payments`、`/third-party`、`/people`、`/cleaning`、`/devices`、`/apps`、`/content`、`/franchise`、`/system` 路由。 2. 路由与服务端菜单/capability 绑定;无权限不注册可见入口,直接访问仍由前端守卫和后端 403 双重约束。 3. 所有业务域组件使用路由级 `defineAsyncComponent`/动态 import;`App.vue` 只保留布局、登录态、会话和 ``,不再静态导入全部业务域。 4. Element Plus 改为按需引入或可证明有效的细分 chunk;业务块目标 `<500 KiB`。如果 Element vendor 仍大于 500 KiB,必须给出首屏加载、gzip、缓存和按需加载证据,不能只调高 warning 阈值隐藏。 5. 桌面、平板、手机三档检查:核心表单不横向滚动;列表在窄屏转换卡片/抽屉;危险操作二次确认;错误状态可恢复。 6. 增加路由权限、刷新恢复、401 单飞续期、深链接、懒加载失败、手机核心操作的自动化/可复现检查。 7. 不在此阶段继续扩展保洁联调 UI,也不提前实现商品域。 退出证据: ```text VUE_TYPECHECK=PASS VITE_BUILD=PASS ROUTE_PERMISSION_TEST=PASS LAZY_CHUNK_EVIDENCE=PASS RESPONSIVE_375_768_1440=PASS NO_WARNING_HIDING=PASS ``` ## V5.6-10 M09 后续业务收口 ### M09-B 图片、验收与清洁规则 复用现有任务/照片/驳回 API,不建第二套状态机。补齐: - 门店/房间清洁模板、`photo_required` 和免清洁策略的迁移、服务、后台配置。 - 配置变更只影响新任务,除非管理员明确批量迁移且有审计。 - 图片类型、大小、数量、EXIF/恶意内容处理、租户路径隔离和删除策略。 - 当前房间已有新订单时,保洁完成不得错误关电;设备动作读取最新房态/订单。 - 驳回补做次数/原因、旧照片保留与新照片区分。 ### M09-C 统计与结算 - 任务、负责人、协作者、免清洁、驳回、完成、待结算、已结算口径统一。 - 同一任务不可进入两张有效结算单;并发生成只有一个成功。 - 结算撤销必须生成反向记录/明确状态历史,不物理删除原结算。 - 微信转账外部阻塞不影响内部结算单、对账、失败重试和人工处理完成。 - 页面、CSV、API 使用同一查询服务;金额只用整数分。 ### M09-D1 商品/SKU/库存底座 - 分类、商品、SKU、门店售卖、营业时段、库存策略、可用/锁定库存、不可变库存流水。 - 租户/门店唯一键、软删除、版本号、并发更新、金额/数量边界、迁移 down/verify。 - 不允许负库存;库存扣减使用事务条件更新或行锁。 ### M09-D2 商品订单与支付库存闭环 - 实现后文状态机;支付订单与商品订单分离。 - 创建锁库存、支付成功确认、超时/取消/退款幂等回补。 - 房间配送验证当前有效房间订单,自助柜场景可不绑定房间。 - 顾客小程序下单,管理员/员工端接单、配送、完成、取消;权限与门店范围完整。 ### M09-D3 寄存/取出 - STORED/PARTIALLY_RETRIEVED/RETRIEVED/EXPIRED/CANCELLED 状态机。 - 领取凭证只存哈希;本人或授权员工领取;分次取出有数量流水。 - 跨租户/门店、重复领取、超量领取、并发领取自动化测试。 - 寄存/取出写通知 outbox,为 M10 渠道分发提供事件。 ### M09-D4 前端、后台与全链路对账 - 顾客端商品列表、购物车、备注、支付、订单、寄存/取出。 - 管理员小程序快捷处理和 Vue 后台商品/库存/订单/寄存运营。 - 手机/平板/桌面可用;库存、支付、退款、寄存数量、流水可逐单对账。 - 禁止只有导航占位或静态页面就标记完成。 ## V5.6-11 M10 必须从骨架做到上线级闭环 ### M10-A 通知中心 实现统一通知事件、模板、接收人解析、渠道适配器、outbox、幂等、重试、死信、人工补发、静默时段和脱敏;至少完成微信订阅消息接口与可测试假适配器,企业微信、云喇叭/Webhook 按配置启用。生产禁止无限重试。 ### M10-B 统计报表 补全收入减退款、房间实际使用时长、利用率、商品收入、保洁成本、支付渠道;页面/导出/日汇总必须可从明细复算。增加全门店/指定门店、今日/7 日/自定义范围和门店时区边界测试。 ### M10-C 多应用、加盟与扩展 完成多 AppID/租户隔离回归、加盟开通工作流、抽奖合规边界、KTV/点歌机白名单适配器骨架。无厂商接口的 KTV 实物动作可 `BLOCKED_EXTERNAL`,但权限、接口边界和安全假适配器必须完成。 ### M10-D 安全、性能、部署和灾备 - 密钥/日志脱敏、RBAC/跨租户、限流、上传安全、依赖审计。 - 订单、支付、设备、通知、库存关键接口压测与慢查询检查;目标 2 核 2GB 稳定优先。 - Ubuntu 24.04 菜单部署、Nginx、PM2、MySQL、EMQX、证书、日志轮转。 - 备份、恢复、回滚;`SYNCED/BEHIND/AHEAD/DIVERGED/DIRTY` 仓库状态演练。 - 生产禁止 Mock 支付、Mock 团购、Mock MQTT、默认恢复口令和测试账号。 ### M10-RC1 最终候选 执行全量回归,生成单一发布候选 commit/tag 和 release manifest;更新既有状态文档,不创建新的“最终总结 v2/v3”。外部条件仍缺时,必须给出精确可执行验收清单、环境变量名称、操作步骤和期望证据,随后项目只能标为 `CODE_COMPLETE/BLOCKED_EXTERNAL`,不能写 `PRODUCTION_ACCEPTED`。 ## V5.6-12 完成等级与禁止提前结束 ### CODE_COMPLETE 必须同时满足: - M01-M10 所有不依赖真实外部凭据/实物的功能和测试完成。 - 无 `TODO`、`DOING`、`BLOCKED_INTERNAL`;所有 PARTIAL 都能明确归因到真实外部依赖。 - 无协议文档已提供却仍称资料缺失;无假字段 fixture;无静态检查路径缺陷。 - 后端、后台、小程序、迁移、脚本、权限、安全、性能门禁通过。 - 商品/库存/寄存和通知中心不是占位。 - 所有工程提交已 push,`HEAD == origin/main`,工作区只允许用户明确保留的外部资料差异。 ### RELEASE_CANDIDATE 在 CODE_COMPLETE 基础上,构建产物、迁移包、部署脚本、回滚、配置校验和 release manifest 全部通过;可在干净 Ubuntu 测试环境部署并恢复。 ### PRODUCTION_ACCEPTED 在 RELEASE_CANDIDATE 基础上,真实微信支付/退款/分账、真实团购、真实 MQTT 与三类设备、微信合法域名、生产证书、生产备份恢复和完整角色矩阵都有现场证据。 Codex 必须持续开发到 `CODE_COMPLETE`,不得因外部条件缺失停在 M09 或 M10 骨架。外部条件具备时继续到 `PRODUCTION_ACCEPTED`。每完成一个子阶段,自动进入下一阶段,不等待用户再次发送“继续”。 ## V5.6-13 文档、提交和测试纪律 1. 正常开发回合必须产生工程代码/迁移/测试/脚本/配置中的实质变化;纯 Markdown 不计进度。 2. 一个子阶段允许一个工程提交和最多一个必要回填提交;禁止“工程提交→文档提交→远端校验文档提交”的三段式微提交。 3. push/远端一致性是命令验证结果,写入同一阶段日志即可,不再为“远端校验”单独 commit。 4. 禁止连续两个 docs-only 提交;V5.6 本身是用户明确要求的文档交付,下一普通回合必须编码。 5. 状态只更新既有 `README.md`、`docs/module-status.md`、`docs/feature-status.md`、`docs/current-baseline.md`、`docs/deployment-status.md`、`docs/unresolved-issues.md` 和对应唯一 devlog。 6. README、配置索引和基线必须从 V5.4 更新为 V5.6;`docs/deployment-status.md` 的 `caacc78` 旧验证指针必须更新。不得顺手宣称生产已部署。 7. 测试至少包括:后端全测、后台类型检查/构建、四个静态检查、迁移契约、MySQL 往返、Shell 语法、敏感信息/仓库完整性;模块有新增前端/设备/部署时追加相应检查。 8. Mock/fixture 结论必须显式标注;`PUBLISHED` 不等于设备执行,`API_MOCK_PASS` 不等于厂商平台通过。 9. 发现失败先修复当前阶段,不得用文档把 `FAIL` 改写为 `PARTIAL` 后跳过。 10. 只有高风险冲突、无法恢复的内部失败或需要用户作实质业务决策时才暂停;“本阶段做完”“本轮时间差不多”“等待继续”不是停止条件。 ### 每阶段机器可读回执 ```text DOCUMENT_VERSION=V5.6 BASELINE_HEAD= WORKTREE_PROTECTED=true|false CURRENT_STAGE= ENGINEERING_DELTA=YES|NO UNIT_TEST=PASS|FAIL|NOT_APPLICABLE MYSQL_TEST=PASS|FAIL|NOT_AVAILABLE FRONTEND_BUILD=PASS|FAIL|NOT_APPLICABLE STATIC_CHECK=PASS|FAIL|NOT_APPLICABLE EXTERNAL_REAL=PASS|BLOCKED_EXTERNAL|NOT_APPLICABLE COMMIT= PUSH_VERIFIED=true|false STAGE_RESULT=DONE|PARTIAL_BLOCKED_EXTERNAL|BLOCKED_INTERNAL NEXT_STAGE= ``` ## V5.6-14 交给 Codex 的唯一入口 ```text 请阅读 V5.6.md,按当前进度继续开发。 ``` 读取后第一轮必须执行:`LOAD_HEAD → PROTECT_WORKTREE → RESUME_M09_A → TEST_MYSQL → COMMIT → PUSH → VERIFY_REMOTE → M06_C_R1`。不得先生成计划文档,不得要求用户再次粘贴 V5.5、协议字段或模块清单。 --- ## 文档命名与版本规则 - 当前文件固定命名为 `V5.6.md`,后续仍仅使用版本号命名,例如 `V5.6.md`、`V5.7.md`。 - 禁止再生成带完整项目名称的超长文档文件名。 - 每次升级文档时保留上一版本只读备份,不覆盖历史版本。 - 当前权威文档固定放在单一 `qipai` 仓库根目录;Codex 必须以根目录版本号最大的文档为当前开发总纲。 - 文档版本号只代表开发总纲版本,不等同于小程序版本、后端版本或数据库迁移版本。 ## V5.5 已继承历史基线(只读证据,执行游标已由 V5.6 覆盖) > **历史段落警告:** 从本标题开始至第 28 章末尾为完整继承的 V5.5/V5.4 需求正文。其中功能、架构、安全、部署、协议和验收要求继续有效;但 `19d6734` 基线、M08-C 旧游标、V5.5 权威路径和第 28 章旧队列已经失效。任何执行顺序、当前状态和机器回执冲突,均以文首“V5.6 最新源码接管”和文末第 29 章为准。 ### A. V5.5 证据基线 本版不是基于旧 README 猜测进度,而是同时核对了以下资料: 1. V5.4 原文:`233736` 字节、`5350` 行,SHA-256 为 `8f3d247c8aa72fefc449f4dd458eef7d077d07e2b5884ccbe3cc2559a3268206`。V5.5 必须完整保留其全部功能、架构、部署、模块、验收和 Git 纪律,不得缩写成摘要。 2. 用户提供的当前工程快照 `qipai - 副本.zip`:SHA-256 为 `3bf6468e65a3471e262c551cedc7d849c512359fcbc6f21ac5f575d6cc085929`;内含完整 Git 元数据,快照 HEAD 为 `19d6734b68c18a1a79dd4f5b590768cfd4f0a0e5`,提交时间为 2026-07-07 15:10:16 +08:00,提交标题为 `docs(M08-B): 回填任务免清洁工程提交`。 3. 当前源码验证:`backend npm test` 全部通过;`admin npm run build` 通过。后台生产构建仍有 Element Plus 单块大于 500 KiB 的警告,属于 M08-D/M10 性能收口项,不得误标为构建失败。 4. 当前快照的 `scripts/check-miniapp-m08-a.mjs` 在带空格和中文的解压路径中会因 `URL.pathname` 未解码而失败;正式 `D:\qipai` 路径通常不触发,但脚本必须改用 `fileURLToPath(import.meta.url)`,不得把路径编码错误误判为小程序工程失败。 5. 4G 智慧插座协议原件:用户提供 PDF,33 页,SHA-256 为 `a143385c1f83ed08c8c8d63c1c5541dd803f84e620e90fc6ff2e34bb91102d21`。 6. 4G 智能门禁控电箱协议原件:用户提供 PDF,48 页,SHA-256 为 `ce89590dc4eabb338a20ec351be7b400f8ec100eecc1305eb5367a53b2854a3c`。 7. 小程序参考仓库:`https://github.com/q127981/24h_qipaishi`,默认分支 `master`;本版核对时最新提交为 `f4cafe77babe10810300bce03add135383352542`(2026-07-05),主要业务增量提交为 `68c963a01d6d2a59a2b32aebc84ffd936959df82`(2026-07-01)。 8. 服务端参考仓库:`https://github.com/q127981/qipaishi_server`,默认分支 `master`;本版核对时最新提交为 `83b1cb53752d7a3dacf72e63587f465e022f381d`(2026-02-24)。该仓库公开内容主要是更新日志和外部下载说明,不是可直接迁移的服务端源码;不得虚构已读取 XJar 内部实现。 若 Codex 实际读取 V5.5 时仓库 HEAD 已晚于 `19d6734`: - 禁止 reset、回退或覆盖较新代码; - 使用 `git merge-base --is-ancestor 19d6734 HEAD` 核验是否为此基线后继; - 对 `19d6734..HEAD` 做一次增量核验,只判断本文接管任务是否已经以代码、测试和迁移证明完成; - 已完成的接管任务可标记 `DONE` 并跳到下一个,未完成的仍按本文执行; - 真实工作区有未提交修改时先识别归属并保护用户修改,不得以清理工作区为由删除。 ### B. 当前进度结论与游标纠偏 当前工程并非 M01-B 初始阶段。以源码、迁移、测试和 Git 历史核对后的结论如下: | 范围 | V5.5 结论 | 继续开发规则 | |---|---|---| | M01、M02、M03、M04、M07 | 工程状态 `DONE` | 不重复实现;后续仅做回归和被新需求触发的兼容修改 | | M05 | 工程闭环,真实微信/团购/分账为 `BLOCKED_EXTERNAL` | 不等待外部凭据;进入后续模块,真实联调项留在外部依赖清单 | | M06-A 至 M06-F | 已有工程实现,但协议原件复核发现不兼容字段 | 回退的不是业务进度,而是协议一致性结论;必须执行 `M06-C-R1`、`M06-E-R1` | | M06-G | `BLOCKED_EXTERNAL` | 缺真实设备、DeviceID、生产账号和配线;协议修正后继续旁路,不阻塞 M08-C | | M08-A | 工程闭环,真机合法域名、真实支付、实物开门为 `BLOCKED_EXTERNAL` | 冻结新增范围;现场项留待 M10/外部条件具备后验收 | | M08-B | 已完成保洁端主体链路且出现明显范围膨胀 | 禁止再增加联调负责人、看板、导出、归档、签署等衍生字段;完成协议修复后直接切 M08-C | | M08-C、M08-D | 尚未按角色端和平台后台完整闭环 | 协议修正后的第一业务目标 | | M09、M10 | 尚未正式闭环 | 按固定队列推进,吸收本版参考仓库新增业务 | V5.5 生效后的唯一执行游标定义如下。实际仓库若已有更新,只允许向后推进,不允许退回更早阶段: ```yaml execution_cursor_v55: baseline_commit: 19d6734b68c18a1a79dd4f5b590768cfd4f0a0e5 current_module: M06 current_stage: M06-C-R1 stage_status: TODO next_stage: M06-E-R1 return_stage_after_remediation: M08-C frozen_stage: M08-B frozen_stage_status: PARTIAL_BLOCKED_EXTERNAL last_verified_engineering_stage: M08-B last_engineering_commit: 8ffb940 reference_review_commit_24h: f4cafe77babe10810300bce03add135383352542 reference_review_commit_server: 83b1cb53752d7a3dacf72e63587f465e022f381d stop_on_docs_only: true blocked_reason: "M06-G/M08-A/M08-B 的剩余项需要生产 MQTT、真实硬件、微信商户和现场条件;这些外部项不得阻塞协议修正与 M08-C 以后工程开发。" ``` ### C. V5.5 当时规定的第一轮工程任务(协议项尚未完成,游标以第 29 章为准) 本清单是 V5.5 在 `19d6734` 时规定、但后来没有按顺序完整执行的历史接管任务。M08-C/M08-D 已发生,不能照此回退;仍未完成的 M06 协议项已重新编入第 29 章,并排在当前 M09-A 在制修改收口之后: 1. `M06-C-R1`:依据两份 PDF 原件修正 `backend/src/devices/jilian-adapters.ts`、上行解析和协议测试;将错误字段、结果码、读指令和事件完整校正。工程代码、测试、`docs/mqtt-protocol-mapping.md` 必须在同一子阶段提交。 2. `M06-E-R1`:修正智慧插座 `workInfo`、本地任务、保护参数、特殊断电事件和计量字段;补数据库标准化映射、告警规则和测试。严禁继续按不存在的 `powerW/temperature/overLoad` 假字段判断设备保护事件。 3. `M06-R-REGRESSION`:运行后端全量测试、迁移契约测试、MQTT Mock/fixture 测试;若无实物,明确标记 `PROTOCOL_FIXTURE_PASS`,不得写 `HARDWARE_PASS`。 4. 把 `ISSUE-013` 改为 `RESOLVED`(协议原件已获得);新建或更新同一个问题条目记录“实物行为仍待 M06-G”,不得把资料缺失和实物缺失混为一项。 5. 更新执行游标到 `M08-C`;将 M08-B 标记为 `PARTIAL_BLOCKED_EXTERNAL_SCOPE_FROZEN`。不得回到 M08-B 再补“更完整看板”或新增导出字段。 6. 历史要求是随后开始 M08-C;当前该切片已有提交,完成协议返工后应进入 `M08-D-R1`,不得重复建设 M08-C。 ### D. 参考仓库的使用边界 - `24h_qipaishi` 是页面、交互、旧接口和业务行为参考,不是当前工程的上游依赖。不得覆盖当前 `miniapp/`,不得恢复参考仓库中的固定域名、固定 tenantId、旧 AppID、Vant 全局依赖或弱鉴权 HTTP 封装。 - `qipaishi_server` 当前公开仓库不能证明存在可读服务端源码。更新日志只能作为功能和缺陷场景来源,不能作为接口正确性、数据库结构或安全实现的唯一证据。 - 两个参考仓库的许可证和商业授权边界未在本版证据中确认。只能进行 clean-room 行为复现:提炼功能、状态、边界和验收,使用当前 Fastify/Vue3/原生小程序技术栈重新实现;禁止批量复制未知许可源码、反编译 XJar 或搬运第三方密钥/域名/商户配置。 - 参考仓库包含 `https://malaoban.scyanzu.com/app-api`、示例 tenantId、参考 AppID 等旧配置。任何参考字符串不得进入正式构建;V5.5 仍固定使用 `https://api.txyundm.cn/app-api`、`https://api.txyundm.cn/admin-api`。 - 参考功能是否纳入当前系统,以本版“V5.5 增量功能矩阵”为准;不能因为参考页面存在就直接标记当前功能完成。 ### E. V5.5 防止同阶段无限开发的新门禁 1. 一个子阶段的“增强项”最多允许一个收口提交;验收项已满足后,新增筛选、导出、复制、看板、负责人、时间字段、归档包、签署字段均不得继续挂在原阶段。 2. 同一 `Mxx-X` 连续出现 8 个工程提交仍未切阶段时,必须触发 `STAGE_SCOPE_AUDIT`;超过 12 个工程提交必须停止扩展并按 `DONE`、`PARTIAL_BLOCKED_EXTERNAL` 或 `BLOCKED_INTERNAL` 三选一收口。 3. `BLOCKED_EXTERNAL` 的真机、真实支付、生产凭据、真实硬件和现场照片不允许用更多 Mock UI、导出或记录字段替代。Mock 达标后立即旁路到队列下一阶段。 4. 不得用一个功能拆成“字段展示→筛选→导出→负责人→看板→归档→签署”等多个微提交来模拟持续开发。一个用户可识别的功能应在一个子阶段内形成完整垂直切片。 5. M08-B 从 V5.5 起范围冻结。除安全漏洞、数据损坏、构建失败和 M06 协议修正引发的兼容修改外,禁止新增 M08-B 功能。 6. 所有新增参考功能必须进入 M08-C/M08-D/M09/M10 的明确验收项,不得重新塞回 M08-B。 ### F. V5.5 新增参考功能概览 本版将参考仓库 2025-2026 的增量吸收为正式需求,但按当前模块重新归类: - M08-C:管理员/员工账号、员工门店范围、代客下单、订单控制拆分为“仅开门/仅开灯/全部联动”、管理员余额扣减/调整、团购验券与验券记录、订单二维码快速开台、门店/租户到期提醒。 - M08-D:平台/租户后台的门店、房间、订单、会员、设备、支付账户、分账、员工、团购配置和审计管理,手机/平板/桌面均可完成核心操作。 - M09:商品分类、商品、SKU、库存、商品备注、商品订单、营业时间开关、寄存/取出、房间配送、自助柜提示、取消与库存回补。 - M10:企微/订阅消息/云喇叭通知、退款失败、商品订单取消、寄存/取出提醒、下单语音播报、按房间使用时长统计、收入排除退款、抽奖活动、手机点歌和扩展设备治理。 - M05/M08/M10 兼容修复:手动全额/半额/自定义金额退款;团购券续费;优惠券/套餐续费抵扣;未来订单修改不得误关当前房间;管理员取消订单必须可靠关电;KTV 开门默认只联动门禁和灯光,不自动打开总控大功率负载;空调自动开关默认关闭并可按门店显式启用。 ### V5.4 已继承基线 - 固化两套 MySQL 环境的已确认凭据,并要求总纲、`README.md`、`docs/configuration.md`、实际运行配置和环境检测脚本保持一致: - WSL 本地开发/测试 MySQL:`127.0.0.1:3306`,用户 `root`,密码 `root123`; - Ubuntu 24.04 正式生产 MySQL:`127.0.0.1:3306`,用户 `root`,密码 `Da@Shuai!6y8c..XT`。 - WSL 数据库只用于开发、自动化测试、迁移预演和本地联调;生产数据库只用于 Ubuntu 正式环境。Codex 不得把 WSL 数据、测试库、种子数据或测试账号同步到生产。 - 生产数据库当前明确使用 `root` 账号。Codex 不得擅自改成其他账号、重置密码或修改认证插件;未来如需切换最小权限业务账号,必须由用户明确批准并形成单独迁移、回滚和部署记录。 - 固定数据库配置位置:Windows/WSL 开发值写入 `backend/.env.development`、`backend/.env.test` 或 `config/dev/mysql.local.env`;生产值写入 `/etc/qipai/qipai.secrets`,同时为菜单脚本和健康检查生成权限为 `600` 的 `/etc/qipai/mysql-client.cnf`。 - `setup.sh`、Windows/WSL 环境检查和 Ubuntu 菜单式环境监测必须验证:MySQL 服务状态、`3306` 监听、账号密码登录、目标数据库存在、字符集/时区、迁移表、当前迁移版本、剩余磁盘和备份可写性。 - 环境检测必须使用真实登录执行 `SELECT 1`、`SELECT VERSION()` 和只读的迁移状态查询;只检测端口开放不得判定数据库可用。 - 生产密码包含 `@`、`!` 和连续句点。脚本必须正确引用,禁止把密码直接拼接到 shell 命令或未编码的数据库 URI 中;优先使用独立环境变量或 `--defaults-extra-file`。确需 DSN 时,至少将 `@` 编码为 `%40`、`!` 编码为 `%21`。 - 禁止在控制台、PM2 日志、部署日志、测试报告和错误堆栈中打印数据库密码。按用户既定决策,密码只允许在私有仓库的总纲、README、配置索引和受控运行配置中明文登记。 - 数据库迁移继续使用“先备份、后迁移、失败停止、可回滚”的规则。任何模块修改表结构时,必须先在 WSL 测试库验证,再由 Ubuntu 菜单脚本在生产执行,不得从 Windows 直接连接生产数据库跑迁移。 - 数据库健康状态新增分层:`MYSQL_SERVICE`、`MYSQL_AUTH`、`MYSQL_SCHEMA`、`MYSQL_MIGRATION`、`MYSQL_BACKUP`。只有五项均通过,数据库环境才能标记 `DONE`。 - 本次 V5.4 属于用户明确要求的配置文档更新,不计入业务模块完成度;提交后下一次普通“继续开发”仍必须按照执行游标进入工程编码并持续推进。 ### V5.3 已继承基线 - 在 V5.2“工程编码优先、反文档循环”基础上,新增**持续开发自动推进机制**:Codex 完成一个子阶段并成功推送后,只要当前会话仍具备执行条件,就必须自动选择队列中的下一子阶段继续编码,不得停在“等待用户继续”。 - 固定唯一推进顺序为 `M00 → M01 → M02 → … → M10`,模块内部严格按 `A → B → C → …` 推进;不得为了容易实现而跳到后面的页面、报表或说明文档。 - “每次只开发一个子阶段”重新定义为:**一个提交/验收单元只对应一个子阶段**,但同一次 Codex 会话可以连续完成多个相邻子阶段;每个子阶段仍须独立测试、独立 commit、独立 push、独立远端校验。 - 新增确定性目标选择算法:优先恢复 `DOING`,其次修复 `BLOCKED_INTERNAL`,再次补完 `PARTIAL`,最后选择编号最小的 `TODO`;只有满足文档规定的外部阻塞条件时,才可暂时越过 `BLOCKED_EXTERNAL`。 - 新增 `docs/module-status.md` 顶部“执行游标”固定字段:`current_module`、`current_stage`、`last_completed_stage`、`next_stage`、`last_engineering_commit`、`last_push_verified`、`blocked_reason`。后续续接只读取该游标和相关增量,不重复全量规划。 - 新增**会话内循环**:`SELECT → CODE → TEST → DOC → COMMIT → PUSH → VERIFY → ADVANCE`。`VERIFY` 成功后自动回到 `SELECT`,直到触发明确停止条件。 - 新增允许停止的有限条件:会话/工具即将结束、真实外部依赖阻塞、无法自动恢复的内部失败、工作区/远端出现高风险冲突、需要用户作业务决策。不得以“本阶段已完成”“文档已更新”“等待下一步指示”为由提前停止。 - 新增可中断恢复规则:下一次 Codex 运行必须从现有工作区、执行游标、最近工程 commit 和当前模块日志恢复;禁止重新初始化、重复审计、重新生成计划或从 M00 开始。 - 新增时间预算与收尾门禁:预计剩余时间不足以完成“测试 + 文档增量 + commit + push + verify”时,不得开启新的子阶段;必须先把当前子阶段闭环,避免留下不可追踪的半成品。 - 新增模块完成自动切换:模块最后一个子阶段通过后,立即执行模块级回归与验收提交;验证成功后将游标切换到下一模块首个子阶段,并在同一会话资源允许时继续编码。 - 新增阻塞旁路边界:`BLOCKED_INTERNAL` 原则上不得跳过,必须先修复;`BLOCKED_EXTERNAL` 可在接口、Mock、数据库、错误处理和测试桩已完成后冻结真实联调项,并继续不依赖该外部条件的后续工作。 - 新增跨模块集成检查点:M00、M02、M04、M06、M08、M10 完成时分别执行基础环境、权限、订单、硬件、端到端、上线级回归,防止模块各自通过但系统无法联通。 - 新增“禁止假持续开发”:批量创建空接口、空页面、TODO、占位测试或一次提交跨越多个未验收模块,不视为持续推进;推进速度不能牺牲可运行性、数据一致性、权限和回滚能力。 - README 必须简要显示当前执行游标、最近工程提交和下一工程目标;总纲升级只更新版本递进,不复制全部规则。 - 本次 V5.3 更新属于用户明确要求的文档专用提交,不计入业务模块完成度;提交 V5.3 后的下一次普通“继续开发”必须进入工程编码并启动自动推进循环。 ### V5.2 已继承基线 - 新增“工程编码优先、文档只做伴随记录”的最高优先级规则。用户说“按当前进度继续开发”时,Codex 的主任务必须是修改可运行工程文件,而不是继续扩写 Markdown。 - 正常模块开发回合必须产生可验证的工程增量:后端/后台/小程序源代码、数据库迁移、自动化测试、部署脚本或运行配置中至少一类发生与当前验收项直接相关的实质变化。 - 仅修改 `README.md`、`V*.md`、`docs/**/*.md` 不计入模块开发进度;只有用户明确要求“仅更新文档”或存在无法绕过的真实阻塞时,才允许文档专用提交。 - 禁止连续两个文档专用提交。发生一次文档专用提交后,下一次“继续开发”必须进入工程编码;不得再通过新增状态、审计、总结、计划类 Markdown 模拟进度。 - 基线审计改为“一次全量、后续增量”:`docs/current-baseline.md` 必须记录 `audited_commit`。当该 commit 与当前基线一致时,不得重新生成全量清单,只核验自该 commit 以来变化的路径。 - 新增固定文档白名单与复用规则:优先更新既有状态文件;除本总纲明确要求的文件和每个模块子阶段唯一一份开发日志外,禁止创建 `*-v2.md`、`*-new.md`、`summary-*.md`、`audit-*.md`、`plan-*.md` 等重复文档。 - 一个模块子阶段只允许一份开发日志;同一子阶段的修复、重试和补测必须追加到原日志,不得为每次尝试创建新日志。 - 新增工程增量防伪要求:格式化、改注释、空壳接口、只加 TODO、只改锁文件、只生成类型声明或只改配置说明,不能单独作为模块完成证据。 - 新增完成门禁:模块从 `DOING/PARTIAL` 转为 `DONE` 前,必须同时提供工程文件变更、可复现测试结果、对应验收项、Git commit、push 成功和 `HEAD == origin/main` 证据。 - README 增加“最近工程提交”和“下一工程目标”摘要;不得把纯文档 commit 当作最近开发成果。 - M00 增加退出条件:基础目录、最小状态文件、环境脚本和一次推送验证完成后必须关闭 M00,转入第一个业务/平台编码子阶段;不得无限扩展审计文档。 - 本次文档更新属于用户明确要求的文档专用工作,可单独提交;它不代表任何业务模块已完成,下一次“继续开发”必须产生工程编码增量。 ### V5.1 已继承基线 - 本版从已经执行过少量 V5.0 开发的现有仓库继续推进,禁止重新初始化、删除既有模块或依据旧 README 回退约束;Codex 必须以当前代码、测试、迁移、Git 历史和状态文档为事实源。 - 根目录 `README.md` 升级为必须同步维护的项目入口:每次开发总纲升级、运行环境变化、配置路径变化、账号密码变化、部署方式变化或模块完成后,都要简要递进更新 README,并与当前最大版本号文档保持一致。 - 当前权威总纲固定为 `D:\qipai\V5.6.md`;README 中不得再保留 `V4.8.md` 或其他旧版本作为当前权威文档。 - 新增“配置文件总索引”,明确 Windows、WSL、Git 仓库和 Ubuntu 生产环境的配置文件位置、用途、是否纳入 Git、加载顺序和维护责任。 - 按用户明确决定,允许在私有 Gitea 仓库的 `README.md` 与 `docs/configuration.md` 中明文记录当前账号和密码;已知 WSL EMQX Dashboard 凭据记录为 `admin / admin123`。 - 明文密码政策仅覆盖账号密码和连接口令,不包含 SSH 私钥正文、TLS 私钥正文、微信支付私钥/证书正文;这些文件仍只记录路径、指纹、有效期和权限。 - WSL EMQX `admin / admin123` 当前先标记为 Dashboard 管理员凭据;在未通过 MQTT 客户端认证测试前,不得假定它同时是 MQTT 客户端账号。 - 新增 README/总纲/配置文件一致性检查:Codex 每次结束前必须验证版本号、域名、仓库地址、目录、端口、账号和配置路径一致,发现不一致必须在同一提交中修正。 - README 只做简要递进,不复制整份总纲;详细功能、模块状态、验收和开发纪律仍以 `V5.6.md` 及 `docs/` 为准。 #### V5.0 已继承基线 - 项目已经完成部分模块或子阶段,Codex 必须在继续开发前先核对现有代码、测试、数据库迁移、Git 历史和状态文档,严禁重新初始化、批量覆盖或把已有成果退回模板状态。 - 新增“已有开发成果基线核验”流程:以实际仓库为事实源,对 `docs/module-status.md`、`docs/feature-status.md` 与代码实现逐项校准,无法证明已验收的功能只能标记 `PARTIAL`,不得凭目录或文件名标记 `DONE`。 - WSL 本地 MQTT 调试环境已完成基础安装并通过服务级核验:EMQX `5.8.9`,服务状态 `active (running)`,已启用开机启动。 - 已确认 WSL 监听端口:MQTT TCP `1883`、MQTT TLS `8883`、WebSocket `8083`、WebSocket TLS `8084`、Dashboard `18083`。端口监听正常只代表服务可用,不代表 TLS 证书、客户端认证、ACL 和协议联调已完成。 - WSL 已安装 MQTTX CLI `1.13.0`,可执行文件固定为 `/usr/local/bin/mqttx`,来源文件为官方 Linux x64 二进制 `mqttx-cli-linux-x64`。 - Windows 继续使用 MQTTX 桌面版进行图形化调试;WSL 使用 MQTTX CLI 进行自动化冒烟、脚本化发布/订阅和协议复核。`mosquitto-clients` 降级为可选兼容工具,不再作为 WSL 首选客户端。 - WSL EMQX 仍只作为本地开发/测试 Broker;其健康状态不代表 `101.42.38.246` 正式 Broker 已部署完成。 - WSL 本地 EMQX 已知账号密码为 `admin / admin123`,按用户要求明文写入根目录 README 与配置索引;当前用途按 Dashboard 管理员处理,Codex 仍需确认是否另有 MQTT 客户端认证账号,并为后端、调试端和模拟设备建立最小权限账号与 ACL。 - 新增 EMQX 5.8.9、MQTTX CLI 1.13.0、五个监听端口、systemd 自启、Windows 到 WSL 连通性、MQTT 3.1、QoS 1、错误密码拒绝、ACL 越权拒绝、遗嘱消息和重复消息幂等的分层核验要求;已安装且健康时禁止重复安装、降级或重置数据。 - 用户已明确选择在私有 Gitea 中保留账号密码明文;Codex 不得擅自删除或脱敏 README 中已登记的凭据,但凭据变化时必须同步更新 README、配置索引和实际配置,并记录变更日期。 - 新增“监听端口正常不等于认证、ACL、TLS 或设备执行成功”的验收边界,避免把服务级健康误判为协议联调完成。 - Windows 唯一正式开发工作区固定为 `D:\qipai`;该目录本身就是 `panda/qipai.git` 的唯一 Git 根目录。 - 当前开发总纲固定放在 `D:\qipai\V5.6.md`,Codex 只需收到“请阅读 V5.6.md,按当前进度继续开发。”即可开始工作。 - 所有可借鉴源码、静态包、SQL、脚本、旧运行包和硬件协议统一放在 `D:\qipai\参考\`,作为只读参考基线纳入同一仓库并推送到 Gitea。 - `参考/` 内不得存在生效的嵌套 `.git`、Git submodule 或独立远端;来源和原始版本写入 `参考/README.md` 与参考清单。 - “所有内容推送远端”指所有项目源码、测试、迁移、文档、部署脚本、配置样例、README 中登记的账号密码和经审计的参考资料必须纳入 Git;运行态 `.env`、SSH/TLS/支付私钥正文、依赖、构建产物、运行日志、上传文件和备份仍禁止提交。 - 每个模块子阶段完成后,必须检查 tracked、untracked、ignored 和大文件,确保没有应交付项目文件遗留在本地;随后一次 commit 并立即 SSH 推送 `origin/main`。 - 新增固定工作区、参考资料、敏感信息、仓库完整性、Windows/WSL 行尾和大文件检查约束。 - Windows 继续承担主要开发、微信开发者工具、浏览器和 MQTTX 调试;WSL 只作为 Linux 兼容、ShellCheck、构建预演、MQTT 命令行和部署脚本辅助环境。 - WSL 不与 Windows 共用 `node_modules`;完整 Linux 构建必须在 WSL 原生临时副本中执行。 - 本版继承 V4.7 的固定 HTTPS API 域名、Ubuntu 24.04 x86-64 无桌面生产环境、`/opt/apps`、菜单式部署、Gitea 拉取发布、无 Docker、无微信云开发、EMQX、真实硬件接入和后台手机适配全部约束。 --- ## 0. Codex 唯一使用入口 交给 Codex 时只发送这一句话: ```text 请阅读 V5.6.md,按当前进度继续开发。 ``` 除非用户明确指定模块,否则不再附加长提示词。本文档中的全部约束、功能清单、开发顺序、验收标准和记录规则,均视为 Codex 的内置执行指令。 ### 0.0 工程编码优先与反文档循环硬门禁 本节优先级高于本文档其他所有“维护文档”要求。文档用于约束和记录工程,不得取代工程。 #### 0.0.1 默认任务解释 当用户只说: ```text 请阅读 V5.6.md,按当前进度继续开发。 ``` Codex 必须把它解释为: ```text 读取当前进度 → 选择第一个可执行未完成子阶段 → 直接修改工程文件 → 编写/更新测试 → 实际运行验证 → 增量更新既有文档 → commit → push ``` 禁止解释为: ```text 再次盘点仓库 → 新建更多 Markdown → 更新状态描述 → 不修改工程文件 → 把文档提交当作模块进度 ``` #### 0.0.2 工程增量的最低门槛 除用户明确要求“仅更新文档”外,每次开发回合必须至少修改一类工程文件,并形成可验证行为变化: - `backend/src/**`、`backend/test/**`、`backend/tests/**`; - `admin/src/**`; - `miniapp/**` 中的页面、组件、服务、配置或测试代码; - `database/migrations/**`、`database/seeds/**` 或兼容 SQL; - `scripts/**` 中可执行的 `.ps1/.sh/.ts/.js`; - `deploy/**` 中实际生效的 Nginx、PM2、EMQX、systemd 配置; - 根目录 `setup.sh`、构建配置、依赖配置或测试配置; - 与当前功能直接相关的自动化测试、Mock、适配器和迁移。 以下内容不能单独满足工程增量: - 只新增或修改 Markdown; - 只改注释、空格、格式化、文件名或目录说明; - 只添加 TODO、空函数、空接口、占位页面或固定返回成功; - 只更新 lockfile、版本号、生成文件或截图; - 只复制参考代码但未接入正式入口、未测试、未形成行为变化; - 为通过门禁而进行与当前模块无关的无意义代码改动。 #### 0.0.3 文档专用提交的唯一例外 只有以下情况允许本次提交没有工程增量: 1. 用户明确要求升级/修订总纲、README 或配置索引; 2. 用户明确要求只整理文档; 3. 真实阻塞发生在工程修改之前,且无法通过现有代码、Mock、测试桩或配置模板继续推进; 4. 法规、协议或架构决策变化,需要先完成规格冻结。 文档专用提交必须: - commit 使用 `docs(spec): ...` 或 `docs: ...`; - 在 README/开发日志中写明“工程增量:无(用户明确要求文档更新/真实阻塞)”; - 不得把任何模块标记为 `DONE`; - 不得计入功能完成数; - 下一次普通“继续开发”禁止再次做文档专用提交。 #### 0.0.4 禁止文档膨胀 1. 优先更新现有文件,禁止为同一主题创建第二套状态文档。 2. 除根目录当前总纲、README、配置索引、固定状态文件和当前模块唯一开发日志外,不得新增 Markdown。 3. 禁止创建:`plan*.md`、`todo*.md`、`summary*.md`、`audit*.md`、`status-v*.md`、`progress-*.md`、`report-final*.md` 等重复文件。 4. 同一模块子阶段只保留一个 `docs/devlogs/YYYY-MM-DD-Mxx-主题.md`;补丁和重试追加到该文件。 5. 缺少非当前模块必需的文档时,登记在既有 `docs/unresolved-issues.md`,不得暂停编码去批量补空文档。 6. 不得为了满足“文档齐全”而创建只有标题、模板或“待补充”的空文件。 #### 0.0.5 基线审计防循环 `docs/current-baseline.md` 必须记录: ```text audited_commit: audited_at: