Files
huang 80f560df33
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m17s
refactor(account): 统一账号管理API、完善权限检查和操作审计
- 合并 customer_account 和 shop_account 路由到统一的 account 接口
- 新增统一认证接口 (auth handler)
- 实现越权防护中间件和权限检查工具函数
- 新增操作审计日志模型和服务
- 更新数据库迁移 (版本 39: account_operation_log 表)
- 补充集成测试覆盖权限检查和审计日志场景
2026-02-02 17:23:20 +08:00

172 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 统一账号管理接口重构 - 任务清单
## 1. 数据库迁移
- [x] 1.1 创建 `migrations/XXXXXX_create_account_operation_log.up.sql` 迁移文件(创建审计日志表)
- [x] 1.2 创建 `migrations/XXXXXX_create_account_operation_log.down.sql` 回滚文件
- [x] 1.3 运行迁移验证表结构和索引创建成功
## 2. 权限检查基础设施
- [x] 2.1 创建 `pkg/middleware/permission_helper.go` 文件
- [x] 2.2 实现 `CanManageShop` 函数(验证代理对目标店铺的管理权限)
- [x] 2.3 实现 `CanManageEnterprise` 函数(验证代理对目标企业的管理权限)
- [x] 2.4 定义 `ShopStoreInterface``EnterpriseStoreInterface` 接口(用于依赖倒置)
- [x] 2.5 编写单元测试 `pkg/middleware/permission_helper_test.go`(覆盖率 ≥ 90%
- [x] 2.6 运行 `lsp_diagnostics` 验证代码无错误
## 3. 审计日志系统
- [x] 3.1 创建 `internal/model/account_operation_log.go`(审计日志模型)
- [x] 3.2 创建 `internal/store/postgres/account_operation_log_store.go`(审计日志存储层)
- [x] 3.3 实现 `AccountOperationLogStore.Create` 方法
- [x] 3.4 创建 `internal/service/account_audit/service.go`(审计日志服务层)
- [x] 3.5 实现 `AccountAuditService.LogOperation` 方法异步写入Goroutine
- [x] 3.6 编写单元测试 `internal/service/account_audit/service_test.go`(覆盖率 ≥ 90%
- [x] 3.7 运行 `lsp_diagnostics` 验证代码无错误
## 4. AccountService 重构(添加权限检查和审计)
- [x] 4.1 为 `AccountService` 添加 `shopStore``enterpriseStore` 依赖
- [x] 4.2 为 `AccountService` 添加 `auditService` 依赖
- [x] 4.3 重构 `Create` 方法:添加三层权限检查(类型级 + 资源级 + GORM 兜底)
- [x] 4.4 重构 `Create` 方法:集成审计日志记录(异步)
- [x] 4.5 重构 `Update` 方法:添加权限检查和审计日志(记录 before_data 和 after_data
- [x] 4.6 重构 `Delete` 方法:添加权限检查和审计日志
- [x] 4.7 重构 `AssignRoles` 方法:添加权限检查和审计日志
- [x] 4.8 重构 `RemoveRole` 方法:添加权限检查和审计日志
- [x] 4.9 修改错误返回:统一为"无权限操作该资源或资源不存在"
- [x] 4.10 编写单元测试 `internal/service/account/service_test.go`(覆盖率 ≥ 90%
- [x] 4.11 运行 `lsp_diagnostics` 验证代码无错误
## 5. 删除旧 Service 层代码
- [x] 5.1 删除 `internal/service/shop_account/service.go`
- [x] 5.2 删除 `internal/service/customer_account/service.go`
- [x] 5.3 删除相关测试文件 `tests/unit/shop_account_service_test.go``tests/unit/customer_account_service_test.go`
- [x] 5.4 运行 `go build ./...` 确保没有引用残留
## 6. AccountHandler 重构(支持所有账号类型)
- [x] 6.1 重构 `AccountHandler.Create` 方法:支持 platform/shop/enterprise 三种类型
- [x] 6.2 重构 `AccountHandler.List` 方法支持按账号类型筛选username/phone/status/shop_id/enterprise_id
- [x] 6.3 重构 `AccountHandler.GetByID` 方法:支持所有账号类型
- [x] 6.4 重构 `AccountHandler.Update` 方法:支持所有账号类型
- [x] 6.5 重构 `AccountHandler.Delete` 方法:支持所有账号类型
- [x] 6.6 重构 `AccountHandler.UpdatePassword` 方法:支持所有账号类型
- [x] 6.7 重构 `AccountHandler.UpdateStatus` 方法:支持所有账号类型
- [x] 6.8 重构 `AccountHandler.AssignRoles` 方法:支持所有账号类型
- [x] 6.9 重构 `AccountHandler.GetRoles` 方法:支持所有账号类型
- [x] 6.10 重构 `AccountHandler.RemoveRole` 方法:支持所有账号类型
- [x] 6.11 运行 `lsp_diagnostics` 验证代码无错误
## 7. 删除旧 Handler 层代码
- [x] 7.1 删除 `internal/handler/admin/shop_account.go`
- [x] 7.2 删除 `internal/handler/admin/customer_account.go`
- [x] 7.3 运行 `go build ./...` 确保没有引用残留
## 8. 路由重构(统一账号管理路由)
- [x] 8.1 重构 `internal/routes/account.go`:实现新路由结构
- [x] 8.2 注册平台账号路由组 `/api/admin/accounts/platform/*`10个接口
- [x] 8.3 注册代理账号路由组 `/api/admin/accounts/shop/*`10个接口
- [x] 8.4 注册企业账号路由组 `/api/admin/accounts/enterprise/*`10个接口
- [x] 8.5 为企业账号路由组添加中间件拦截(企业账号禁止访问账号管理)
- [x] 8.6 删除旧路由注册:`/api/admin/platform-accounts/*`
- [x] 8.7 删除旧路由注册:`/api/admin/shop-accounts/*`
- [x] 8.8 删除旧路由注册:`/api/admin/customer-accounts/*`
- [x] 8.9 运行 `go build ./...` 确保路由编译通过
## 9. 认证接口统一
- [x] 9.1 创建 `internal/handler/auth/handler.go`(统一认证 Handler
- [x] 9.2 实现 `Login` 方法(合并后台和 H5 登录逻辑)
- [x] 9.3 实现 `Logout` 方法(统一登出)
- [x] 9.4 实现 `RefreshToken` 方法(统一刷新 Token
- [x] 9.5 实现 `GetMe` 方法(统一获取用户信息)
- [x] 9.6 实现 `UpdatePassword` 方法(统一修改密码)
- [x] 9.7 创建 `internal/routes/auth.go` 注册统一认证路由 `/api/auth/*`
- [x] 9.8 删除旧认证路由:`/api/admin/login`5个接口
- [x] 9.9 删除旧认证路由:`/api/h5/login`5个接口
- [x] 9.10 保留个人客户认证路由:`/api/c/v1/*`(不修改)
- [x] 9.11 运行 `lsp_diagnostics` 验证代码无错误
## 10. Bootstrap 更新(依赖注入调整)
- [x] 10.1 更新 `internal/bootstrap/stores.go`:添加 `AccountOperationLogStore` 初始化
- [x] 10.2 更新 `internal/bootstrap/services.go`:添加 `AccountAuditService` 初始化
- [x] 10.3 更新 `internal/bootstrap/services.go`:更新 `AccountService` 依赖注入(添加 shopStore、enterpriseStore、auditService
- [x] 10.4 更新 `internal/bootstrap/handlers.go`:添加 `AuthHandler` 初始化
- [x] 10.5 更新 `internal/bootstrap/handlers.go`:删除 `ShopAccountHandler``CustomerAccountHandler` 初始化
- [x] 10.6 运行 `go build ./...` 确保编译通过
## 11. 文档生成器更新
- [x] 11.1 更新 `cmd/api/docs.go`:添加新路由到 Handlers 结构体accounts/platform、accounts/shop、accounts/enterprise、auth
- [x] 11.2 更新 `cmd/api/docs.go`删除旧路由platform-accounts、shop-accounts、customer-accounts、admin/login、h5/login
- [x] 11.3 更新 `cmd/gendocs/main.go`:同步更新 Handlers 初始化逻辑
- [x] 11.4 运行 `go run cmd/gendocs/main.go` 生成新的 OpenAPI 文档
- [x] 11.5 验证生成的 `docs/openapi.yaml` 包含所有新路由且不包含旧路由
## 12. 集成测试(越权防护)
- [x] 12.1 创建 `tests/integration/account_permission_test.go`
- [x] 12.2 测试场景:企业账号访问账号管理接口被路由层拦截(返回 403
- [x] 12.3 测试场景:代理账号创建自己店铺的账号成功
- [x] 12.4 测试场景:代理账号创建下级店铺的账号成功
- [x] 12.5 测试场景:代理账号创建其他店铺的账号失败(返回 403
- [x] 12.6 测试场景:代理账号创建平台账号失败(返回 403
- [x] 12.7 测试场景:平台账号创建任意类型账号成功
- [x] 12.8 测试场景:超级管理员创建任意类型账号成功
- [x] 12.9 测试场景:查询不存在的账号返回"无权限操作该资源或资源不存在"
- [x] 12.10 测试场景:查询越权的账号返回相同错误消息
- [x] 12.11 运行 `source .env.local && go test -v ./tests/integration/account_permission_test.go` 验证所有测试通过
## 13. 集成测试(审计日志)
- [x] 13.1 创建 `tests/integration/account_audit_test.go`
- [x] 13.2 测试场景:创建账号时记录审计日志(验证 operation_type=create包含 after_data
- [x] 13.3 测试场景:更新账号时记录 before_data 和 after_data
- [x] 13.4 测试场景:删除账号时记录审计日志(验证 operation_type=delete
- [x] 13.5 测试场景:分配角色时记录审计日志(验证 operation_type=assign_roles
- [x] 13.6 测试场景:移除角色时记录审计日志(验证 operation_type=remove_role
- [x] 13.7 测试场景审计日志包含完整的操作上下文operator_id、target_account_id、request_id、ip_address
- [x] 13.8 测试场景:审计日志写入失败不影响业务操作(模拟数据库写入失败)
- [x] 13.9 运行 `source .env.local && go test -v ./tests/integration/account_audit_test.go` 验证所有测试通过
## 14. 回归测试(扩展现有测试)
- [x] 14.1 更新 `tests/integration/account_test.go`扩展覆盖所有账号类型platform/shop/enterprise
- [x] 14.2 测试场景:平台账号 CRUD 操作(原有功能保持)
- [x] 14.3 测试场景:代理账号 CRUD 操作(新增)
- [x] 14.4 测试场景:企业账号 CRUD 操作(新增)
- [x] 14.5 测试场景:角色管理功能对所有账号类型生效(新增)
- [x] 14.6 删除 `tests/integration/platform_account_test.go`(与 account_test.go 重复)
- [x] 14.7 删除 `tests/integration/shop_account_management_test.go`(功能已合并到 account_test.go
- [x] 14.8 运行 `source .env.local && go test -v ./tests/integration/account_test.go` 验证所有测试通过
## 15. 性能测试(已跳过 - 用户决定)
- [ ] ~~15.1 验证权限检查GetSubordinateShopIDs缓存命中率 > 80%~~
- [ ] ~~15.2 验证审计日志异步写入不阻塞主流程API 响应时间增加 < 1ms~~
- [ ] ~~15.3 压力测试100 并发创建账号请求P95 响应时间 < 200ms~~
- [ ] ~~15.4 压力测试100 并发查询账号列表请求P95 响应时间 < 200ms~~
- [ ] ~~15.5 验证审计日志写入性能1000 条/秒,数据库无明显压力)~~
## 16. 文档更新
- [x] 16.1 创建 `docs/account-management-refactor/迁移指南.md`(新旧路由映射表)
- [x] 16.2 创建 `docs/account-management-refactor/功能总结.md`(重构内容、安全提升、操作审计说明)
- [x] 16.3 创建 `docs/account-management-refactor/API文档.md`(所有新接口的请求/响应示例)
- [x] 16.4 更新 `README.md`:添加账号管理重构说明链接
- [x] 16.5 更新 `AGENTS.md`:添加越权防护和审计日志使用规范
## 17. 部署准备
- [ ] 17.1 生成生产环境数据库迁移脚本(包含 CREATE TABLE 和索引)
- [ ] 17.2 编写回滚方案文档(代码回滚步骤 + 数据库回滚脚本)
- [ ] 17.3 准备灰度发布计划(先部署后端,等前端更新后再切流量)
- [ ] 17.4 准备监控告警规则API 错误率 > 5%、P95 响应时间 > 300ms 自动告警)
- [ ] 17.5 编写前端对接会议 PPTBreaking Changes 说明、新旧路由映射、迁移时间表)