6.8 KiB
生产登录态只读验收:设计说明
1. 设计边界
本任务是生产账号诊断与登录态只读验收,不是账号修复或产品开发。前一部署任务已经证明产品候选、migration、匿名鉴权和公网基础 readiness;本任务只补齐因仓库外凭据 401 而缺失的登录态证据。
核心原则是“先读取状态,再决定是否允许一次登录”。账号失败计数和锁定属于生产安全状态,不能拿登录端点当探针。合同终止是不可逆写入,浏览器验收必须在输入和网络两层同时保证不会提交。
2. 状态序列
生产身份 / 已部署 SHA / 65 migration(只读)
-> rollback window PRE(只读)
-> admin/employee identifier 登录语义 + 账号状态(BEGIN READ ONLY)
-> 分流:identifier / locked / inactive-role / password credential
-> 仅当合法新鲜凭据 + 全部门禁 PASS:每角色最多一次登录
-> admin 合同详情只读 + terminate POST=0
-> employee 权限负向
-> rollback window POST(只读)
-> 只读 reviewer / 结论
任何箭头失败都停止。PRE 与 POST 快照即使中间步骤 PAUSED 也都要执行;这样能区分本任务未写入与同期真实用户关闭窗口。
3. 账号只读诊断
3.1 查询合同
生产查询使用 BEGIN READ ONLY,只处理 admin/employee 两个 role key。identifier 从受控进程变量读取,在数据库内与 email、phone 做精确比较;不能因为现有 dry-run helper 支持 employee_no 就把员工编号视为可登录 identifier。
稳定输出模型:
roleKey=admin|employee
matchedBy=email|phone|none
active=true|false
archived=true|false
locked=true|false
failureCount=<非负整数>
expectedRoleReady=true|false
不输出 identifier、员工编号、邮箱、手机号、锁定时间、密码 hash、角色明细或原始行。查询目标多于一条、事务不是 read-only、输出字段异常都 fail-closed。
3.2 分流矩阵
| 只读结果 | 结论 | 动作 |
|---|---|---|
matchedBy=none |
secret 中 identifier 过期或不符合 email/phone 登录合同 | PAUSED;账号持有人从合法来源恢复仓库外凭据 |
| active/role 不满足 | 账号或授权事实已变化 | PAUSED;另设账号/权限 task |
locked=true |
账号当前锁定 | PAUSED;不试登录、不解锁 |
| 匹配、active、role 正确、未锁定,既有结果为 401 | 按当前 auth 分支可判定仓库外密码不匹配 | PAUSED;密码变更另行批准 |
| 合法新鲜凭据已恢复且全部健康 | 允许有限登录验证 | 每角色最多一次,单 worker、零 retry |
账号不存在与密码错误在 HTTP 上同为 401;只有数据库只读诊断能安全拆分。若一次获准登录仍失败,立即重查 failure count/locked,记录差值并停止。
4. 回滚窗口双快照
termination migration 已 applied,因此必须真实查询:
SELECT count(*) FROM contract_registry WHERE status = 'terminated';
查询异常不可 catch 后默认 OPEN。两次快照使用同一目标、同一查询合同和同一输出格式:
- count = 0:
rollbackWindow=OPEN - count > 0:
rollbackWindow=CLOSED - PRE OPEN / POST CLOSED 且 terminate request count = 0:并发真实用户已产生首条终止记录;记录窗口永久关闭,不归因于本任务
- PRE CLOSED:全部验收仍只读,旧应用回退从一开始就不可用
5. 登录预算与浏览器控制
5.1 登录预算
- 执行前确认仓库外凭据是新鲜、合法来源,不靠修改生产账号获得。
- 管理员、员工各最多一次;Playwright 固定
--workers=1 --retries=0 --reporter=list。 - 禁止复用默认 CI retry;一次失败即结束该角色路径。
- 失败后重新运行账号只读查询,证明是否增加失败计数或触发锁定。
5.2 合同详情安全断言
draft/archived 不显示终止面板,无法承担“误点后服务端 409”的兜底。对已有 active/expired 合同采用以下边界:
- 打开合同详情并验证自然中文状态和只读摘要;证据不采集正文或敏感字段。
- 注册请求监听,统计匹配终止端点的
POST;初始为 0。 - 验证“终止合同”面板、至少 10 字提示和 destructive 按钮存在。
- 终止原因保持空值或不足 10 字;断言按钮 disabled。
- 不点击按钮,不打开确认层,不调用 API;结束时终止
POST仍为 0。
优先使用 Playwright CLI 的受控会话;若 CLI 命令不能可靠表达请求监听和 disabled 断言,则由执行者本人做更窄人工检查,只验证入口与按钮状态,不打开确认层。不得为本任务新增会提交数据的 spec。
5.3 权限与数据分支
- 管理员正向:能进入合同台账/详情。
- 员工负向:合同管理入口不可达或服务端返回既定无权结果;不得扩大权限。
- archived 样本存在:只读验证字段锁定;不存在则
PAUSED。 - terminated 样本存在:只读验证中文标签与终止事实;不存在则
PAUSED,绝不制造样本。
6. 失败与权限边界
| 阶段 | 失败 | 处理 |
|---|---|---|
| 身份/SHA/migration | 目标或版本不符 | 停止,不登录 |
| rollback PRE/POST | 查询失败或不可解析 | fail-closed,不推断 OPEN |
| identifier | 不匹配 email/phone 或不唯一 | PAUSED,恢复仓库外 secret |
| 状态/角色/锁定 | 任一不健康 | PAUSED,另行批准账号治理 |
| 登录 | 首次失败 | 停止,重查失败计数/锁定,不重试 |
| 管理员 UI | 数据缺失或只读断言失败 | PAUSED/FAIL,不造数据、不改产品 |
| 员工负向 | 权限扩大或结果不符 | FAIL,不改权限推进 |
| terminate 请求 | 计数不为 0 | 紧急停止并复核 POST 确切结果与窗口;不得再次操作 |
7. 证据与隐私
原始查询和浏览器会话只在受控现场存在。提交材料保存稳定枚举、布尔、计数、SHA、HTTP status 和相对 evidence 引用;不保存生产 identity 明文、账号、凭据、cookie、合同正文、相对方、金额、终止原因或 payload。
截图不是必需证据;若必须截图,应使用无业务正文的局部裁切或脱敏摘要。任一敏感扫描命中都先处理证据,不降低 scanner。
8. 只读 review 与 readiness 结论
本任务涉及生产认证、权限和不可逆状态机边界,执行后必须启动只读 reviewer。reviewer 不修改代码、账号、权限、数据库或证据,只核对:
- 登录前诊断确实先于登录;
- 每角色尝试次数与失败后复查;
- 终止原因/确认层/POST 均未越界;
- rollback window 前后快照及变化解释;
- 证据脱敏与最终 readiness 用语。
只要必需登录态 AC 仍 PAUSED,最终结论只能是“已部署但登录态验收未完成”,不能告知用户可以测试。