文件
hyb-oa/.trellis/tasks/archive/2026-08/07-28-all-account-login-readiness/implement.md
T

12 KiB

全员登录可用性实施计划

1. Read-only Baseline

  • 核对公网 /ready 和认证 capabilities;企业邮箱验证码登录、忘记密码均启用。
  • 聚合核对 4 个 active 账户的邮箱/手机号、密码状态、锁定、企微 binding 和成功登录类型,不输出个人标识或认证数据。
  • 确认唯一管理员缺企微 binding,其余 3 个 active 账户已有 binding;当前企微成功登录证据为 0。
  • 确认 3 个账户仍需首次改密且未知随机初始密码无法作为已交付凭据。

2. Administrator Self-Recovery

  • 用户批准进入实施并确认本人可访问企业邮箱。
  • 首次电脑自助请求已签发新的有效验证码;旧验证码失效后被误用 1 次,账户未锁定,服务端未记录邮件发送失败。
  • 失败现场已定性并保留:失败发生在 /reset-password 成功之前,是第二次签发使旧验证码失效;没有前端缓存跳转证据。
  • 执行已批准的管理员 break-glass:精确定位唯一 active 管理员,设置受控一次性密码,清除锁定、撤销旧会话、递增 token version、失效旧验证码并写脱敏审计。
  • 独立只读复核通过:必须首次改密、锁定清零、活动会话与活动验证码均为 0,审计存在;公网 /ready 返回 200。
  • 用户以一次性密码登录并完成强制改密;只读核对首次改密标记已清除、当前仅 1 个活动会话、改密与 break-glass 审计均存在。
  • 新版部署后用户从企微工作台重新进入,由 userid/唯一企业邮箱自动补 binding 并直接登录,不输入 OA 密码。
  • 首次复测仍显示 unbound;只读诊断确认管理员尚无 binding,近 30 分钟没有来自企微 WebView 的成功或失败密码登录,也没有 bind 审计,说明尚未提交页面下方的账号密码表单。
  • 用户再次从企微工作台进入,确认直接到 OA 且不再出现 unbound。
  • 只读核对管理员新增密码成功、binding 和企微登录审计,输出仅限布尔值。

3. Remaining Active Accounts

  • 首批 2–3 名同事完成企微工作台真实登录试用,用户确认本轮参与者全部成功;未收集账号、userid、密码、验证码或个人明细。
  • 已由其余 3 名已有 binding 的 active 员工按不含账号/密码的操作说明,由本人直接测试企微工作台免登。
  • 每名企微成员均已从工作台真机进入;用户于 2026-08-23 确认其余 3 人全部可以进入,结合此前已通过人员,当前 6/6 唯一 binding 与真人免登验收完成。
  • 企微免登验证后,密码回退按最终批准采用代表性生产验收;实际真人覆盖保持 4/6,另外 2 人不要求本轮逐人操作,管理员不接触其密码或验证码。
  • 邮件失败者单独登记稳定失败类别;确需管理员一次性密码时先给出目标数量、审计和交付方案并另行获批。

4. Verification and Prevention

  • 腾讯云生产补充只读聚合已复核:active 6、binding 6、密码历史成功覆盖 3、企微成功审计历史覆盖 4、三类认证锁定均为 0;企微审计计数与用户 6/6 真人可进入证据分开记录,不输出人员明细。
  • 当前快照 binding 缺失/冲突、inactive binding 和 inactive 账户活跃会话均为 0;近 7 天角色变更、企微通讯录写入和 binding 写入审计均为 0。
  • 曾按用户初次指令将唯一 active manager 的直属主管设为 wangshunli;用户随后澄清其仅为系统开发/系统管理员,该中间关系需按最终职责口径修正。
  • 只读确认唯一 active manager 与 majianyong CEO 账户,排除自环/环路后原子将 direct_manager_id 从 wangshunli 修正为 majianyong、写脱敏审计,并复核组织链;不改角色、邮箱、密码、binding 或企微通讯录。
  • 只读解析手工企微通讯录导出并与生产 OA 对账:6 个 userid/binding 和 6 个企业邮箱全部精确一致,缺失、重复、冲突、未匹配和需修改数均为 0。
  • 只读确认 majianyong 保持 ceo 且无直属主管、wangshunli 不新增业务审批角色;生产只有 active finance、没有 active finance_mgr。更早完成的 07-28-ceo-finance-fallback 已使代码兼容 finance|finance_mgr 并将生产三档规则回填为 finance,CEO 本人三档均只读解析为唯一 active 非本人 finance;本轮未创建真实 CEO 报销。
  • 更新现有管理员手册/试运行 checklist:active 账号启用必须包含安全凭据交付、首次改密、密码登录和企微本人免登。
  • 运行认证聚焦测试、前端 typecheck/build、Trellis task/governance、敏感扫描、文档审计和 git diff --check;获批后已完成腾讯云真实生产发布与公网 smoke。

4A. Passwordless First WeCom Login

  • 抽取只读企微成员资料获取能力:输入 OAuth 已确认的内部 userid,只返回规范化企业邮箱和必要状态,不记录原始 payload。
  • 普通企微登录在 binding 缺失时,按 userid/唯一企业邮箱匹配既有 active OA 账户;事务内二次检查双向冲突、建立 binding、写脱敏审计并创建会话。
  • 对无匹配、inactive、userid 已绑定他人、账户已绑定其他 userid 和企微 API 失败逐类失败关闭;不按姓名绑定、不创建账户、不改角色。企微邮箱缺失时仅允许 userid 精确匹配。
  • 保持已有 binding 快路径不变,避免每次登录都调用通讯录详情接口;密码登录不再消费 pending bind 建立企微映射。
  • 修正 unbound 页面文案:不再把账号密码作为首次企微绑定说明,显示稳定的映射缺失/冲突处理指引。
  • 增加后端路由与服务测试、前端文案/交互测试;覆盖首次免密自动绑定、已有 binding、负向矩阵和审计脱敏。
  • 生成生产存量 dry-run 脱敏汇总;部署和 apply 回填分别取得明确批准后执行。
  • 最新生产 live 只读复核确认 OA active 6、企微 active 6、binding 6、唯一匹配 6;缺失、冲突、状态漂移和待回填均为 0,因此本轮无需 apply。剩余 6 条企微资料必填字段 finding 沿用既有接受口径,不作为 binding 阻断。

4B. 2026-08-23 Production Read-only Follow-up

  • 复用既有生产身份引导、运行构建精确比较和 production preflight;腾讯云真实生产身份、migration pending=none、rollback window OPEN/0 均通过。
  • 首个只读事务在聚合前因冲突统计把 UUID 与文本直接 UNION 而被 PostgreSQL 拒绝,事务已回滚、写入为 0,且未自动重试;同一错误在本地只读数据库复现并修正类型合同。
  • 修正版先在本地同结构数据库通过,再执行一次明确的补充生产只读事务;有效查询 1、自动重试 0,只输出白名单计数和布尔值。
  • 最终生产计数:active 6、must-change 3、binding 6、binding 缺失/冲突/inactive 漂移 0、密码历史成功覆盖 3、企微历史成功审计覆盖 4、近 7 天企微成功审计覆盖 1、三类认证锁定 0、异常活跃会话 0。
  • 近 7 天角色变更、企微通讯录写入和 binding 写入审计均为 0;本轮未登录真人账号,未修改数据库、角色、binding、会话或企微通讯录。

4C. 2026-08-23 Production Email Recovery Enablement

  • 先以公网只读方式确认 OA /ready 正常、认证 capabilities 返回 email_disabled;页面在 POST 前拦截,未签发验证码、未增加请求次数,排除员工邮箱或账号本身导致的现场失败。
  • 无发送邮件的 SMTP 连接与认证探测通过;历史生产证据显示邮件开关此前持续关闭,任务中“忘记密码已启用”的旧记录不再作为当前事实。
  • 用户明确批准启用腾讯云真实生产邮件能力;生产 .env 已原子改为 EMAIL_ENABLED=true,未改其他配置、数据库、账号、角色、binding、审批规则或企业微信通讯录。
  • 第一次尝试因 Compose 缺少显式构建标识在写入前停止,第二次尝试因发现生产没有 worker 在写入前停止;两次均为零写入、未自动重试。
  • 只重建当前唯一 server,保持生产 server=1、worker=0、JOBS_ENABLED=true 的既有拓扑,未擅自启动 worker,避免形成重复作业调度;运行构建未改变。
  • 初始健康等待器错误要求 Docker healthcheck,但当前 server 容器没有 healthcheck;随后以容器 running、restartCount=0、公网 /ready=200 以及 capabilities 通过确认服务正常,因此未回滚。
  • 最终 capabilities 为 emailDeliveryReady=true、passwordResetEnabled=true 且 statusReasons=[];SMTP 连接与认证通过,未发送测试邮件,migration pending=none,rollback window 为 OPEN/0。
  • 临时敏感回滚副本已删除,生产 .env 保留已批准的启用状态;本轮未部署代码、未运行 migration、未登录员工账号、未发送邮件。
  • 剩余首次改密范围按用户最终批准采用代表性生产验收:1 人本人完成验证码重置和密码登录,另外 2 人不要求本轮逐一操作,仅记为预计可用;管理员不接触其密码或验证码。
  • 用户确认其中 1 人已完整通过“忘记密码 → 设置新密码 → 使用新密码登录”;只记录通过计数,不记录邮箱、验证码或密码。当前密码历史成功覆盖按真人验收口径为 4/6,尚余 2 人。

4D. Password Input Tab Order

  • 调研 W3C 键盘/焦点顺序、GOV.UK 密码组件,以及 Ant Design、Arco、Element Plus、TDesign 的显示密码实现;国内组件存在“图标进入/跳过 Tab”两套默认。
  • 按用户裁决调整共享 PasswordInput:顺序 Tab 跳过显示/隐藏按钮,保留原生按钮、动态可访问名称、按下状态和输入关联,不使用正数 tabIndex。
  • 增加认证聚焦回归:登录页密码 → 忘记密码链接;修改密码页旧密码 → 新密码 → 确认密码 → 提交;忘记密码页新密码 → 确认密码 → 提交。
  • 保留点击显示/隐藏、输入值不丢失和确认密码框 Enter 提交测试;前端 typecheck/build、3 条聚焦 E2E、Trellis/流程/敏感/差异门禁通过。
  • 首次直接运行两份 E2E 文件时本地入口未启动,20/20 均以 ERR_CONNECTION_REFUSED 停在导航前;启动 Vite 并显式使用本地前端基址后,本次相关 3 条用例全部通过,未把环境失败归类为产品回归。

4E. 2026-08-23 Production Rollout

  • 用户批准推送当前生产候选并部署腾讯云真实生产;main 的 26 个待推送提交经范围核对、migration 差异检查、Trellis/流程/敏感/差异门禁后进入上游,未使用未发布提交 override。
  • 通过生产身份引导器唯一识别腾讯云部署身份与 forced-command refresh 身份;部署前 13/13 聚合体检、目标与数据库身份、migration pending=none、rollback window OPEN/0 均通过。
  • 使用既有部署标准入口发布 7b86ffb,固定 SYNC_ENV=0、DEPLOY_DATA_MODE=existing;未覆盖生产 .env,未执行 reset、db push、手工 DDL 或业务写入。
  • 部署后 Prisma、/ready、运行构建、企业微信/SMTP/OCR/消息桥接契约、runtime smoke、公网 bundle 扫描与备份合同 refresh 均通过;Compose 保持 server=1、worker=0,未启动 worker。
  • 无凭据真实浏览器公网复核通过:根入口登录页可见,密码框 Tab 直接进入“忘记密码?”链接,点击后忘记密码页面正常打开;未登录账号、未发送验证码、未写生产数据。
  • 纠正发布后探针误判:默认 Accept: */* 的纯 HTTP 客户端请求两个路由可返回 404,但全新且禁用 Service Worker 的真实浏览器直接进入时均返回 200、目标页面可见;已有 Service Worker 的首次进入和刷新也均为 200,用户本人刷新未见 404。因此不存在用户可见的 history fallback finding,无需创建对应修复任务。

5. Stop Conditions

  • 企业邮箱不可达、验证码投递异常或账户锁定:停止该员工操作,不连续请求。
  • 企微回调缺 userid、binding conflict 或映射不唯一:停止写入并只读诊断。
  • 任何步骤要求在聊天、任务、命令参数或普通日志中暴露密码、验证码、完整账号或 userid:立即停止并改用受控现场交付。