7.5 KiB
7.5 KiB
user-system review 修复收口(2026-05-28)
结论
本轮已完成 review 报告相关最高优先级前端/E2E blocker 修复,并完成后端、前端、E2E 三层验证。
当前状态:
- 最高优先级 blocker:已修复
- Go 全量测试:通过
- 前端全量测试:通过(82 files, 522 tests)
- Playwright CDP 全链路 E2E:通过
本轮修复项
1. 会话恢复 / refresh 竞态
- 问题:
AuthProvider初始恢复会话与 HTTP client 401 重试路径会并发触发/auth/refresh,在 refresh token 轮换模型下导致401。 - 修复:前端改为共享 single-flight refresh。
- 涉及文件:
frontend/admin/src/lib/http/client.tsfrontend/admin/src/services/auth.tsfrontend/admin/src/services/auth.test.ts
2. 用户列表响应结构漂移
- 问题:后端
/users返回{ users, total, limit, offset },前端只按items读取,导致页面空表。 - 修复:增加 users 列表 normalize,兼容
items/users和page_size/limit/offset。 - 涉及文件:
frontend/admin/src/services/users.tsfrontend/admin/src/services/users.test.ts
3. Webhooks 列表响应结构漂移
- 问题:Webhooks 页加载时报
Cannot read properties of undefined (reading 'map')。 - 修复:兼容
data/items/webhooks多种列表包裹形状。 - 涉及文件:
frontend/admin/src/services/webhooks.tsfrontend/admin/src/services/webhooks.test.ts
4. Social accounts 响应结构漂移
- 问题:ProfileSecurityPage 报
socialAccounts.map is not a function。 - 修复:兼容
array/items/accounts/social_accounts形状。 - 涉及文件:
frontend/admin/src/services/social-accounts.tsfrontend/admin/src/services/social-accounts.test.ts
5. Playwright CDP E2E harness 漂移
- 修复点包括:
- refresh token 断言从可读 cookie 改为 HttpOnly cookie / session presence 真相
创建用员文案 typo- responsive 场景后 viewport 未恢复
- drawer 选择器 strict mode 冲突
- delete confirm 由 modal 漂移为 popconfirm
- 菜单分组/路由漂移:设备、审计日志、Webhooks、profile/security
- 多处页面断言从宽文本改为更稳定选择器
- 涉及文件:
frontend/admin/scripts/run-playwright-cdp-e2e.mjsfrontend/admin/scripts/run-playwright-auth-e2e.sh
6. E2E 限流误伤
- 问题:测试流量触发 API rate limit,导致后续场景误报。
- 修复:为 E2E backend 增加
DISABLE_RATE_LIMIT=1开关,仅用于测试启动脚本。 - 涉及文件:
internal/api/middleware/ratelimit.gofrontend/admin/scripts/run-playwright-auth-e2e.sh
7. 内存限流器全局误伤与条目泄漏风险
- 问题:
internal/api/middleware/ratelimit.go之前按 endpoint 只创建单一 limiter,导致同一接口上的所有用户共享一个桶;同时缺少空闲条目清理策略,无法对历史 client key 做收敛。 - 修复:改为按
endpoint + user_id/IP分桶,并在访问路径上按 TTL 清理长期空闲的 limiter 条目。 - 回归测试:
- 不同 IP 的登录限流相互独立
- 共享 IP 下不同
user_id的 API 限流相互独立 - 空闲 limiter 会被清理,不再无限累积
- 涉及文件:
internal/api/middleware/ratelimit.gointernal/api/middleware/ratelimit_test.go
8. handler context 类型断言补强
- 问题:
SSOHandler与WebhookHandler仍存在user_id.(int64)/username.(string)直接断言,若 middleware 注入异常类型会触发 panic。 - 修复:统一复用
getUserIDFromContext/getUsernameFromContext,类型不匹配时返回401 unauthorized,避免 handler panic。 - 回归测试:
SSOHandler.Authorize非法 context 类型返回401SSOHandler.UserInfo非法 context 类型返回401WebhookHandler.CreateWebhook/ListWebhooks非法 context 类型返回401
- 涉及文件:
internal/api/handler/auth_handler.gointernal/api/handler/sso_handler.gointernal/api/handler/webhook_handler.gointernal/api/handler/context_guard_test.go
9. 密码强度 + 静默错误补强
- 问题:review 报告中指出两类尾部问题:
- 默认密码校验对刚好达到最小长度的短密码过于宽松
- TOTP / 操作日志链路存在
_ = err、_ = json.Unmarshal(...)、_ = repo.Create(...)这类静默吞错
- 修复:
validatePasswordStrength改为对“刚好达到最小长度”的密码要求至少 3 种字符类型;较长密码仍保留 2 种类型可过的兼容行为TOTPService对恢复码摘要、JSON 编解码、UpdateTOTP持久化失败全部显式返回错误,不再静默忽略OperationLogMiddleware对 nil repo fail-safe 返回;异步落库失败改为写日志,不再无声吞错
- 回归测试:
- 8 位两类字符密码被拒绝,8 位三类字符密码通过,较长两类字符密码仍通过
- 损坏的恢复码 JSON 会返回解析错误
- 恢复码消费后持久化失败会显式返回更新错误
- operation log 在 nil repo 情况下不会 panic,参数脱敏/非 JSON fallback 继续受测
- 涉及文件:
internal/service/auth.gointernal/service/auth_service_test.gointernal/service/auth_password_internal_test.gointernal/service/totp.gointernal/service/totp_internal_test.gointernal/api/middleware/operation_log.gointernal/api/middleware/operation_log_test.go
10. review 报告真相校准 + avatar 路径硬化
- 真相校准:
PROJECT_REVIEW_REPORT.md中一批条目已不再代表当前仓库真相,至少包括:uploadAvatar字段名错误:前后端当前都使用avatar,该条为陈旧误报StateManager无法停止、L1Cache无容量限制、密码强度过宽松、操作日志未转义、Webhooks 客户端全量分页、ContactBindingsSection未复用:均已在后续提交中关闭
- 仍值得继续跟踪、但已不构成功能 blocker 的尾项:
social_account_repo.go仍是原生 SQL 实现AuthProvider仍保留 React state + session store 双轨状态管理ApiResponse.data空值建模仍偏乐观(T而非T | null)
- 本轮额外修复:
- 将头像上传目录从运行时相对路径解析改为绝对路径归一化,避免 cwd 漂移导致文件落盘位置不稳定
- 扩展名校验统一转小写,避免
.JPG/.PNG这类常见文件名被误拒
- 回归测试:
resolveAvatarUploadDir("")返回绝对路径且收敛到/uploads/avatars- 自定义根目录会被保留并归一化到
<root>/avatars
- 涉及文件:
internal/api/handler/avatar_handler.gointernal/api/handler/avatar_handler_path_test.go
验证结果
后端
- 命令:
go test ./... - 结果:通过
前端
- 命令:
npm test -- --runInBand - 结果:通过
- 统计:
82 passed,522 passed
E2E
- 命令:
npm run e2e:full - 结果:通过
- 结论:
Playwright CDP E2E completed successfully
闭环判断
实现闭环
已完成。本轮识别出的真实 blocker 均已修复。
证据闭环
已完成。Go 全量测试、前端全量测试、CDP E2E 全部通过。
文档真相闭环
已完成。本文件记录了问题、修复、验证与当前结论。
防复发闭环
已部分完成:
- 已为 users/webhooks/social-accounts 响应结构漂移补 service-level normalize + tests
- 已把 refresh 单飞与 E2E harness 漂移修复固化
- 后续建议:把 E2E 页面导航/断言进一步抽象为页面对象或稳定 helper,减少文案/菜单变动带来的连锁断言漂移