-
Notifications
You must be signed in to change notification settings - Fork 0
feat(player): implement unified player entity feature with core CRUD and authorization #267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Phase 0: Research & Technical Decisions
- Evaluate string vs numeric enums (chose string for Prisma compatibility)
- Define SWR + useSWRMutation integration strategy
- Design Zod schemas compatible with future Prisma migration
- Plan MongoDB indexing strategy with partial filters
- Document role conversion mapping (0→MEMBER, 1→OWNER, 2→ADMIN)
Phase 1: Design Artifacts
- Complete data model with TypeScript, Mongoose, and Zod schemas
- Player entity with state machine (INVITED/JOINED/PURE_PLAYER)
- Role transition rules (MEMBER/ADMIN/OWNER) with permissions
- Migration mapping from Member collection and Team.members[]
- OpenAPI 3.1 specification with 7 RESTful endpoints
- JSON Schema definitions for type generation
- Postman collection with 17 test cases
- Implementation quickstart guide (5-7 day roadmap)
API Endpoints:
- GET/DELETE /api/players/{playerId}
- PATCH /api/players/{playerId}/info (no notifications)
- PATCH /api/players/{playerId}/role (triggers notification)
- PATCH /api/players/{playerId}/status (discriminated union: invite/accept/reject/cancel/leave)
- GET/POST /api/teams/{teamId}/players
- GET /api/users/{userId}/players
Constitution Check: ✅ ALL PASS
- MVP First: P1 features independently deliverable
- TDD: Complete test strategy with 85%+ coverage goals
- Quality First: Type-safe, indexed, RESTful best practices
- Chinese Docs: All design docs in zh-TW
- Clean Architecture: Dependency direction enforced
Updated agent context with feature tech stack.
Ready for Phase 2 implementation.
Generate comprehensive task list (128 tasks) organized by User Story: - Phase 1: Setup (3 tasks) - Initialize Player infrastructure - Phase 2: Foundational (13 tasks) - Core entity, schema, repository, auth - Phase 3-9: User Stories (78 tasks) - Seven P1-P3 stories with TDD workflow - Phase 10: Migration (17 tasks) - Data migration and legacy code cleanup - Phase 11: Polish (9 tasks) - Optimization and cross-cutting concerns Key highlights: - All 128 tasks follow strict checklist format with Task IDs, [P] parallelization markers, and [Story] labels - MVP scope: Phase 1-5 (57 tasks) covers US1-US3 core functionality - ~60% of tasks marked [P] for parallel execution within phases - Each User Story includes independent test criteria and TDD Red/Green phases - Foundational phase (Phase 2) blocks all User Stories to ensure architecture stability - Clear checkpoint validation at each phase boundary Format improvements: - Markdown table alignment in data-model.md for readability - Consistent backtick escaping in quickstart.md for code examples - Research.md formatting updates for clarity
…astructure Setup: - T001: Create Player-related directory structure for entities, applications, infrastructure, API routes, validations, hooks, and components - T002: Register PlayerRepository and all Player use case types in DI container (types.ts) - T003: Confirm test environment is properly configured with MongoDB mocks Changes: - src/entities/player.ts: Define unified Player entity with status inference functions - src/entities/__tests__/player.test.ts: Complete unit tests for getPlayerStatus, canManageTeam, isOwner - src/infrastructure/di/types.ts: Register 13 new Player-related DI symbols - specs/001-unify-player/tasks.md: Mark T001-T003 as complete Verification: ✓ All 12 tests pass ✓ No TypeScript errors ✓ ESLint passes for new files ✓ Ready for Phase 2 (Foundational)
…pository foundational layer Phase 2.1 Completion (Entity & Validation & Database): - T004: Create unified Player entity with getPlayerStatus, canManageTeam, isOwner helper functions - T005: Complete unit tests for Player entity (12 passing tests) - T006: Create Zod validation schemas for Player operations (CreatePlayer, UpdatePlayerInfo, UpdatePlayerRole, UpdatePlayerStatus) - T007: Complete validation tests with discriminated union coverage (37 passing tests) - T008: Create Mongoose Player schema with proper indices (teamId, userId, email, composite unique index on teamId+email) - T009: Create model method tests for PlayerModel - T010: Define IPlayerRepository interface with complete CRUD and query methods - T011: Implement PlayerRepository with all 11 required methods - T012: Complete PlayerRepository unit tests with mocked PlayerModel (24 passing tests) Changes: - src/entities/player.ts: Define Player type and utility functions - src/entities/__tests__/player.test.ts: 12 tests for entity and helpers - src/lib/validations/player.ts: Complete Zod schema definitions - src/lib/validations/__tests__/player.test.ts: 37 validation tests - src/infrastructure/db/mongoose/schemas/player.ts: Define Mongoose schema with indices - src/infrastructure/db/mongoose/schemas/__tests__/player.test.ts: Model method tests - src/applications/repositories/player.repository.interface.ts: IPlayerRepository interface - src/infrastructure/db/repositories/player.repository.ts: PlayerRepository implementation - src/infrastructure/db/repositories/__tests__/player.repository.test.ts: 24 repository tests - jest.setup.ts: Enhanced Mongoose mock with virtual(), virtualpath(), countDocuments, getIndexes() - specs/001-unify-player/tasks.md: Mark T004-T012 as complete Verification: ✓ 73 tests passing ✓ No TypeScript errors ✓ No new ESLint errors ✓ Ready to proceed to Authorization Service and DI Container registration
…iner integration Phase 2.2 Completion (Authorization Service Update & DI): - T013: Extend IAuthorizationService with Player-specific permission methods - verifyIsTeamAdmin: Check if user is admin or owner - verifyIsTeamOwner: Check if user is team owner - verifyPlayerRole: Verify user has specific player role - getPlayerRole: Get user's role in a team - T014: Update AuthorizationService implementation to use PlayerRepository - T015: Complete authorization service tests with 14 passing tests - T016: Register PlayerRepository in DI container (inversify.config.ts) Changes: - src/applications/services/auth/authorization.service.interface.ts: Add 4 new Player permission methods - src/infrastructure/services/auth/authorization.service.ts: Implement new methods using PlayerRepository - src/infrastructure/services/auth/__tests__/authorization.service.test.ts: 14 comprehensive tests - src/infrastructure/di/inversify.config.ts: Register PlayerRepository binding - specs/001-unify-player/tasks.md: Mark T013-T016 as complete Verification: ✓ 14 authorization tests passing ✓ All 248 tests still passing (no regressions) ✓ Phase 2 (Foundational) complete - User Stories can now proceed in parallel
…T032-T038, T043-T050) Implement 6 core use case interfaces and implementations: US1 (Invite Members): - CreateInvitationUseCase: Invite users by email with role assignment - GetUserPlayersUseCase: Retrieve all teams/players for a user US2 (Accept/Reject Invitations): - AcceptInvitationUseCase: Accept pending invitations (INVITED → JOINED) - RejectInvitationUseCase: Reject pending invitations (INVITED → PURE_PLAYER) US3 (View Team Members): - GetTeamPlayersUseCase: Retrieve all players in a team - GetPlayerUseCase: Retrieve single player by ID All 6 use case test files created with comprehensive test coverage (31 tests): - 7 tests for CreateInvitation (success, auth, validation, duplicates) - 6 tests for GetUserPlayers (multiple teams, empty results, roles) - 4 tests for AcceptInvitation (success, not found, status conversion) - 5 tests for RejectInvitation (success, not found, role preservation) - 4 tests for GetTeamPlayers (multiple types, empty teams) - 5 tests for GetPlayer (found, not found, status variations) Status: 248 tests passing, 0 failures MVP business logic layer complete, ready for API route implementations
…9-T020, T025-T026)
Implement API route handlers for Player management:
US1 Integration Tests (T019-T020):
- POST /api/teams/{teamId}/players (create invitation)
- Email validation, role validation, authentication, response structure
- Status codes: 201 (success), 401 (unauthorized), 403 (forbidden), 409 (conflict)
- GET /api/users/{userId}/players (list user players)
- User isolation, pending invitations, mixed role statuses
- Status codes: 200 (success), 401 (unauthorized), 403 (forbidden)
API Route Implementations (T025-T026):
- POST /api/teams/{teamId}/players (T025)
- Validates email format (Zod)
- Verifies authentication
- Calls CreateInvitationUseCase via DI container
- Returns 201 with playerId on success
- Proper error handling with status codes
- GET /api/teams/{teamId}/players (T025)
- Authenticates user
- Calls GetTeamPlayersUseCase
- Returns array of players with validation
- GET /api/users/{userId}/players (T026)
- Verifies authentication
- Prevents cross-user data access (403)
- Calls GetUserPlayersUseCase
- Returns array of player records
DI Container Updates:
- Registered all 6 player use cases in inversify.config.ts
- Imported use case implementations from unified player index
Status: 319 tests passing, 0 failures
API contract verified, ready for UI components (hooks and React components)
…T046, T051-T052)
Implement remaining API route handlers for Player management:
US2 Integration Tests (T034):
- PATCH /api/players/{playerId}/status
- Action validation (accept, reject, leave, cancel)
- Status transitions (INVITED → JOINED, INVITED → PURE_PLAYER)
- Field preservation (email, role)
- Error handling for invalid states
US2 API Route Implementation (T039):
- PATCH /api/players/{playerId}/status
- Action-based routing (accept → AcceptInvitationUseCase, reject → RejectInvitationUseCase)
- Proper status codes (200 success, 404 not found, 409 conflict)
- Placeholder implementations for leave and cancel (T085-T095)
US3 Integration Tests (T045-T046):
- GET /api/teams/{teamId}/players
- Returns array of all player types (joined, invited, pure)
- Includes optional fields (number, position)
- Handles empty teams and large lists
- GET /api/players/{playerId}
- Single player retrieval
- All player types (JOINED, INVITED, PURE_PLAYER)
- Proper error handling (404 not found)
US3 API Route Implementations (T051-T052):
- GET /api/teams/{teamId}/players (already in T025)
- GET /api/players/{playerId}
- Authenticates user
- Calls GetPlayerUseCase
- Returns single player with validation
- 404 when player not found
Status: 365 tests passing (+46 new tests), 0 failures
All MVP API contracts defined and tested
Ready for UI integration (React hooks and components)
…4, T039, T045-T046, T051-T052)
Fix DI container binding error by exporting use case implementation classes alongside their interfaces. Use 'export type' for interfaces to satisfy TypeScript isolatedModules requirement. - Export all 6 use case implementations - Use 'export type' for interface exports - Fixes runtime TypeError in inversify.config.ts Status: 365 tests passing, dev server now starts correctly
- Fix Next.js 16 breaking change: params is now Promise in API routes - Fix Better Auth server-side authentication using auth.api.getSession - Fix ZodError property: use .issues instead of .errors - Fix Mongoose schema: replace duplicate $ne with $nin operator - Fix model overwrite error: use mongoose.models pattern for hot reload - Implement ObjectId to string conversion in PlayerRepository - Standardize all imports to use @ alias absolute paths - Use import type for interface imports throughout use cases - Export implementation classes alongside interfaces in index - Fix TypeScript errors: remove unused imports and explicit any types - Add PlayerDocument interface for virtual field type safety All tests passing (365), build successful, TypeScript checks clean
…027-T031) - T027: Create PlayerController with invitation-related methods * Delegates to use cases via DI container * Methods: createInvitation, acceptInvitation, rejectInvitation, getUserPlayers, getTeamPlayers, getPlayer - T028: Create useUserPlayers SWR hook for fetching user invitations * Implements SWR pattern with cache and deduping * Includes usePlayerStatusMutation for accept/reject operations * Includes useTeamPlayers and usePlayerDetail helper hooks - T029: Create InviteAccordion component for inviting members * Form with email input and role selection * Error handling and loading states * Callback on successful invitation - T030: Create RoleSelect component for choosing player roles * Reusable dropdown for MEMBER and ADMIN roles * Integrated with Shadcn/UI Select component - T031: Write comprehensive InviteAccordion component tests * Tests for rendering, form interaction, and submission * Error handling and loading state verification * 8 passing tests covering all functionality All tests passing (373 passed, 36 skipped) Build successful TypeScript types verified
… invitations (T040-T042) - T040: usePlayerStatusMutation hook already implemented in Phase 3 * Provides updatePlayerStatus function for accept/reject/cancel/leave actions * Implements SWR cache revalidation on status changes * Integrated into use-players.ts - T041: Create InvitationList component for displaying pending invitations * Filters and shows only INVITED status players * Displays role badges and invitation details * Accept/Reject buttons with loading states * Empty state when no pending invitations - T042: Write comprehensive InvitationList component tests * Tests for empty state, list rendering, and filtering * Tests for role display and email information * Tests for accept/reject button interactions * Tests for multiple invitations and loading states * 11 passing tests covering all functionality All tests passing (384 passed, 36 skipped) Build successful TypeScript types verified
…s (T053-T057) - T053: useTeamPlayers hook already implemented in Phase 3 * Provides players data for a specific team * Includes usePlayerDetail for individual player information * Integrated into use-players.ts - T054: Create PlayerCard component for displaying player information * Shows player name, number, position, and status badges * Displays role (MEMBER, ADMIN, OWNER) with visual distinction * Shows user ID or email information as applicable * Includes action buttons: Edit, Promote, Remove (when canManage=true) * Handles loading states and permission checks - T055: Create PlayerList component with filtering functionality * Grid layout for responsive player display * Search by player name (case-insensitive) * Filter by position (OH, MB, OP, S, L) * Filter by status (JOINED, INVITED, PURE_PLAYER) * Clear filters button and result summary * Delegates player actions to PlayerCard components * Empty state handling - T056: Write comprehensive PlayerCard component tests * Tests for basic rendering and information display * Tests for role badges and status indicators * Tests for management functionality (edit, promote, remove) * Tests for loading states and permission checks * 17 passing tests covering all functionality - T057: Write comprehensive PlayerList component tests * Tests for rendering all players and empty states * Tests for search functionality (case-insensitive) * Tests for position and status filtering * Tests for clearing filters * Tests for multiple simultaneous filters * Tests for management features integration * 11 passing tests covering all functionality All tests passing (412 passed, 36 skipped) Build successful TypeScript types verified MVP Core Features (US1-US3) Complete: - US1: Invite members to team ✓ - US2: Accept/reject invitations ✓ - US3: View team member list ✓
…r lookup Replace inefficient N+1 query pattern (fetching all players then filtering) with direct database queries using new findByTeamIdAndUserId method. Changes: - Add findByTeamIdAndUserId to IPlayerRepository interface for direct lookups - Implement findByTeamIdAndUserId in PlayerRepository with single MongoDB findOne - Refactor verifyIsTeamAdmin to use direct query instead of fetch-all-then-filter - Refactor verifyPlayerRole to use direct query for better performance - Refactor getPlayerRole to use direct query instead of filtering in code - Update authorization service tests to mock new method This improves database efficiency and eliminates unused variable warnings.
…ypes - Updated PlayerDocument interface to use Types.ObjectId for teamId field instead of string - Added proper type parameters to Mongoose Schema and model declarations following team.ts pattern - Changed from generic mongoose.Schema() to Schema<PlayerDocument>() for proper type inference - Updated PlayerModel export to use model<PlayerDocument>() for type safety - Fixed player.repository.ts to import and use PlayerDocument type from schema - This resolves type incompatibility issues that arose when converting imports to absolute paths (@/) All tests pass (412/412), build succeeds, and TypeScript errors for player files are resolved.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @andrewck24's task —— View job PR Review: Unified Player Entity ImplementationComprehensive review of this large-scale Player entity refactoring implementing Clean Architecture with 3 priority user stories. Review Checklist
✅ Strengths & Excellent Implementation1. Clean Architecture Excellence
2. Type Safety & Validation
3. State Machine Design (
|
| Category | Score | Notes |
|---|---|---|
| Architecture | 🟢 9/10 | Excellent Clean Architecture implementation |
| Type Safety | 🟢 9/10 | Outstanding Zod + TypeScript integration |
| Performance | 🟡 7/10 | Good queries, needs indexes |
| Security | 🟡 6/10 | Basic validation needs improvement |
| Test Coverage | 🟢 9/10 | Comprehensive 412 tests |
| Code Quality | 🟢 8/10 | Clean, well-structured code |
✅ Approval Recommendation
APPROVE WITH CONDITIONS: This is an excellent implementation of Clean Architecture with strong type safety and comprehensive testing. The identified security and performance issues should be addressed before merging to production, but they don't block the architectural foundation this PR establishes.
Critical fixes required: Email validation and role authorization security improvements.
…hases - Insert new Phase 5.5: MVP Hotfixes & Code Quality with critical security fixes (T058-T061) - Email validation using Zod schema - Owner-only protection for OWNER role assignment - Missing database indexes (teamId+userId, teamId+email, teamId+role) - Replace duplicate existsInvitation() method - Renumber Phase 6 (US4) from T058-T064 to T062-T068 - Renumber Phase 7 (US5) from T065-T076 to T069-T080 - Renumber Phase 8 (US6) from T077-T090 to T081-T094 - Phase 9-11 require manual renumbering (sed replacement caused duplicates, will fix separately) - Total task count increases from 128 to 132 tasks
T058: Replace basic email validation with Zod schema validation
- Replaced string.includes('@') with Zod's email().parse()
- Ensures proper email format validation and injection prevention
T059: Add owner-only protection for OWNER role assignment
- Only OWNER can assign OWNER role to new invitations
- Prevents privilege escalation attacks
- Added comprehensive tests for both OWNER and non-OWNER scenarios
T060: Add missing MongoDB indexes for query optimization
- Added composite index on (teamId, role) for efficient role queries
- Already had (teamId, userId) and (teamId, email) indices
- Improves query performance for team member lookups
T061: Replace existsInvitation() call with findInvitedByTeamIdAndEmail()
- Direct query is more efficient than existence check
- Eliminates duplicate query logic
- Reduces database calls in create invitation flow
All 414 tests passing with new OWNER role protection tests included.
|
Claude finished @andrewck24's task —— View job PR Review: Unified Player Entity ImplementationComprehensive review of this large-scale Player entity refactoring implementing Clean Architecture with 3 priority user stories. Review Checklist
✅ Strengths & Excellent Implementation1. Clean Architecture Excellence
2. Type Safety & Validation
3. State Machine Design (
|
| Category | Score | Notes |
|---|---|---|
| Architecture | 🟢 9/10 | Excellent Clean Architecture implementation |
| Type Safety | 🟢 9/10 | Outstanding Zod + TypeScript integration |
| Performance | 🟡 7/10 | Good queries, needs indexes |
| Security | 🟡 6/10 | Basic validation needs improvement |
| Test Coverage | 🟢 9/10 | Comprehensive 412 tests |
| Code Quality | 🟢 8/10 | Clean, well-structured code |
✅ Approval Recommendation
APPROVE WITH CONDITIONS: This is an excellent implementation of Clean Architecture with strong type safety and comprehensive testing. The identified security and performance issues should be addressed before merging to production, but they don't block the architectural foundation this PR establishes.
Critical fixes required: Email validation and role authorization security improvements.
Summary
Completes the unified Player entity refactoring as specified in
specs/001-unify-player/spec.md. This PR implements the foundational infrastructure and three priority-1 user stories (US1-US3) with complete test coverage, API routes, and React components.Completed Components
Phase 1-2: Foundational Infrastructure ✅
Phase 3-5: User Stories 1-3 Implementation ✅
API Routes ✅
React Components ✅
Key Technical Improvements
Query Optimization
findByTeamIdAndUserId()instead of fetch-all-then-filterType Safety
Schema<PlayerDocument>()type parametersTypes.ObjectIdusage instead ofanyjest.Mocked<T>for test mocksArchitecture
Test Coverage
Code Quality
@/absolute pathsTasks Completed
Total: 57/128 tasks completed (44.5%)
Remaining tasks (71) are for US4-US7 which are not in scope for this MVP.
Breaking Changes
Migration Path
摘要
實現統一 Player 實體功能,完成 MVP 三個優先級 P1 使用者故事 (US1-US3)。
核心功能
技術亮點
Types.ObjectId,無any型別進度