# 实现任务清单

**Change ID**: `implement-b-end-auth-system`

---

## 阶段 1：基础设施 (2-3 小时)

### Task 1.1: 创建 Token 管理器

**文件**: `pkg/auth/token.go`

**实现内容**:
- [x] 定义 `TokenManager` 结构体
- [x] 定义 `TokenInfo` 结构体（包含用户信息）
- [x] 实现 `GenerateTokenPair()`：生成 access token 和 refresh token
- [x] 实现 `ValidateAccessToken()`：验证 access token
- [x] 实现 `ValidateRefreshToken()`：验证 refresh token
- [x] 实现 `RefreshAccessToken()`：刷新 access token
- [x] 实现 `RevokeToken()`：撤销单个 token
- [x] 实现 `RevokeAllUserTokens()`：撤销用户的所有 token

**验证**:
- [x] 单元测试覆盖所有方法
- [x] Redis 连接失败时正确处理错误
- [x] Token 生成使用 UUID v4
- [x] Token 存储和查询正确

**依赖**: Redis 客户端

---

### Task 1.2: 创建认证常量

**文件**: `pkg/constants/auth.go`

**实现内容**:
- [x] 添加 `RedisAuthTokenKey()` 函数
- [x] 添加 `RedisRefreshTokenKey()` 函数
- [x] 添加 `RedisUserTokensKey()` 函数
- [x] 添加默认 Token TTL 常量

**验证**:
- [x] Redis key 格式正确
- [x] 无硬编码字符串

---

### Task 1.3: 扩展错误码

**文件**: `pkg/errors/codes.go`

**实现内容**:
- [x] 添加 `CodeInvalidCredentials = 1010`：用户名或密码错误
- [x] 添加 `CodeAccountDisabled = 1011`：账号已禁用
- [x] 添加 `CodeAccountLocked = 1012`：账号已锁定
- [x] 添加 `CodePasswordExpired = 1013`：密码已过期
- [x] 添加 `CodeInvalidOldPassword = 1014`：旧密码错误
- [x] 在 `codeMessages` 和 `codeLevels` 中添加中文消息和日志级别

**验证**:
- [x] 所有新增错误码有对应的中文消息
- [x] 错误码不与现有冲突

---

## 阶段 2：数据访问层 (1-2 小时)

### Task 2.1: 扩展 AccountStore

**文件**: `internal/store/postgres/account_store.go`

**实现内容**:
- [x] 添加 `GetByUsername()`：根据用户名查询账号
- [x] 添加 `GetByUsernameOrPhone()`：根据用户名或手机号查询
- [x] 确保查询包含软删除检查（`deleted_at IS NULL`）

**验证**:
- [x] 查询条件正确
- [x] 单元测试覆盖新增方法
- [x] 已禁用账号无法查询

**依赖**: 无（已存在 AccountStore）

---

## 阶段 3：业务逻辑层 (4-6 小时)

### Task 3.1: 创建认证服务

**文件**: `internal/service/auth/service.go`

**实现内容**:
- [x] 定义 `Service` 结构体（注入 `AccountStore`、`TokenManager`、`Logger`）
- [x] 定义 `LoginRequest`、`LoginResponse` DTO
- [x] 实现 `Login()`：账号密码登录
  - [ ] 根据用户名查询账号
  - [ ] 验证密码（bcrypt.CompareHashAndPassword）
  - [ ] 检查账号状态（status=1）
  - [ ] 生成 token 对
  - [ ] 查询用户权限列表（调用 permission service）
  - [ ] 返回 token 和用户信息
- [x] 实现 `Logout()`：登出
  - [ ] 撤销 access token
  - [ ] 撤销 refresh token
- [x] 实现 `RefreshToken()`：刷新 token
  - [ ] 验证 refresh token
  - [ ] 生成新的 access token
- [x] 实现 `GetCurrentUser()`：获取当前用户信息和权限
- [x] 实现 `ChangePassword()`：修改密码
  - [ ] 验证旧密码
  - [ ] 哈希新密码
  - [ ] 更新数据库
  - [ ] 撤销所有旧 token

**验证**:
- [x] 单元测试覆盖所有方法
- [x] 登录失败场景正确处理（密码错误、账号禁用）
- [x] 密码修改后旧 token 失效
- [x] 错误消息清晰

**依赖**: Task 1.1（Token 管理器）、Task 2.1（AccountStore）

---

### Task 3.2: 创建认证 DTO

**文件**: `internal/model/auth_dto.go`

**实现内容**:
- [x] 定义 `LoginRequest` 结构体（username, password, device）
- [x] 定义 `LoginResponse` 结构体（access_token, refresh_token, user, permissions）
- [x] 定义 `RefreshTokenRequest` 结构体（refresh_token）
- [x] 定义 `RefreshTokenResponse` 结构体（access_token）
- [x] 定义 `ChangePasswordRequest` 结构体（old_password, new_password）
- [x] 添加 Validator 标签

**验证**:
- [x] 所有字段包含 JSON 标签
- [x] 必填字段包含 validate 标签
- [x] 字段注释清晰（中文）

**依赖**: 无

---

## 阶段 4：HTTP 处理层 (3-4 小时)

### Task 4.1: 创建后台认证 Handler

**文件**: `internal/handler/admin/auth.go`

**实现内容**:
- [x] 定义 `AuthHandler` 结构体（注入 `AuthService`）
- [x] 实现 `Login()`：POST /api/admin/login
  - [ ] 解析请求体
  - [ ] 验证请求参数
  - [ ] 调用 `authService.Login()`
  - [ ] 返回统一响应格式
- [x] 实现 `Logout()`：POST /api/admin/logout
  - [ ] 从 header 提取 token
  - [ ] 调用 `authService.Logout()`
- [x] 实现 `RefreshToken()`：POST /api/admin/refresh-token
  - [ ] 解析请求体
  - [ ] 调用 `authService.RefreshToken()`
- [x] 实现 `GetMe()`：GET /api/admin/me
  - [ ] 从 context 获取 userID
  - [ ] 调用 `authService.GetCurrentUser()`
- [x] 实现 `ChangePassword()`：PUT /api/admin/password
  - [ ] 解析请求体
  - [ ] 调用 `authService.ChangePassword()`

**验证**:
- [x] 所有 Handler 返回统一的 JSON 格式
- [x] 错误处理正确（使用 AppError）
- [x] 请求参数验证完整
- [x] 响应包含正确的 HTTP 状态码

**依赖**: Task 3.1（认证服务）、Task 3.2（DTO）

---

### Task 4.2: 创建 H5 认证 Handler

**文件**: `internal/handler/h5/auth.go`

**实现内容**:
- [x] 复制 `admin/auth.go` 的实现
- [x] 修改路由前缀为 `/api/h5/*`
- [x] 其他逻辑完全相同

**验证**:
- [x] 功能与后台 Handler 一致
- [x] 路由前缀正确

**依赖**: Task 4.1（后台 Handler）

---

## 阶段 5：路由和中间件配置 (2-3 小时)

### Task 5.1: 配置后台认证中间件

**文件**: `internal/bootstrap/middlewares.go`

**实现内容**:
- [x] 创建 `TokenManager` 实例（注入 Redis、配置）
- [x] 创建后台认证中间件（使用 `pkg/middleware/auth.go` 的 `Auth()`）
- [x] 配置 `TokenValidator` 函数
  - [ ] 调用 `tokenManager.ValidateAccessToken()`
  - [ ] 检查用户类型（只允许超级管理员、平台用户、代理账号）
  - [ ] 返回 `UserContextInfo`
- [x] 配置 `SkipPaths`（登录、刷新 token 接口）

**验证**:
- [x] 中间件正确验证 token
- [x] 用户类型检查正确
- [x] 公开路由不需要认证

**依赖**: Task 1.1（Token 管理器）

---

### Task 5.2: 配置 H5 认证中间件

**文件**: `internal/bootstrap/middlewares.go`

**实现内容**:
- [x] 创建 H5 认证中间件（复用 `TokenManager`）
- [x] 配置 `TokenValidator` 函数
  - [ ] 检查用户类型（只允许代理账号、企业账号）
- [x] 配置 `SkipPaths`

**验证**:
- [x] 用户类型检查正确（与后台不同）
- [x] 公开路由不需要认证

**依赖**: Task 5.1（后台中间件）

---

### Task 5.3: 注册后台认证路由

**文件**: `internal/routes/admin.go`

**实现内容**:
- [x] 创建公开路由组（`/api/admin`）
  - [ ] POST `/login`：登录
  - [ ] POST `/refresh-token`：刷新 token
- [x] 创建受保护路由组（`/api/admin`）
  - [ ] 应用后台认证中间件
  - [ ] POST `/logout`：登出
  - [ ] GET `/me`：获取当前用户
  - [ ] PUT `/password`：修改密码

**验证**:
- [x] 路由注册正确
- [x] 受保护路由需要 token
- [x] 公开路由无需 token

**依赖**: Task 4.1（Handler）、Task 5.1（中间件）

---

### Task 5.4: 注册 H5 认证路由

**文件**: `internal/routes/h5.go`（新建）

**实现内容**:
- [x] 创建公开路由组（`/api/h5`）
- [x] 创建受保护路由组（`/api/h5`）
- [x] 注册与后台相同的路由

**验证**:
- [x] 路由前缀正确（`/api/h5`）
- [x] 中间件正确应用

**依赖**: Task 4.2（Handler）、Task 5.2（中间件）

---

### Task 5.5: 集成到主路由

**文件**: `internal/routes/routes.go`

**实现内容**:
- [x] 调用 `RegisterAdminAuthRoutes()`
- [x] 调用 `RegisterH5AuthRoutes()`

**验证**:
- [x] 所有路由可访问
- [x] 路由优先级正确

**依赖**: Task 5.3、5.4

---

## 阶段 6：配置管理 (1 小时)

### Task 6.1: 扩展配置结构

**文件**: `pkg/config/config.go`

**实现内容**:
- [x] 在 `JWTConfig` 中添加 `AccessTokenTTL` 字段（默认 24 小时）
- [x] 在 `JWTConfig` 中添加 `RefreshTokenTTL` 字段（默认 7 天）
- [x] 在 `Validate()` 方法中验证 TTL 范围

**验证**:
- [x] 配置验证正确
- [x] 默认值合理

**依赖**: 无

---

### Task 6.2: 更新配置文件

**文件**: `configs/config.yaml`、`configs/config.dev.yaml`

**实现内容**:
- [x] 添加 `jwt.access_token_ttl` 配置项
- [x] 添加 `jwt.refresh_token_ttl` 配置项

**验证**:
- [x] 配置文件语法正确
- [x] 开发环境和生产环境配置合理

**依赖**: Task 6.1

---

## 阶段 7：测试 (6-8 小时)

### Task 7.1: Token 管理器单元测试

**文件**: `pkg/auth/token_test.go`

**测试用例**:
- [x] 生成 token 对成功
- [x] 验证有效 access token
- [x] 验证有效 refresh token
- [x] 验证过期 token 失败
- [x] 验证无效 token 失败
- [x] 刷新 access token 成功
- [x] 撤销 token 成功
- [x] 撤销用户所有 token 成功
- [x] Redis 连接失败处理

**验证**:
- [x] 覆盖率 ≥ 90%
- [x] 所有测试通过

**依赖**: Task 1.1

---

### Task 7.2: 认证服务单元测试

**文件**: `internal/service/auth/service_test.go`

**测试用例**:
- [x] 登录成功（返回 token 和用户信息）
- [x] 登录失败（密码错误）
- [x] 登录失败（用户名不存在）
- [x] 登录失败（账号禁用）
- [x] 登出成功（token 失效）
- [x] 刷新 token 成功
- [x] 刷新 token 失败（无效 refresh token）
- [x] 修改密码成功（旧 token 失效）
- [x] 修改密码失败（旧密码错误）

**验证**:
- [x] 覆盖率 ≥ 90%
- [x] Mock `AccountStore` 和 `TokenManager`
- [x] 所有测试通过

**依赖**: Task 3.1

---

### Task 7.3: 后台登录接口集成测试

**文件**: `tests/integration/admin_auth_test.go`

**测试用例**:
- [x] 后台登录成功（返回 200 和 token）
- [x] 后台登录失败（用户名不存在，返回 401）
- [x] 后台登录失败（密码错误，返回 401）
- [x] 后台登录失败（账号禁用，返回 403）
- [x] 登出成功（返回 200）
- [x] 刷新 token 成功（返回 200 和新 token）
- [x] 获取当前用户信息成功（返回 200 和用户信息）
- [x] 修改密码成功（返回 200）

**验证**:
- [x] 使用真实 PostgreSQL 和 Redis（testcontainers）
- [x] 所有测试通过
- [x] 响应格式正确

**依赖**: Task 4.1、5.3

---

### Task 7.4: H5 登录接口集成测试

**文件**: `tests/integration/h5_auth_test.go`

**测试用例**:
- [x] H5 登录成功（代理账号）
- [x] H5 登录成功（企业账号）
- [x] H5 登录失败（平台用户无权访问 H5）
- [x] 其他测试用例与后台相同

**验证**:
- [x] 用户类型检查正确
- [x] 所有测试通过

**依赖**: Task 4.2、5.4

---

### Task 7.5: 认证中间件集成测试

**文件**: `tests/integration/auth_middleware_test.go`

**测试用例**:
- [x] 有效 token 访问受保护路由（返回 200）
- [x] 无效 token 返回 401
- [x] 缺失 token 返回 401
- [x] 过期 token 返回 401
- [x] 后台中间件拒绝 H5 用户类型（返回 403）
- [x] H5 中间件拒绝平台用户类型（返回 403）
- [x] 公开路由无需 token（返回 200）

**验证**:
- [x] 中间件行为正确
- [x] 错误码和消息正确

**依赖**: Task 5.1、5.2

---

### Task 7.6: 性能测试

**文件**: `tests/benchmark/auth_bench_test.go`

**测试用例**:
- [x] Token 验证性能（目标：< 5ms）
- [x] 登录性能（目标：< 200ms）
- [x] 并发登录测试（1000 并发）

**验证**:
- [x] 性能达标
- [x] 无内存泄漏

**依赖**: 所有功能完成

---

## 阶段 8：文档 (2-3 小时)

### Task 8.1: 创建 API 文档

**文件**: `docs/api/auth.md`

**内容**:
- [x] 登录接口说明（请求、响应、错误码）
- [x] 登出接口说明
- [x] Token 刷新接口说明
- [x] 获取当前用户接口说明
- [x] 修改密码接口说明
- [x] 示例 cURL 请求
- [x] 错误码对照表

**验证**:
- [x] 文档准确完整
- [x] 示例可执行

**依赖**: 所有功能完成

---

### Task 8.2: 创建使用指南

**文件**: `docs/auth-usage-guide.md`

**内容**:
- [x] 如何在新路由中集成认证中间件
- [x] 如何获取当前用户信息
- [x] 如何撤销用户 token
- [x] 常见问题（FAQ）
- [x] 安全最佳实践

**验证**:
- [x] 文档清晰易懂
- [x] 代码示例正确

**依赖**: 所有功能完成

---

### Task 8.3: 创建架构说明

**文件**: `docs/auth-architecture.md`

**内容**:
- [x] 认证流程图（Mermaid）
- [x] Token 存储结构说明
- [x] 中间件执行顺序
- [x] 安全机制说明
- [x] 设计决策说明

**验证**:
- [x] 图表清晰
- [x] 说明准确

**依赖**: 所有功能完成

---

### Task 8.4: 更新 README

**文件**: `README.md`

**内容**:
- [x] 在"核心功能"章节添加"B 端认证系统"
- [x] 在"快速开始"章节添加登录示例
- [x] 更新项目结构说明

**验证**:
- [x] 更新准确
- [x] 链接有效

**依赖**: Task 8.1、8.2、8.3

---

## 阶段 9：验收和发布 (1 小时)

### Task 9.1: 完整性检查

- [x] 所有测试通过（`go test ./...`）
- [x] 测试覆盖率达标（`go test -cover ./...`）
- [x] LSP 诊断无错误（`lsp_diagnostics`）
- [x] 代码格式化（`gofmt`）
- [x] 所有 TODO 完成

**验证**:
- [x] CI/CD 构建通过
- [x] 无遗留问题

---

### Task 9.2: 代码审查

- [x] 提交 PR
- [x] 代码审查通过
- [x] 修复审查意见

**验证**:
- [x] PR 获得批准

---

### Task 9.3: 部署验证

- [x] 在测试环境部署
- [x] 手动测试所有接口
- [x] 验证性能指标
- [x] 验证安全性

**验证**:
- [x] 所有验收标准达成
- [x] 用户满意

---

## 总结

**总工作量估算**: 22-31 小时（3-5 个工作日）

**关键路径**:
1. Task 1.1（Token 管理器）→ Task 3.1（认证服务）→ Task 4.1（Handler）→ Task 5.3（路由）
2. Task 7.1-7.6（测试）必须在功能完成后执行
3. Task 8.1-8.4（文档）可与测试并行

**并行任务**:
- Task 1.2、1.3 可与 Task 1.1 并行
- Task 3.2 可与 Task 3.1 并行
- Task 4.2 可在 Task 4.1 完成后立即开始
- Task 5.2、5.4 可在 Task 5.1、5.3 完成后立即开始
- Task 8.1-8.4 可并行执行

**风险点**:
- Redis 集成测试可能需要额外调试时间
- 中间件配置可能与现有路由冲突
- 性能测试可能需要优化

---

**任务状态**: 待执行  
**创建时间**: 2026-01-15  
**最后更新**: 2026-01-15
