用户故事实现细节¶
本文件与
user-story.csv通过story_id关联。 CSV 负责状态和索引,本文件负责业务规则、边界、接口、数据和测试。 每个故事一节,并使用显式 HTML 锚点,保证 CSV 里的details_ref(如#us-001)始终能跳转:
US-001 用户登录¶
1. 目标¶
注册用户可以使用邮箱和密码登录系统,获得访问令牌,进入工作台。
2. 角色与权限¶
- 已注册且状态为
active的用户可以登录。 - 被封禁/未验证用户不能登录。
- 登录失败不暴露“邮箱是否存在”。
3. 入口与界面¶
- 页面:
/login - 字段:
| 字段 | 类型 | 必填 | 校验 |
|---|---|---|---|
| 邮箱 | 是 | 合法邮箱格式,≤ 254 字符 | |
| 密码 | password | 是 | 8-72 字符 |
- 状态:默认 / 提交中 / 错误 / 账号锁定
- 交互:
- 提交时禁用按钮,显示 loading。
- 失败时保留邮箱,清空密码。
- 成功后跳转到
redirect参数指定页面,默认/projects。
4. 业务规则¶
- 邮箱大小写不敏感,存储时统一小写。
- 密码使用 Argon2id 或 bcrypt 哈希校验。
- 连续 5 次失败锁定 15 分钟。
- 登录成功返回 access token(15 分钟)和 refresh token(7 天)。
- 所有登录尝试写审计日志(成功/失败/锁定)。
- 不在日志中记录密码或完整令牌。
5. 数据模型¶
- 读:
users - 写:
audit_logs - 关键字段:
id,email,password_hash,status,failed_login_count,locked_until
6. API¶
POST /api/v1/auth/login- 请求:
- 成功:
200
{
"access_token": "...",
"refresh_token": "...",
"expires_in": 900,
"user": {
"id": "uuid",
"email": "user@example.com",
"display_name": "张三"
}
}
- 失败:
400 VALIDATION_ERROR401 AUTH_INVALID_CREDENTIALS423 AUTH_ACCOUNT_LOCKED403 AUTH_ACCOUNT_DISABLED
7. 验收标准¶
AC-1 正常登录
Given 我是已注册且状态正常的用户
When 我输入正确邮箱和密码并提交
Then 返回 200,跳转到 /projects
And 审计日志记录登录成功
AC-2 密码错误
Given 我是已注册用户
When 我输入错误密码
Then 返回 401 AUTH_INVALID_CREDENTIALS
And 页面显示“邮箱或密码不正确”
AC-3 连续失败锁定
Given 我已经连续失败 5 次
When 我再次尝试登录
Then 返回 423 AUTH_ACCOUNT_LOCKED
And 页面显示剩余锁定时间
AC-4 账号禁用
Given 我的账号状态为 disabled
When 我尝试登录
Then 返回 403 AUTH_ACCOUNT_DISABLED
And 页面提示联系管理员
8. 边界与异常¶
- 邮箱不存在:返回与密码错误相同的提示。
- 密码超长:400,不进行哈希计算。
- 数据库不可用:503,记录 request_id。
- 并发登录:允许多设备,刷新令牌可分别撤销。
- 时区:锁定时间使用 UTC 存储。
9. 可观测性¶
- 日志:
request_id,user_id(成功时),result,duration_ms - 指标:
login_total{result},login_locked_total - 审计:
action=auth.login,result=success/failure/locked
10. 依赖¶
- 依赖:无。
- 被依赖:所有需要登录的故事。
11. 完成定义¶
- 单元测试:密码校验、锁定、禁用、错误码
- 集成测试:数据库读写、审计
- E2E:正常登录、密码错误、锁定
- 实现报告
- CSV 状态
qa_pass
US-xxx <标题>¶
1. 目标¶
<...>
2. 角色与权限¶
<...>
3. 入口与界面¶
- 页面:<路由>
- 字段:
| 字段 | 类型 | 必填 | 校验 |
|---|---|---|---|
| <...> | <...> | <...> | <...> |
- 状态:<默认/加载/空/错误/无权限>
- 交互:<...>
4. 业务规则¶
- <...>
- <...>
5. 数据模型¶
- 读:<表>
- 写:<表>
- 关键字段:<...>
- 索引:<...>
6. API¶
<METHOD> <path>- 请求:
- 成功:<状态码 / 示例>
- 失败:<错误码列表>
7. 验收标准¶
AC-1 <名称> Given <...> When <...> Then <...> And <...>
AC-2 <异常> Given <...> When <...> Then <...>
AC-3 <权限> Given <...> When <...> Then <...>
8. 边界与异常¶
- <空数据>
- <超长/非法格式>
- <权限不足>
- <并发冲突>
- <第三方失败>
- <时区/编码>
9. 可观测性¶
- 日志:<字段>
- 指标:<指标名>
- 审计:
10. 依赖¶
- 依赖:
- 被依赖:
11. 完成定义¶
- 单元测试
- 集成测试
- E2E
- 实现报告
- CSV 状态更新
通用检查清单¶
每个故事在标记 qa_pass 前,确认:
- 正常路径、异常路径、权限边界都有验收标准
- 所有规则可测试
- API 与 OpenAPI 一致
- 数据表与 schema 一致
- 错误码与统一错误模型一致
- 前端状态齐全
- 测试数据可清理
- 依赖关系无环
- 实现报告路径已写入 CSV
- E2E manifest 路径已写入 CSV