主要功能: - 实现完整的 RBAC 权限系统(账号、角色、权限的多对多关联) - 基于 owner_id + shop_id 的自动数据权限过滤 - 使用 PostgreSQL WITH RECURSIVE 查询下级账号 - Redis 缓存优化下级账号查询性能(30分钟过期) - 支持多租户数据隔离和层级权限管理 技术实现: - 新增 Account、Role、Permission 模型及关联关系表 - 实现 GORM Scopes 自动应用数据权限过滤 - 添加数据库迁移脚本(000002_rbac_data_permission、000003_add_owner_id_shop_id) - 完善错误码定义(1010-1027 为 RBAC 相关错误) - 重构 main.go 采用函数拆分提高可读性 测试覆盖: - 添加 Account、Role、Permission 的集成测试 - 添加数据权限过滤的单元测试和集成测试 - 添加下级账号查询和缓存的单元测试 - 添加 API 回归测试确保向后兼容 文档更新: - 更新 README.md 添加 RBAC 功能说明 - 更新 CLAUDE.md 添加技术栈和开发原则 - 添加 docs/004-rbac-data-permission/ 功能总结和使用指南 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
25 KiB
Tasks: RBAC 表结构与 GORM 数据权限过滤
Input: Design documents from /specs/004-rbac-data-permission/
Prerequisites: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/
Tests: REQUIRED per Constitution - Testing Standards (spec.md includes testing requirements)
Organization: Tasks are grouped by user story to enable independent implementation and testing of each story.
Format: [ID] [P?] [Story] Description
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions
Path Conventions
- Single project:
internal/,pkg/,cmd/,migrations/,tests/at repository root - Paths follow the project structure defined in plan.md
Phase 1: Setup (Shared Infrastructure)
Purpose: Project initialization and RBAC-specific infrastructure
- T001 Add RBAC-related error codes (账号、角色、权限相关) in pkg/errors/codes.go
- T002 [P] Add Redis key generation function for subordinates cache in pkg/constants/redis.go
- T003 [P] Add RBAC business constants (user types, role types, permission types, status) in pkg/constants/constants.go
- T004 [P] Create Store query options structure with WithoutDataFilter option in internal/store/options.go
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Core RBAC infrastructure that MUST be complete before ANY user story can be implemented
⚠️ CRITICAL: No user story work can begin until this phase is complete
Context Helper Functions
- T005 Define context key types and constants (UserIDKey, UserTypeKey, ShopIDKey) in pkg/middleware/auth.go
- T006 [P] Implement SetUserContext function (sets user ID, user type, shop ID to context) in pkg/middleware/auth.go
- T007 [P] Implement GetUserIDFromContext function (extracts user ID from context) in pkg/middleware/auth.go
- T008 [P] Implement GetShopIDFromContext function (extracts shop ID from context) in pkg/middleware/auth.go
- T009 [P] Implement IsRootUser function (checks if user is root type) in pkg/middleware/auth.go
Route Module Structure
- T010 Create routes registry structure and Services container in internal/routes/routes.go
- T011 [P] Create health check routes in internal/routes/health.go
- T012 [P] Create task routes in internal/routes/task.go
Checkpoint: Foundation ready - user story implementation can now begin
Phase 3: User Story 1 - 数据库表结构和GORM模型定义 (Priority: P1) 🎯 MVP
Goal: Create 5 RBAC database tables and corresponding GORM models with soft delete and hierarchy support
Independent Test: Run database migrations, verify table structures, create test data via GORM to validate models
Database Migrations for User Story 1
- T013 [US1] Create RBAC tables migration file migrations/000002_rbac_data_permission.up.sql
- T014 [US1] Define accounts table in migration (id, username, phone, password, user_type, shop_id, parent_id, status, creator, updater, timestamps)
- T015 [US1] Add indexes for accounts table (unique: username, phone; normal: user_type, shop_id, parent_id, deleted_at)
- T016 [US1] Define roles table in migration (id, role_name, role_desc, role_type, status, creator, updater, timestamps)
- T017 [US1] Add indexes for roles table (role_type, deleted_at)
- T018 [US1] Define permissions table in migration (id, perm_name, perm_code, perm_type, url, parent_id, sort, status, creator, updater, timestamps)
- T019 [US1] Add indexes for permissions table (unique: perm_code; normal: perm_type, parent_id, deleted_at)
- T020 [US1] Define account_roles table in migration (id, account_id, role_id, status, creator, updater, timestamps)
- T021 [US1] Add indexes for account_roles table (account_id, role_id, deleted_at, unique: account_id+role_id WHERE deleted_at IS NULL)
- T022 [US1] Define role_permissions table in migration (id, role_id, perm_id, status, creator, updater, timestamps)
- T023 [US1] Add indexes for role_permissions table (role_id, perm_id, deleted_at, unique: role_id+perm_id WHERE deleted_at IS NULL)
- T024 [P] [US1] Create rollback migration migrations/000002_rbac_data_permission.down.sql
- T025 [P] [US1] 🔮 (未来功能) Create data_transfer_log table migration migrations/000004_data_transfer_log.up.sql
- T026 [P] [US1] 🔮 (未来功能) Create data_transfer_log rollback migration migrations/000004_data_transfer_log.down.sql
GORM Models for User Story 1
- T027 [P] [US1] Create Account model with GORM tags (password uses json:"-") in internal/model/account.go
- T028 [P] [US1] Create Account DTO structures in internal/model/account_dto.go
- T029 [P] [US1] Create Role model with GORM tags in internal/model/role.go
- T030 [P] [US1] Create Role DTO structures in internal/model/role_dto.go
- T031 [P] [US1] Create Permission model with GORM tags in internal/model/permission.go
- T032 [P] [US1] Create Permission DTO structures in internal/model/permission_dto.go
- T033 [P] [US1] Create AccountRole model (no ORM association tags) in internal/model/account_role.go
- T034 [P] [US1] Create AccountRole DTO structures in internal/model/account_role_dto.go
- T035 [P] [US1] Create RolePermission model (no ORM association tags) in internal/model/role_permission.go
- T036 [P] [US1] Create RolePermission DTO structures in internal/model/role_permission_dto.go
- T037 [P] [US1] 🔮 (未来功能) Create DataTransferLog model in internal/model/data_transfer_log.go
Store Layer for User Story 1
- T038 [US1] Create AccountStore with Create method in internal/store/postgres/account_store.go
- T039 [US1] Add GetByID, GetByUsername, GetByPhone methods to AccountStore in internal/store/postgres/account_store.go
- T040 [US1] Add Update and Delete (soft) methods to AccountStore in internal/store/postgres/account_store.go
- T041 [US1] Add List method with pagination and filters to AccountStore in internal/store/postgres/account_store.go
- T042 [P] [US1] Create RoleStore with CRUD methods in internal/store/postgres/role_store.go
- T043 [P] [US1] Create PermissionStore with CRUD methods in internal/store/postgres/permission_store.go
- T044 [P] [US1] Create AccountRoleStore with batch operations in internal/store/postgres/account_role_store.go
- T045 [P] [US1] Create RolePermissionStore with batch operations in internal/store/postgres/role_permission_store.go
- T046 [P] [US1] 🔮 (未来功能) Create DataTransferLogStore (append-only) in internal/store/postgres/data_transfer_log_store.go
Service Layer for User Story 1
- T047 [US1] Create Account service with Create method (validate params, check uniqueness, bcrypt password, set creator/updater) in internal/service/account/service.go
- T048 [US1] Add validation for non-root accounts requiring parent_id in Account service in internal/service/account/service.go
- T049 [US1] Add Get, Update (forbid parent_id/user_type change), Delete methods to Account service in internal/service/account/service.go
- T050 [US1] Add List method with pagination and filters to Account service in internal/service/account/service.go
- T051 [P] [US1] Create Role service with CRUD methods in internal/service/role/service.go
- T052 [P] [US1] Create Permission service with CRUD methods (validate perm_code uniqueness) in internal/service/permission/service.go
Handler Layer for User Story 1
- T053 [US1] Create Account handler with Create, Get, Update, Delete, List methods in internal/handler/account.go
- T054 [P] [US1] Create Role handler with Create, Get, Update, Delete, List methods in internal/handler/role.go
- T055 [P] [US1] Create Permission handler with Create, Get, Update, Delete, List methods in internal/handler/permission.go
Account-Role and Role-Permission Association
- T056 [US1] Add AssignRoles method to Account handler (POST /accounts/:id/roles) in internal/handler/account.go
- T057 [US1] Add GetRoles method to Account handler (GET /accounts/:id/roles) in internal/handler/account.go
- T058 [US1] Add RemoveRole method to Account handler (DELETE /accounts/:account_id/roles/:role_id) in internal/handler/account.go
- T059 [US1] Add AssignRoles, GetRoles, RemoveRole methods to Account service in internal/service/account/service.go
- T060 [P] [US1] Add AssignPermissions, GetPermissions, RemovePermission methods to Role handler in internal/handler/role.go
- T061 [P] [US1] Add AssignPermissions, GetPermissions, RemovePermission methods to Role service in internal/service/role/service.go
Routes for User Story 1
- T062 [US1] Create account routes with CRUD and role assignment endpoints in internal/routes/account.go
- T063 [P] [US1] Create role routes with CRUD and permission assignment endpoints in internal/routes/role.go
- T064 [P] [US1] Create permission routes with CRUD and tree query endpoints in internal/routes/permission.go
Tests for User Story 1
- T065 [P] [US1] Integration tests for database migrations in tests/integration/migration_test.go
- T066 [P] [US1] Unit tests for Account model CRUD operations in tests/unit/account_model_test.go
- T067 [P] [US1] Unit tests for soft delete operations in tests/unit/soft_delete_test.go
- T068 [P] [US1] Integration tests for Account API endpoints in tests/integration/account_test.go
- T069 [P] [US1] Integration tests for Role API endpoints in tests/integration/role_test.go
- T070 [P] [US1] Integration tests for Permission API endpoints in tests/integration/permission_test.go
- T071 [P] [US1] Integration tests for account-role association in tests/integration/account_role_test.go
- T072 [P] [US1] Integration tests for role-permission association in tests/integration/role_permission_test.go
Checkpoint: At this point, User Story 1 should be fully functional - RBAC tables created, models work with GORM soft delete
Phase 4: User Story 2 - GORM自动数据权限过滤 (Priority: P1)
Goal: Implement automatic data permission filtering based on owner_id + shop_id with recursive subordinate query and Redis caching
Independent Test: Create hierarchical user data, execute queries with different user identities, verify correct filtering results
Database Migrations for User Story 2
- T073 [US2] Create owner_id/shop_id fields migration template migrations/000003_add_owner_id_shop_id.up.sql (注:示例迁移,实际业务表由项目需求决定)
- T074 [US2] Add migration template showing how to add owner_id/shop_id to business tables with indexes (注:仅作为示例,user/order 表是之前的示例代码)
- T075 [P] [US2] Create rollback migration template migrations/000003_add_owner_id_shop_id.down.sql (注:示例迁移)
Recursive Subordinate Query Implementation
- T078 [US2] Add GetSubordinateIDs method with Redis cache check to AccountStore in internal/store/postgres/account_store.go
- T079 [US2] Implement PostgreSQL WITH RECURSIVE query for subordinate IDs (including soft-deleted) in internal/store/postgres/account_store.go
- T080 [US2] Implement Redis cache write (30min expiry) for subordinate IDs in internal/store/postgres/account_store.go
- T081 [US2] Add ClearSubordinatesCache method in internal/store/postgres/account_store.go
- T082 [US2] Add ClearSubordinatesCacheForParents method (recursive cache clearing) in internal/store/postgres/account_store.go
GORM Scopes Data Permission Filtering
- T083 [US2] Create DataPermissionScope function in internal/store/postgres/scopes.go
- T084 [US2] Implement context extraction (user ID, shop ID) in DataPermissionScope
- T085 [US2] Implement root user check (skip filtering) in DataPermissionScope
- T086 [US2] Call GetSubordinateIDs and apply WHERE owner_id IN (...) AND shop_id = ? in DataPermissionScope
- T087 [US2] Implement error handling (fallback to self data only) in DataPermissionScope
Apply Data Permission to Store Methods
- T088 [US2] Apply DataPermissionScope to AccountStore List and Get methods in internal/store/postgres/account_store.go (注:账号表本身是所有权表,无需 owner_id 过滤,DataPermissionScope 用于业务表)
- T089 [US2] Document how to apply DataPermissionScope to future business Store methods (注:user/order 是示例,实际业务 Store 由项目需求决定)
- T090 [US2] Ensure all Store methods accept context parameter for context propagation
Cache Clearing on Account Changes
- T092 [US2] Add cache clearing on account creation in Account service in internal/service/account/service.go
- T093 [US2] Add cache clearing on account soft deletion in Account service in internal/service/account/service.go
Auth Middleware Updates
- T094 [US2] Update Auth middleware to extract user ID, user type, shop ID from token in pkg/middleware/auth.go
- T095 [US2] Call SetUserContext to write user info to context in Auth middleware in pkg/middleware/auth.go
Tests for User Story 2
- T096 [P] [US2] Unit tests for GetSubordinateIDs recursive query in tests/unit/subordinate_query_test.go
- T097 [P] [US2] Unit tests for Redis cache read/write/clear in tests/unit/subordinate_cache_test.go
- T098 [P] [US2] Unit tests for DataPermissionScope in tests/unit/data_permission_scope_test.go
- T099 [P] [US2] Integration tests for data permission filtering with hierarchy in tests/integration/data_permission_test.go
- T100 [P] [US2] Integration tests for WithoutDataFilter option in tests/integration/data_permission_test.go
- T101 [P] [US2] Integration tests for cross-shop isolation in tests/integration/data_permission_test.go
Checkpoint: At this point, User Stories 1 AND 2 should both work - data permission filtering automatically applied
Phase 5: User Story 3 - 主函数重构和路由模块化 (Priority: P2)
Goal: Refactor main function into multiple init functions (≤100 lines), split routes into modular files under internal/routes/
Independent Test: Run application, verify all existing endpoints work correctly, check code structure
Main Function Refactoring
- T102 [US3] Create initConfig function (load config, return *config.Config) in cmd/api/main.go
- T103 [US3] Create initLogger function (init logger, return *zap.Logger) in cmd/api/main.go
- T104 [US3] Create initDatabase function (connect DB, return *gorm.DB) in cmd/api/main.go
- T105 [US3] Create initRedis function (connect Redis, return *redis.Client) in cmd/api/main.go
- T106 [US3] Create initQueue function (init Asynq, return *asynq.Client) in cmd/api/main.go
- T107 [US3] Create initServices function (init all Services, return *routes.Services) in cmd/api/main.go
- T108 [US3] Create initMiddleware function (register global middleware) in cmd/api/main.go
- T109 [US3] Create initRoutes function (register all routes, call routes.RegisterRoutes) in cmd/api/main.go
- T110 [US3] Create startServer function (start Fiber server) in cmd/api/main.go
- T111 [US3] Rewrite main function as orchestration only (≤100 lines) in cmd/api/main.go
Route Modularization
- T112 [US3] Define Services struct (all Service fields) in internal/routes/routes.go
- T113 [US3] Implement RegisterRoutes function (main entry, call module route functions) in internal/routes/routes.go
- T114 [US3] Document route modularization pattern for future business routes (注:user/order 是之前的示例,实际业务路由由项目需求决定)
- T115 [US3] Verify each route file is ≤100 lines with single responsibility
Tests for User Story 3
- T117 [P] [US3] Integration tests for all API endpoints after refactoring in tests/integration/api_regression_test.go
- T118 [P] [US3] Verify main function is ≤100 lines with code review (main函数42行,符合要求)
Checkpoint: All user stories should now be independently functional
Phase 6: Polish & Quality Gates
Purpose: Improvements that affect multiple user stories and final quality checks
Documentation (Constitution Principle VII - REQUIRED)
- T119 [P] Create feature summary doc in docs/004-rbac-data-permission/功能总结.md (Chinese filename and content)
- T120 [P] Create usage guide in docs/004-rbac-data-permission/使用指南.md (Chinese filename and content)
- T121 [P] Create architecture doc in docs/004-rbac-data-permission/架构说明.md (optional, Chinese filename and content)
- T122 Update README.md with brief feature description (2-3 sentences in Chinese)
Code Quality
- T123 Code cleanup and refactoring (测试文件已修复格式和编译错误)
- T124 Performance optimization (verify P95 < 200ms, P99 < 500ms, recursive query < 50ms)
- T125 [P] Additional unit tests to reach 70%+ coverage (90%+ for core business)
- T126 Security audit (bcrypt password hashing, SQL injection prevention)
- T127 Run quickstart.md validation with test scenarios
- T128 Quality Gate: Run
go test ./...(pkg 测试全部通过,unit 测试通过,internal 测试需要数据库) - T129 Quality Gate: Run
gofmt -l .(no formatting issues) - T130 Quality Gate: Run
go vet ./...(no issues - requires go mod tidy first) - T131 Quality Gate: Run
golangci-lint run(主要 errcheck 问题已修复,仅剩少量 staticcheck 建议和废弃 API 警告) - T132 Quality Gate: Verify test coverage with
go test -cover ./...(pkg 包覆盖率良好,部分单元测试失败需要 Redis 环境) - T133 Quality Gate: Check no TODO/FIXME remains (or documented in issues)
- T134 Quality Gate: Verify database migrations work correctly (up and down)
- T135 Quality Gate: Verify API documentation updated (contracts/ match implementation)
- T136 Quality Gate: Verify no hardcoded constants or Redis keys (all use pkg/constants/)
- T137 Quality Gate: Verify no duplicate hardcoded values (3+ identical literals must be constants)
- T138 Quality Gate: Verify code comments use Chinese (implementation comments in Chinese)
- T139 Quality Gate: Verify log messages use Chinese (logger Info/Warn/Error/Debug in Chinese)
- T140 Quality Gate: Verify error messages support Chinese (user-facing errors have Chinese text)
- T141 Quality Gate: Verify no Java-style anti-patterns (no getter/setter, no I-prefix, no Impl-suffix)
- T142 Quality Gate: Verify Go naming conventions (UserID not userId, HTTPServer not HttpServer)
- T143 Quality Gate: Verify error handling is explicit (no panic/recover abuse)
- T144 Quality Gate: Verify uses goroutines/channels (not thread pool patterns)
- T145 Quality Gate: Verify feature summary docs created in docs/004-rbac-data-permission/ with Chinese filenames
- T146 Quality Gate: Verify ALL HTTP requests logged to access.log (no exceptions)
- T147 Quality Gate: Verify access log includes all required fields
- T148 Quality Gate: Verify all API errors use unified JSON format (pkg/errors/ ErrorHandler)
- T149 Quality Gate: Verify Handler layer returns errors (no manual c.Status().JSON() for errors)
- T150 Quality Gate: Verify business errors use pkg/errors.New() or pkg/errors.Wrap()
- T151 Quality Gate: Verify all error codes defined in pkg/errors/codes.go
- T152 Quality Gate: Verify Recover middleware catches all panics
- T153 Quality Gate: Verify no foreign key constraints in migrations (Constitution Principle IX)
- T154 Quality Gate: Verify no GORM association tags (Constitution Principle IX)
- T155 Quality Gate: Verify password field excluded from JSON responses (json:"-" tag)
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): No dependencies - can start immediately
- Foundational (Phase 2): Depends on Setup completion - BLOCKS all user stories
- User Stories (Phase 3+): All depend on Foundational phase completion
- User Story 1 (US1) and User Story 2 (US2) are both P1 priority
- US2 depends on US1 completion (needs account models and stores)
- User Story 3 (US3) can start after US1 but benefits from US2 completion
- Polish (Phase 6): Depends on all desired user stories being complete
User Story Dependencies
- User Story 1 (P1): Can start after Foundational (Phase 2) - No dependencies on other stories
- User Story 2 (P1): Depends on US1 completion (uses AccountStore for GetSubordinateIDs)
- User Story 3 (P2): Can start after US1, should integrate US2 components
Within Each User Story
- Migrations before models
- Models before stores
- Stores before services
- Services before handlers
- Handlers before routes
- Tests can run in parallel with implementation but verify after
Parallel Opportunities
Phase 1 (Setup):
- T002, T003, T004 can run in parallel
Phase 2 (Foundational):
- T006-T009 (context helpers) can run in parallel
- T011, T012 (routes) can run in parallel
Phase 3 (US1):
- T024-T026 (rollback migrations) can run in parallel
- T027-T037 (GORM models) can run in parallel
- T042-T046 (stores except AccountStore) can run in parallel
- T51, T052 (services except Account) can run in parallel
- T054, T055 (handlers except Account) can run in parallel
- T060, T061 (role association methods) can run in parallel
- T063, T064 (routes except account) can run in parallel
- T065-T072 (tests) can run in parallel
Phase 4 (US2):
- T075, T077 (model updates) can run in parallel
- T089, T090 (apply scope) can run in parallel
- T096-T101 (tests) can run in parallel
Phase 5 (US3):
- T114, T115 (route files) can run in parallel
- T117, T118 (tests) can run in parallel
Phase 6 (Polish):
- T119-T121 (documentation) can run in parallel
- Most quality gates can run in parallel
Parallel Example: Phase 3 Models
# Launch all GORM models together:
Task T027: "Create Account model with GORM tags in internal/model/account.go"
Task T028: "Create Account DTO structures in internal/model/account_dto.go"
Task T029: "Create Role model with GORM tags in internal/model/role.go"
Task T030: "Create Role DTO structures in internal/model/role_dto.go"
Task T031: "Create Permission model with GORM tags in internal/model/permission.go"
Task T032: "Create Permission DTO structures in internal/model/permission_dto.go"
Task T033: "Create AccountRole model in internal/model/account_role.go"
Task T035: "Create RolePermission model in internal/model/role_permission.go"
Task T037: "Create DataTransferLog model in internal/model/data_transfer_log.go"
Implementation Strategy
MVP First (User Stories 1 + 2)
- Complete Phase 1: Setup
- Complete Phase 2: Foundational (CRITICAL - blocks all stories)
- Complete Phase 3: User Story 1 (RBAC tables and CRUD)
- Complete Phase 4: User Story 2 (Data permission filtering)
- STOP and VALIDATE: Test both stories independently
- Deploy/demo if ready - Core RBAC system functional
Incremental Delivery
- Complete Setup + Foundational → Foundation ready
- Add User Story 1 → Test independently → RBAC tables and CRUD working
- Add User Story 2 → Test independently → Data filtering working (MVP!)
- Add User Story 3 → Test independently → Code refactored
- Each story adds value without breaking previous stories
Parallel Team Strategy
With multiple developers:
- Team completes Setup + Foundational together
- Once Foundational is done:
- Developer A: User Story 1 (models and CRUD)
- Developer B: Prepare User Story 2 tests (can start writing tests)
- Once US1 is done:
- Developer A: User Story 2 (data permission filtering)
- Developer B: User Story 3 (refactoring)
- Stories complete and integrate independently
Summary
Total Task Count: 150 tasks (已移除 user/order 示例相关任务)
Task Count per User Story:
- Setup (Phase 1): 4 tasks
- Foundational (Phase 2): 8 tasks
- User Story 1 (Phase 3): 60 tasks
- User Story 2 (Phase 4): 26 tasks (移除了 T076, T077, T089, T090 合并)
- User Story 3 (Phase 5): 15 tasks (T114, T115 合并为 T114)
- Polish (Phase 6): 37 tasks
Parallel Opportunities: ~45 tasks marked [P]
Independent Test Criteria per Story:
- US1: Run migrations, verify tables, create test data, soft delete works
- US2: Hierarchical user data, query filtering, Redis cache
- US3: All endpoints work, main ≤100 lines, route files ≤100 lines
Suggested MVP Scope: Phase 1-4 (User Stories 1 + 2) = 98 tasks
Format Validation: ✅ ALL tasks follow checklist format (checkbox, ID, labels, file paths)
Notes
- [P] tasks = different files, no dependencies
- [Story] label maps task to specific user story for traceability
- Each user story should be independently completable and testable
- Verify tests fail before implementing
- Commit after each task or logical group
- Stop at any checkpoint to validate story independently
- US1 and US2 are both P1 priority but US2 depends on US1
- Avoid: vague tasks, same file conflicts, cross-story dependencies that break independence