From b71b48b3d09a3d4062e8b4951136ee43c2e11379 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 10 Aug 2026 14:58:50 +0800 Subject: [PATCH] =?UTF-8?q?docs(M09-A):=20=E5=9B=9E=E5=A1=AB=E4=BA=8B?= =?UTF-8?q?=E5=8A=A1=E6=94=B6=E5=8F=A3=E4=B8=8EV5.6=E6=B8=B8=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 +- V5.6.md | 6738 +++++++++++++++++ docs/configuration.md | 9 +- docs/current-baseline.md | 18 +- .../db-changelog/2026-06-25-M08-B-cleaning.md | 7 + docs/devlogs/2026-06-25-M08-B-保洁端.md | 12 + docs/feature-status.md | 2 + docs/module-status.md | 16 +- scripts/dev/windows/check-readme-config.ps1 | 10 +- 9 files changed, 6795 insertions(+), 34 deletions(-) create mode 100644 V5.6.md diff --git a/README.md b/README.md index be55898..12e5bad 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # 自助棋牌室系统 -本仓库是 `panda/qipai.git` 的单一 Monorepo 工作区。Windows 固定开发路径为 `D:\qipai`,当前权威开发总纲为 [`V5.4.md`](./V5.4.md)。详细功能、模块顺序、验收标准和 Codex 纪律以总纲及 `docs/` 为准。 +本仓库是 `panda/qipai.git` 的单一 Monorepo 工作区。Windows 固定开发路径为 `D:\qipai`,当前权威开发总纲为 [`V5.6.md`](./V5.6.md)。详细功能、模块顺序、验收标准和 Codex 纪律以总纲及 `docs/` 为准。 ## 固定约束 -- 当前权威总纲:`V5.4.md` +- 当前权威总纲:`V5.6.md` - 固定远端:`ssh://git@git.txyundm.cn:2222/panda/qipai.git` - 默认分支:`main` - 生产 API:`https://api.txyundm.cn` @@ -35,7 +35,7 @@ | 用途 | 位置 | |---|---| | 项目入口 | `D:\qipai\README.md` | -| 当前总纲 | `D:\qipai\V5.4.md` | +| 当前总纲 | `D:\qipai\V5.6.md` | | 完整配置索引 | `D:\qipai\docs\configuration.md` | | 仓库目录映射 | `D:\qipai\docs\repository-map.md` | | 后端开发配置 | `D:\qipai\backend\.env.development` | @@ -113,16 +113,16 @@ WSL 已验证:EMQX `5.8.9`、MQTTX CLI `1.13.0`、EMQX 服务 `active (running - 一个 commit 只完成一个子阶段;同一次 Codex 会话可连续完成多个相邻子阶段。 - 每个子阶段必须完成工程编码、真实测试、增量文档、commit、push,并验证 `HEAD == origin/main`。 - 完成一个子阶段后,在会话资源允许时自动继续下一子阶段,不询问“是否继续”。 -- 纯 Markdown 变更不计业务进度;V5.4 文档提交后的下一次普通开发必须产生工程增量。 +- 纯 Markdown 变更不计业务进度;V5.6 文档提交后的下一次普通开发必须产生工程增量。 - 当前游标、最近工程提交和下一工程目标以 `docs/module-status.md`、`docs/current-baseline.md` 为准,不在 README 中猜测。 ## 当前进度 项目已开发部分模块。具体完成度不得从 README 猜测,必须以现有代码、测试、数据库迁移、Git 历史以及 `docs/current-baseline.md`、`docs/module-status.md`、`docs/feature-status.md` 为准。 -- 当前执行游标:`M09-A`(DOING);`M08-D` 可独立工程内容已完成,真实团购商家授权、微信和硬件现场验收保持 `BLOCKED_EXTERNAL`。 -- 最近工程提交:`0511008` / `M08-D后台登录与可撤销会话`,Vue 后台已使用正式密码登录、轮换刷新令牌、当前会话、401 自动续期/清理和服务端权限菜单。 -- 下一工程目标:进入 M09-A,复核并补齐保洁任务状态机、订单结束自动建任务、事务抢单、管理员指派和超时回收。 +- 当前执行游标:`M06-C-R1`(DOING);`M09-A-RECOVERY` 已完成,真实团购商家授权、微信和硬件现场验收保持 `BLOCKED_EXTERNAL`。 +- 最近工程提交:`9b2f055` / `M09-A保洁任务事务与并发收口`,真实 MySQL 8.4.10 已验证并发 claim 单赢家、事件失败回滚、重指派清理、`SKIP LOCKED` 批量回收和订单唯一建任务。 +- 下一工程目标:按 V5.6 固定队列执行 M06-C-R1,依据智慧插座协议原件修正 wire schema、fixture、标准化字段和消息落库。 ## 版本递进 @@ -130,11 +130,12 @@ WSL 已验证:EMQX `5.8.9`、MQTTX CLI `1.13.0`、EMQX 服务 `active (running - **V5.2**:增加工程编码优先、反文档循环、增量审计和工程完成证据。 - **V5.3**:增加固定模块队列、执行游标、会话内自动推进、可中断恢复和跨模块回归检查点。 - **V5.4**:固化 WSL/生产 MySQL 账号密码、配置位置、真实登录检测和特殊字符处理规则。 +- **V5.6**:接管最新源码与在制 M09-A,固化协议返工、后台架构返工、M09/M10 收口队列和 `CODE_COMPLETE` 门禁。 ## Codex 入口 ```text -请阅读 V5.4.md,按当前进度继续开发。 +请阅读 V5.6.md,按当前进度继续开发。 ``` diff --git a/V5.6.md b/V5.6.md new file mode 100644 index 0000000..8ca77ed --- /dev/null +++ b/V5.6.md @@ -0,0 +1,6738 @@ +# 自助棋牌室系统开发总纲(V5.6) + + +> 文档版本:V5.6(最新源码接管 + 漏项纠偏 + M09/M10 连续收口 + 全量测试版) +> 更新日期:2026-08-10(Asia/Shanghai) +> 当前工程证据基线:`b35af9037f256657f38f922e7b8a9bed9eb9aee9` +> 当前执行起点:保护并完成工作区中的 `M09-A` 在制事务化修改;随后补做被跳过的 `M06-C-R1 → M06-E-R1 → M06-R-REGRESSION`,再完成 `M08-D-R1 → M09-B/C/D → 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: b35af9037f256657f38f922e7b8a9bed9eb9aee9 + base_branch: main + remote: ssh://git@git.txyundm.cn:2222/panda/qipai.git + current_module: M09 + current_stage: M09-A-RECOVERY + stage_status: DOING_UNCOMMITTED + last_completed_functional_stage: M08-D-FUNCTIONAL + last_engineering_commit: 0511008 + last_docs_commit: b35af90 + next_stage_after_current: M06-C-R1 + mandatory_return_after_remediation: M08-D-R1 + frozen_stages: + M08-B: PARTIAL_BLOCKED_EXTERNAL_SCOPE_FROZEN + internal_blockers: + - M06_PROTOCOL_DOCUMENT_MISMATCH + - CHECK_SCRIPTS_FILE_URL_PATH + - M08D_ROUTER_LAZYLOAD_CHUNK + 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: