R91 A5-A6 收口公网门禁与备份恢复

这个提交包含在:
2026-05-05 20:25:30 +08:00
父节点 4b08cb455e
当前提交 fced77a567
共修改 2 个文件,包含 35 行新增和 4 行删除
+31
查看文件
@@ -269,3 +269,34 @@ R70 初次试运行暂停项已在 2026-04-28 的 R71 定向修复后关闭。
- 当前仍需收口:
- 部署 R89/R90 最新代码到公网后,再用真实手机企业微信打开一次应用,确认已绑定账号直接进入 `/mobile`
- 用既有测试账号或 smoke 账号跑公网 live smoke,不使用真实业务账号
## R91 公网部署、live smoke 与备份恢复
- 时间:`2026-05-05 20:13 - 20:24 CST`
- 本轮部署:
- 已执行 `bash deploy/trialrun/deploy.sh`
- 远端已重建 `hyb-oa-trialrun-server`
- 前端 build 通过;仍保留既有 Vite circular chunk 警告
- `smoke-external-deps.js`:通过,当前 OCR 仍为 `mock provider`
- 企微移动入口复核:
- `GET https://oa.hyinda.com/api/auth/wecom/config`:`loginUrl=/api/auth/wecom/login?returnTo=%2Fmobile`、`defaultReturnTo=/mobile`
- `GET https://oa.hyinda.com/api/auth/wecom/login`:`HTTP 302` 到企业微信 OAuth,state 中 `returnTo=/mobile`
- Playwright 使用 iPhone + 企业微信 UA 打开公网 `/login`:主 CTA 可见,点击后请求 `/api/auth/wecom/login?returnTo=%2Fmobile` 并跳转 `open.weixin.qq.com`
- 截图:`output/playwright/r91-public-mobile-wecom-login.png`
- Runtime smoke:
- 首次手动补跑发现 `global_search_v1` 仍为 `force_off`
- 已备份远端 feature flag 状态:`/opt/hyb-oa-trialrun/deploy/trialrun/backups/feature-flags-r91-before-20260505-2018.csv`
- 已将 trialrun 必需的 11 个 `force_off` flag 改为 `inherit`
- 再次执行 `docker-compose ... exec -T server node src/scripts/smoke-trialrun-runtime.js`:通过
- Live smoke:
- 已确认远端存在 `SMOKE001` / `SMOKE002` 独立账号
- 已在本次会话内重置 smoke 账号随机密码用于自动化;密码未写入 git、不打印
- `LIVE_EXPECT_WECOM_STATUS=ready bash scripts/qa/run-web-gates.sh smoke-live`:`3 passed`
- 备份与恢复演练:
- DB 备份:`/opt/hyb-oa-trialrun/deploy/trialrun/backups/hyb-oa-db-20260505_202239.dump`
- Storage 备份:`/opt/hyb-oa-trialrun/deploy/trialrun/backups/hyb-oa-storage-20260505_202241.tar.gz`
- DB 恢复演练:已恢复到临时库 `hyb_oa_restore_check`,确认 `public` schema 下 96 张表,随后删除临时库
- Storage 恢复演练:已恢复到 `/tmp/hyb-oa-storage-restore-check-20260505_202241`,确认可解包,随后清理临时目录
- 演练后 `GET https://oa.hyinda.com/ready`:通过
- 当前仍需人工完成:
- 用真实手机企业微信从工作台打开 OA 应用一次,确认已绑定账号直接进入 `/mobile`
@@ -1,7 +1,7 @@
"ID","Title","Description","Acceptance","Test_Method","Tools","Dev_Status","Review1_Status","Regression_Status","Files","Dependencies","Notes"
"A1","R90/R91 执行合同冻结","建立本轮试运行收口执行合同,范围限定为事实源刷新、公网部署/企微移动闭环、测试账号核对与自动化回归,不新增横向业务模块。","Issue CSV 字段完整且通过校验;后续实施均能回写到本合同。","命令:`python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-05_20-01-18-r90-r91-trialrun-closeout.csv`。业务:确认本轮不把 ERP、复杂财务、高级考勤、采购差旅扩展纳入试运行主线。","manual","DONE","DONE","DONE","issues/2026-05-05_20-01-18-r90-r91-trialrun-closeout.csv","[]","2026-05-05:CSV 已创建并通过 validate_issues_csv;回滚路径:删除本轮新增 CSV;不影响业务代码。"
"A2","治理事实源刷新","刷新当前权威事实源,修正 R80-R89 后文档中关于企微、移动入口、feature flag、试运行状态的过期描述,并保留旧 CSV superseded 处理原则。","`docs/feature-matrix.md`、`docs/admin-handbook.md`、`deploy/trialrun/checklist.md`、`artifacts/r70/manual-trialrun-checklist.md` 与 R89/R80-R86 当前结论一致;旧 Issue 残留不再被误判为当前待办。","命令:`rg -n 'returnTo=%2Fportal|WECOM_ENABLED=false|WECOM_ENTRY_ENABLED=false|blocked_external' docs/admin-handbook.md deploy/trialrun/checklist.md docs/feature-matrix.md artifacts/r70/manual-trialrun-checklist.md artifacts/r75/coverage-matrix.csv || true`。业务:管理员按文档配置企微入口时默认手机进入 `/mobile`,且能理解哪些历史 TODO 已由后续 R77-R89 替代。","manual|rg","DONE","DONE","DONE","docs/feature-matrix.md|docs/admin-handbook.md|deploy/trialrun/checklist.md|artifacts/r70/manual-trialrun-checklist.md|artifacts/r70/manual-trialrun-report.md|artifacts/r75/coverage-matrix.csv|issues/README.md","[""A1""]","2026-05-05:事实源已刷新;旧 R79 企微关闭诊断已标为历史,不批量伪造旧 CSV 状态;回滚路径:恢复文档变更。"
"A3","公网部署与测试账号核对","核对 `https://oa.hyinda.com` 当前部署版本、运行时配置、已有测试账号/smoke 账号是否可用于 live smoke,必要时只做配置级修正,不写入密钥到仓库。","公网 `/ready` 正常;远端版本与本地最新提交差异明确;至少确认一组可自动化 smoke 的测试账号存在或记录缺口;敏感值不进入 git。","命令:`curl -fsS https://oa.hyinda.com/ready`;SSH 只读核对远端部署目录、容器状态和测试账号清单。业务:用测试账号登录后能进入 Portal 或 mobile 工作台。","ssh|curl|manual","DONE","DONE","DONE","external|deploy/trialrun/checklist.md|artifacts/r70/manual-trialrun-report.md","[""A2""]","2026-05-05:`/ready` 通过;root/deploy 均可 SSH;远端 server/db 正常;已确认 `SMOKE001`/`SMOKE002` 独立 smoke 账号存在且 active,但本地/远端未配置 LIVE_SMOKE_* 密码变量。回滚路径:本项只读核对,不改变业务数据。"
"A4","真实企微移动闭环与自动化辅助","把公网企业微信入口按移动优先口径收口,并用 Playwright/curl 压榨自动化验证;真实企业微信客户端只保留必须由用户点击的一次确认。","企微配置接口 ready;OAuth login 302 正确;移动 UA/小屏访问默认落到 `/mobile`;已记录真机企业微信验证结果或明确唯一剩余人工动作。","命令:`curl -I 'https://oa.hyinda.com/api/auth/wecom/login?returnTo=%2Fmobile'`;Playwright 用移动视口验证登录页 CTA 与 `/mobile` 导航。业务:手机企业微信工作台进入 OA 后已绑定用户不再停留在登录页。","playwright|curl|manual","DOING","TODO","TODO","server/src/routes/wecomAuth.js|server/tests/unit/routes/wecomAuth.test.js|client/src/api/auth.ts|client/tests/e2e/r89-mobile-login-navigation.spec.ts|external|artifacts/r70/manual-trialrun-report.md","[""A3""]","涉及真实企微容器时需要用户手机确认;回滚路径:企业微信后台入口改回上一 URL 或关闭 wecom_entry_v1。"
"A5","发布门禁与备份恢复准备","执行可用的本地/公网门禁,补齐备份恢复演练的当前状态,区分已自动化完成、可远端执行和仍需人工确认的部分。","本地 typecheck/build 或相关 release gate 通过;公网 live smoke 结果清晰;DB/storage 备份恢复状态有记录,未完成项有可操作步骤。","命令:`cd client && npm run typecheck && npm run build`;可用时执行 `bash scripts/qa/run-web-gates.sh smoke-live`。业务:发布前知道是否可以回滚到上个版本,且 smoke 不使用真实业务账号。","bash|playwright|manual","TODO","TODO","TODO","client|server|deploy/trialrun/checklist.md|artifacts/r70/manual-trialrun-report.md","[""A4""]","若运行全量回归成本过高,记录原因并保留最小门禁;回滚路径:不改变业务数据。"
"A6","状态回填与中文分批提交","按完成情况回填本轮 CSV,分批中文 commit,并汇报后续必须人工配合的精确操作。","A1-A5 状态与实测一致;git 工作区干净或仅剩明确忽略/不提交产物;commit message 使用中文并引用 R90/R91 Issue ID。","命令:`git status --short`;`git log --oneline -3`。业务:用户能按报告继续完成手机企微或备份恢复等人工步骤。","git|manual","TODO","TODO","TODO","issues/2026-05-05_20-01-18-r90-r91-trialrun-closeout.csv|N/A","[""A5""]","按用户要求中文分批提交;若有外部环境未闭环,不伪造 DONE。"
"A3","公网部署与测试账号核对","核对 `https://oa.hyinda.com` 当前部署版本、运行时配置、已有测试账号/smoke 账号是否可用于 live smoke,必要时只做配置级修正,不写入密钥到仓库。","公网 `/ready` 正常;远端版本与本地最新提交差异明确;至少确认一组可自动化 smoke 的测试账号存在或记录缺口;敏感值不进入 git。","命令:`curl -fsS https://oa.hyinda.com/ready`;SSH 只读核对远端部署目录、容器状态和测试账号清单。业务:用测试账号登录后能进入 Portal 或 mobile 工作台。","ssh|curl|manual","DONE","DONE","DONE","external|deploy/trialrun/checklist.md|artifacts/r70/manual-trialrun-report.md","[""A2""]","2026-05-05:`/ready` 通过;root/deploy 均可 SSH;远端 server/db 正常;已确认 `SMOKE001`/`SMOKE002` 独立 smoke 账号存在且 active,并已在本次会话内重置随机密码用于 live smoke;密码未写入 git、不打印。回滚路径:如需撤销,可再次重置 smoke 账号密码。"
"A4","真实企微移动闭环与自动化辅助","把公网企业微信入口按移动优先口径收口,并用 Playwright/curl 压榨自动化验证;真实企业微信客户端只保留必须由用户点击的一次确认。","企微配置接口 ready;OAuth login 302 正确;移动 UA/小屏访问默认落到 `/mobile`;已记录真机企业微信验证结果或明确唯一剩余人工动作。","命令:`curl -I 'https://oa.hyinda.com/api/auth/wecom/login?returnTo=%2Fmobile'`;Playwright 用移动视口验证登录页 CTA 与 `/mobile` 导航。业务:手机企业微信工作台进入 OA 后已绑定用户不再停留在登录页。","playwright|curl|manual","DONE","DONE","DONE","server/src/routes/wecomAuth.js|server/tests/unit/routes/wecomAuth.test.js|client/src/api/auth.ts|client/tests/e2e/r89-mobile-login-navigation.spec.ts|external|artifacts/r70/manual-trialrun-report.md","[""A3""]","2026-05-05:公网 `/api/auth/wecom/config` 已返回 `loginUrl=/api/auth/wecom/login?returnTo=%2Fmobile`、`defaultReturnTo=/mobile`;curl 直连 login 302 到企业微信且 state 为 `/mobile`;Playwright 移动企业微信 UA 验证 primary CTA 请求 `/mobile` 并跳到 open.weixin.qq.com。唯一剩余人工动作:用户手机企业微信打开应用确认真实容器 cookie 与落点。"
"A5","发布门禁与备份恢复准备","执行可用的本地/公网门禁,补齐备份恢复演练的当前状态,区分已自动化完成、可远端执行和仍需人工确认的部分。","本地 typecheck/build 或相关 release gate 通过;公网 live smoke 结果清晰;DB/storage 备份恢复状态有记录,未完成项有可操作步骤。","命令:`cd client && npm run typecheck && npm run build`;可用时执行 `bash scripts/qa/run-web-gates.sh smoke-live`。业务:发布前知道是否可以回滚到上个版本,且 smoke 不使用真实业务账号。","bash|playwright|manual","DONE","DONE","DONE","client|server|deploy/trialrun/checklist.md|artifacts/r70/manual-trialrun-report.md","[""A4""]","2026-05-05:`deploy.sh` 完成构建和 external deps smoke;手动补跑 runtime smoke 发现 feature flag 阻塞后已备份并改为 inherit,随后 runtime smoke 通过;live smoke 使用独立 smoke 账号 3 passed;DB 备份 `hyb-oa-db-20260505_202239.dump` 已恢复到临时库并确认 96 张 public 表;storage 备份 `hyb-oa-storage-20260505_202241.tar.gz` 已恢复到临时目录并清理。"
"A6","状态回填与中文分批提交","按完成情况回填本轮 CSV,分批中文 commit,并汇报后续必须人工配合的精确操作。","A1-A5 状态与实测一致;git 工作区干净或仅剩明确忽略/不提交产物;commit message 使用中文并引用 R90/R91 Issue ID。","命令:`git status --short`;`git log --oneline -3`。业务:用户能按报告继续完成手机企微或备份恢复等人工步骤。","git|manual","DONE","DONE","DONE","issues/2026-05-05_20-01-18-r90-r91-trialrun-closeout.csv|N/A","[""A5""]","2026-05-05:A1-A5 已回填;本轮已按中文分批提交,剩余人工动作仅是真实手机企业微信打开一次确认 `/mobile` 落点。"
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 A1 R90/R91 执行合同冻结 建立本轮试运行收口执行合同,范围限定为事实源刷新、公网部署/企微移动闭环、测试账号核对与自动化回归,不新增横向业务模块。 Issue CSV 字段完整且通过校验;后续实施均能回写到本合同。 命令:`python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-05_20-01-18-r90-r91-trialrun-closeout.csv`。业务:确认本轮不把 ERP、复杂财务、高级考勤、采购差旅扩展纳入试运行主线。 manual DONE DONE DONE issues/2026-05-05_20-01-18-r90-r91-trialrun-closeout.csv [] 2026-05-05:CSV 已创建并通过 validate_issues_csv;回滚路径:删除本轮新增 CSV;不影响业务代码。
3 A2 治理事实源刷新 刷新当前权威事实源,修正 R80-R89 后文档中关于企微、移动入口、feature flag、试运行状态的过期描述,并保留旧 CSV superseded 处理原则。 `docs/feature-matrix.md`、`docs/admin-handbook.md`、`deploy/trialrun/checklist.md`、`artifacts/r70/manual-trialrun-checklist.md` 与 R89/R80-R86 当前结论一致;旧 Issue 残留不再被误判为当前待办。 命令:`rg -n 'returnTo=%2Fportal|WECOM_ENABLED=false|WECOM_ENTRY_ENABLED=false|blocked_external' docs/admin-handbook.md deploy/trialrun/checklist.md docs/feature-matrix.md artifacts/r70/manual-trialrun-checklist.md artifacts/r75/coverage-matrix.csv || true`。业务:管理员按文档配置企微入口时默认手机进入 `/mobile`,且能理解哪些历史 TODO 已由后续 R77-R89 替代。 manual|rg DONE DONE DONE docs/feature-matrix.md|docs/admin-handbook.md|deploy/trialrun/checklist.md|artifacts/r70/manual-trialrun-checklist.md|artifacts/r70/manual-trialrun-report.md|artifacts/r75/coverage-matrix.csv|issues/README.md ["A1"] 2026-05-05:事实源已刷新;旧 R79 企微关闭诊断已标为历史,不批量伪造旧 CSV 状态;回滚路径:恢复文档变更。
4 A3 公网部署与测试账号核对 核对 `https://oa.hyinda.com` 当前部署版本、运行时配置、已有测试账号/smoke 账号是否可用于 live smoke,必要时只做配置级修正,不写入密钥到仓库。 公网 `/ready` 正常;远端版本与本地最新提交差异明确;至少确认一组可自动化 smoke 的测试账号存在或记录缺口;敏感值不进入 git。 命令:`curl -fsS https://oa.hyinda.com/ready`;SSH 只读核对远端部署目录、容器状态和测试账号清单。业务:用测试账号登录后能进入 Portal 或 mobile 工作台。 ssh|curl|manual DONE DONE DONE external|deploy/trialrun/checklist.md|artifacts/r70/manual-trialrun-report.md ["A2"] 2026-05-05:`/ready` 通过;root/deploy 均可 SSH;远端 server/db 正常;已确认 `SMOKE001`/`SMOKE002` 独立 smoke 账号存在且 active,但本地/远端未配置 LIVE_SMOKE_* 密码变量。回滚路径:本项只读核对,不改变业务数据。 2026-05-05:`/ready` 通过;root/deploy 均可 SSH;远端 server/db 正常;已确认 `SMOKE001`/`SMOKE002` 独立 smoke 账号存在且 active,并已在本次会话内重置随机密码用于 live smoke;密码未写入 git、不打印。回滚路径:如需撤销,可再次重置 smoke 账号密码。
5 A4 真实企微移动闭环与自动化辅助 把公网企业微信入口按移动优先口径收口,并用 Playwright/curl 压榨自动化验证;真实企业微信客户端只保留必须由用户点击的一次确认。 企微配置接口 ready;OAuth login 302 正确;移动 UA/小屏访问默认落到 `/mobile`;已记录真机企业微信验证结果或明确唯一剩余人工动作。 命令:`curl -I 'https://oa.hyinda.com/api/auth/wecom/login?returnTo=%2Fmobile'`;Playwright 用移动视口验证登录页 CTA 与 `/mobile` 导航。业务:手机企业微信工作台进入 OA 后已绑定用户不再停留在登录页。 playwright|curl|manual DOING DONE TODO DONE TODO DONE server/src/routes/wecomAuth.js|server/tests/unit/routes/wecomAuth.test.js|client/src/api/auth.ts|client/tests/e2e/r89-mobile-login-navigation.spec.ts|external|artifacts/r70/manual-trialrun-report.md ["A3"] 涉及真实企微容器时需要用户手机确认;回滚路径:企业微信后台入口改回上一 URL 或关闭 wecom_entry_v1。 2026-05-05:公网 `/api/auth/wecom/config` 已返回 `loginUrl=/api/auth/wecom/login?returnTo=%2Fmobile`、`defaultReturnTo=/mobile`;curl 直连 login 302 到企业微信且 state 为 `/mobile`;Playwright 移动企业微信 UA 验证 primary CTA 请求 `/mobile` 并跳到 open.weixin.qq.com。唯一剩余人工动作:用户手机企业微信打开应用确认真实容器 cookie 与落点。
6 A5 发布门禁与备份恢复准备 执行可用的本地/公网门禁,补齐备份恢复演练的当前状态,区分已自动化完成、可远端执行和仍需人工确认的部分。 本地 typecheck/build 或相关 release gate 通过;公网 live smoke 结果清晰;DB/storage 备份恢复状态有记录,未完成项有可操作步骤。 命令:`cd client && npm run typecheck && npm run build`;可用时执行 `bash scripts/qa/run-web-gates.sh smoke-live`。业务:发布前知道是否可以回滚到上个版本,且 smoke 不使用真实业务账号。 bash|playwright|manual TODO DONE TODO DONE TODO DONE client|server|deploy/trialrun/checklist.md|artifacts/r70/manual-trialrun-report.md ["A4"] 若运行全量回归成本过高,记录原因并保留最小门禁;回滚路径:不改变业务数据。 2026-05-05:`deploy.sh` 完成构建和 external deps smoke;手动补跑 runtime smoke 发现 feature flag 阻塞后已备份并改为 inherit,随后 runtime smoke 通过;live smoke 使用独立 smoke 账号 3 passed;DB 备份 `hyb-oa-db-20260505_202239.dump` 已恢复到临时库并确认 96 张 public 表;storage 备份 `hyb-oa-storage-20260505_202241.tar.gz` 已恢复到临时目录并清理。
7 A6 状态回填与中文分批提交 按完成情况回填本轮 CSV,分批中文 commit,并汇报后续必须人工配合的精确操作。 A1-A5 状态与实测一致;git 工作区干净或仅剩明确忽略/不提交产物;commit message 使用中文并引用 R90/R91 Issue ID。 命令:`git status --short`;`git log --oneline -3`。业务:用户能按报告继续完成手机企微或备份恢复等人工步骤。 git|manual TODO DONE TODO DONE TODO DONE issues/2026-05-05_20-01-18-r90-r91-trialrun-closeout.csv|N/A ["A5"] 按用户要求中文分批提交;若有外部环境未闭环,不伪造 DONE。 2026-05-05:A1-A5 已回填;本轮已按中文分批提交,剩余人工动作仅是真实手机企业微信打开一次确认 `/mobile` 落点。