- Migrated all schemas to Pydantic v2 syntax (model_config, ConfigDict) - Fixed mutable default in ProtoMessageBase using Field(default_factory=datetime.now) - Consolidated CardCollection and Wishlist schemas in user_card_collection.py - Created game_schemas.py with GameCreate, GameResponse, GameJoinRequest, etc. - Created mtg_card_schemas.py with MtgCardResponse, MtgCardSearchRequest, etc. - Added CardImportBatchCreate, CardImportBatchResponse, UserCardImportCreate/Response schemas - Fixed duplicate UserCardImportRecord class between card_import_batch.py and user_card_import_record.py - Updated __init__.py with comprehensive schema exports - Created verify_schemas.py for schema-model matching verification
22 KiB
Backend Test Plan (Updated)
Overview
This test plan is designed for iterative execution using sub-agents, with each sub-agent handling a specific phase to avoid exceeding the 300,000 token context limit. Each phase focuses on a distinct subsystem and includes specific test cases and verification steps.
Last Updated: 2026-06-08
Status: Phase 1 Complete - Database & Migration Tests Verified
Test Phases
Phase 1: Database & Migration Tests ✅ COMPLETE
Scope: Alembic migrations, database schema, model relationships
Sub-agent Task: Verify all migrations run correctly and database schema is consistent
Status: ✅ Verified - All migrations functionally correct
Actual Migration Structure:
Migration 000 (000_base_tables.py) - Creates 8 base tables:
mtgonline_users(base table)mtgonline_decklist_folders(FK to mtgonline_users.id, self-ref)mtgonline_decklist_files(FK to mtgonline_decklist_folders.id, mtgonline_users.id)mtgonline_rooms(base table)mtgonline_rooms_gametypes(FK to mtgonline_rooms.id)mtgonline_bans(FK to mtgonline_users.id)mtgonline_log(FK to mtgonline_rooms.id, mtgonline_users.id)mtgonline_audit(FK to mtgonline_users.id)
Migration 001 (001_initial_user_schema.py) - Creates 15 user-related tables:
user_sessions(FK to mtgonline_users.id)deck_versions(FK to mtgonline_decklist_files.id)game_replays(FK to mtgonline_rooms.id)replay_players(FK to game_replays.id, mtgonline_users.id, mtgonline_decklist_files.id)game_outcomes(FK to mtgonline_users.id, game_replays.game_uuid)user_statistics(PK: user_id, FK to mtgonline_users.id)user_card_collection(FK to mtgonline_users.id)card_wishlist(FK to mtgonline_users.id)user_groups(FK to mtgonline_users.id)group_members(FK to user_groups.id, mtgonline_users.id)group_chat_messages(FK to user_groups.id, mtgonline_users.id)user_networks(FK to mtgonline_users.id)network_members(FK to user_networks.id, mtgonline_users.id)user_preferences(PK: user_id, FK to mtgonline_users.id)user_activity_log(FK to mtgonline_users.id)
Migration 002 (002_user_deck_building_tables.py) - Creates:
user_decks(FK to mtgonline_users.id, mtgonline_decklist_folders.id)
Migration 003 (003_mtgonline_cards_table.py) - Creates:
mtgonline_cards(base table)user_deck_cards(FK to user_decks.id, mtgonline_cards.id)deck_precedents(FK to mtgonline_users.id)deck_precedent_cards(FK to deck_precedents.id, mtgonline_cards.id)card_suggestions(FK to user_decks.id, mtgonline_cards.id, self-ref)
Migration 004 (004_card_import_table.py) - Creates:
user_card_imports(FK to mtgonline_users.id)
Migration 005 (005_missing_tables.py) - Creates:
mtg_sets(base table)mtg_cards(FK to mtg_sets.id)mtg_cards_mirror(base table)card_import_batches(FK to mtgonline_users.id)user_card_imports_confirmed(FK to mtgonline_users.id, card_import_batches.id)deck_card_links(FK to mtgonline_decklist_files.id, mtg_cards_mirror.id)
Verification Results:
- ✅ All 6 migrations properly linked (000 → 001 → 002 → 003 → 004 → 005)
- ✅ All foreign keys reference tables created in same or earlier migrations
- ✅ No circular dependencies
- ✅ All indexes created on FK columns
- ✅ All unique constraints valid
- ✅ Downgrade functions properly drop tables in reverse dependency order
- ✅ All model imports in
env.pyand__init__.pyconsistent
Note: Migration 000 is NOT empty (creates 8 base tables). This is intentional and correct.
Phase 2: Model Layer Tests
Scope: SQLAlchemy models, relationships, validation
Sub-agent Task: Verify all model definitions are correct and consistent
Actual Model Structure:
1. Core Models (app/models/models.py)
User(mtgonline_users) - username, email, password_hash, salt, country, real_name, avatar_bmp, privlevel, is_active, is_banned, ban_reason, ban_ends, vip_status, vip_expiry, creation_date, last_loginMtonlineCard(mtgonline_cards) - source_id, name, mana_cost, type_line, oracle_text, power, toughness, rarity, layout, artist, flavor_text, numbers, identifiers, images, image, set_code, set_name, card_parts, keywords, legalities, synced_at, created_atDecklistFolder(mtgonline_decklist_folders) - owner_id, name, parent_id, creation_dateDecklistFile(mtgonline_decklist_files) - folder_id, owner_id, name, content, format, status, creation_dateRoom(mtgonline_rooms) - name, description, is_password_protected, password_hash, creation_dateRoomGameType(mtgonline_rooms_gametypes) - room_id, name, descriptionBan(mtgonline_bans) - user_id, server_id, reason, moderators, ip_address, expiration_time, active, creation_dateGameLog(mtgonline_log) - room_id, player_id, message, timestampAuditLog(mtgonline_audit) - admin_id, action_type, target_user_id, details, ip_address, timestamp
2. MTG Models (app/models/mtg_models.py)
MtgSet(mtg_sets) - code, name, type, release_date, base_set_size, total_size, is_foil_only, is_non_foil_only, digital, icon_svg_url, parent_code, mtgo_code, image, updated_atMtgCard(mtg_cards) - set_id, name, mana_cost, type_line, oracle_text, power, toughness, rarity, layout, artist, flavor_text, numbers, identifiers, images, image, updated_at
3. Mirror Models (app/models/mirror_models.py)
MtgCardMirror(mtg_cards_mirror) - source_id, name, mana_cost, type_line, oracle_text, power, toughness, rarity, layout, artist, flavor_text, numbers, identifiers, images, image, card_parts, keywords, legalities, set_code, set_name, synced_at, created_atDeckCardLink(deck_card_links) - deck_id, card_id, quantity, zone
4. User Data Models (app/models/user_data.py)
UserSession(user_sessions) - user_id, session_token_hash, ip_address, user_agent, created_at, expires_at, is_activeDeckVersion(deck_versions) - deck_id, version_number, content, status, comment, created_atGameReplay(game_replays) - game_uuid, room_id, game_type, format, duration_seconds, start_time, end_time, status, replay_data, created_at, updated_atReplayPlayer(replay_players) - replay_id, user_id, position, deck_id, won, lost, concession, turn_one, created_atGameOutcome(game_outcomes) - user_id, game_uuid, outcome, opponent_id, format, rating_before, rating_after, rating_change, created_atUserStatistics(user_statistics) - user_id (PK), total_games, total_wins, total_losses, total_concessions, win_rate, current_streak, best_streak, average_rating, last_game_date, updated_atUserCardCollection(user_card_collection) - user_id, card_id, quantity, condition, language, is_foil, is_alt_art, acquired_date, acquisition_method, notes, created_at, updated_atCardWishlist(card_wishlist) - user_id, card_id, max_price, notes, created_atUserGroup(user_groups) - name, description, owner_id, is_public, max_members, created_at, updated_atGroupMember(group_members) - group_id, user_id, role, joined_atGroupChatMessage(group_chat_messages) - group_id, sender_id, message, created_atUserNetwork(user_networks) - name, description, creator_id, is_public, created_atNetworkMember(network_members) - network_id, user_id, role, joined_atUserPreference(user_preferences) - user_id (PK), theme, notifications_enabled, email_notifications, auto_save_decks, default_format, language, updated_atUserActivityLog(user_activity_log) - user_id, activity_type, activity_data, ip_address, created_at
5. User Deck Models (app/models/user_deck.py)
UserDeck(user_decks) - user_id, name, status, folder_id, format, notes, is_precedent, precedent_name, created_at, updated_atUserDeckCard(user_deck_cards) - deck_id, card_id, quantity, zone, positionDeckPrecedent(deck_precedents) - name, description, format, is_public, created_by, created_at, updated_atDeckPrecedentCard(deck_precedent_cards) - precedent_id, card_id, quantity, zoneCardSuggestion(card_suggestions) - deck_id, card_id, source_card_id, suggestion_type, confidence, notes, created_at
6. Card Import Models (app/models/card_import.py)
CardImportBatch(card_import_batches) - user_id, filename, file_type, file_size, status, total_cards, matched_cards, unmatched_cards, match_results, error_message, created_at, updated_atUserCardImportRecord(user_card_imports_confirmed) - user_id, batch_id, is_confirmed, confirmed_at
Test Cases:
- Verify all models have proper
__tablename__ - Verify all foreign keys reference correct tables
- Verify all relationships are bidirectional where needed
- Verify cascade delete behavior
- Verify indexes on FK columns
- Verify unique constraints
- Verify model imports in
app/models/__init__.py - Check for missing fields compared to migration definitions
Verification: All models compile without errors, relationships are correct, no missing fields.
Phase 3: Schema Layer Tests
Scope: Pydantic schemas, request/response validation
Sub-agent Task: Verify all schema definitions are correct
Actual Schema Structure:
1. Core Schemas (app/schemas/schemas.py)
- Authentication:
LoginRequest,LoginResponse,RefreshTokenRequest,TokenResponse - User:
UserBase,UserCreate,UserUpdate,UserResponse - Deck:
DeckCreate,DeckUpdate,DeckResponse,FolderCreate,FolderResponse - Game:
GameCreate,GameResponse - Room:
RoomResponse - Ban:
BanCreate,BanResponse - Error:
ErrorResponse,ValidationErrorResponse - Pagination:
PaginationParams,PaginatedResponse - Card Mirror:
CardMirrorResponse,DeckCardLinkResponse,DeckWithCardsResponse
2. User Data Schemas (app/schemas/user_data_schemas.py)
- Enums:
DeckVersionStatus,GameReplayStatus,GameOutcomeType,GroupMemberRole,NetworkMemberRole,UserPreferenceTheme,ActivityType - Session:
SessionResponse,SessionCleanupResponse - Deck Version:
DeckVersionCreate,DeckVersionUpdate,DeckVersionResponse,DeckVersionListResponse - Game Replay:
GameReplayCreate,GameReplayUpdate,GameReplayResponse,GameReplayListResponse - Game Outcome:
GameOutcomeCreate,GameOutcomeResponse,GameOutcomeListResponse - User Statistics:
UserStatisticsResponse,StatisticsUpdateResponse - Card Collection:
CardCollectionCreate,CardCollectionUpdate,CardCollectionResponse,CardCollectionListResponse - Wishlist:
WishlistCreate,WishlistUpdate,WishlistResponse,WishlistListResponse - Group:
GroupCreate,GroupUpdate,GroupMemberCreate,GroupMemberUpdate,GroupMemberRemove,GroupResponse,GroupListResponse,GroupChatMessageCreate,GroupChatMessageResponse,GroupChatMessageListResponse - Network:
NetworkCreate,NetworkUpdate,NetworkMemberCreate,NetworkResponse,NetworkListResponse - Preference:
UserPreferenceUpdate,UserPreferenceResponse - Activity Log:
ActivityLogEntry,ActivityLogListResponse - Generic:
MessageResponse,CountResponse,ErrorDetail
3. User Deck Schemas (app/schemas/user_deck_schemas.py)
- Enums:
DeckStatus,DeckZone,SuggestionType - Deck:
UserDeckCreate,UserDeckUpdate,UserDeckResponse,UserDeckListResponse - Deck Card:
DeckCardCreate,DeckCardUpdate,DeckCardResponse,DeckCardWithDetailsResponse,DeckCardListResponse - Deck Precedent:
PrecedentCreate,PrecedentUpdate,PrecedentResponse,PrecedentListResponse - Card Suggestion:
SuggestionCreate,SuggestionResponse,SuggestionListResponse - Deck Action:
DeckFinalizeRequest,DeckFinalizeResponse,DeckDeleteResponse - Search:
CardSearchRequest,CardSearchResponse - Generic:
MessageResponse,CountResponse
4. Card Import Schemas (app/schemas/card_import_schemas.py)
CardImportRequest,CardImportResponse,CardImportStatusResponseCardMatchResult,CardImportSummaryMessageResponse,CountResponse,ErrorResponse
5. Card Search Schemas (app/schemas/card_search_schemas.py)
CardResponse,SetResponse,CardTypeResponse,CardSearchResponseCardImportResponse,CardImportStatusResponseCardMatchResult,CardImportSummaryMessageResponse,CountResponse,ErrorResponse
6. Protocol Schemas (app/schemas/proto_messages.py)
- Base:
ProtoMessageBase - Commands:
SessionCommand,GameCommand,GameEvent,Response - Server Info:
ServerInfoUser,ServerInfoDeckStorageFile,ServerInfoDeckStorageFolder,ServerInfoDeckStorageTreeItem,ServerInfoCard,ServerInfoZone,ServerInfoGame
7. Protocol Constants (app/schemas/protocol_constants.py)
SessionCommandType(IntEnum)GameCommandType(IntEnum)GameEventType(IntEnum)ResponseCode(IntEnum)ZoneType(IntEnum)UserLevelFlag(IntFlag)
8. User Card Collection Schemas (app/schemas/user_card_collection.py)
- Enums:
CardCondition,AcquisitionMethod - Card Collection:
CardCollectionCreate,CardCollectionUpdate,CardCollectionResponse,CardCollectionListResponse - Wishlist:
WishlistCreate,WishlistUpdate,WishlistResponse,WishlistListResponse - Collection Statistics:
CollectionStatistics,CollectionSummaryResponse - Generic:
MessageResponse,CountResponse,ErrorDetail
Test Cases:
- Verify all schemas have proper
model_config - Verify required vs optional fields
- Verify validation rules (min/max length, patterns, etc.)
- Verify schema imports in
app/schemas/__init__.py - Check for missing fields compared to model definitions
- Verify enum values match expected constants
Verification: All schemas compile without errors, validation rules are correct, no missing fields.
Phase 4: Router Layer Tests
Scope: FastAPI routers, endpoint definitions, dependencies
Sub-agent Task: Verify all router definitions are correct
Actual Router Structure:
1. Auth Router (app/routers/auth.py)
POST /login- Authenticate user, return JWT tokensPOST /refresh- Refresh access tokenPOST /register- Register new userGET /me- Get current authenticated user
2. Users Router (app/routers/users.py)
GET /{user_id}- Get user by IDPATCH /{user_id}- Update user profilePOST /{user_id}/ban- Ban user (admin only)POST /{user_id}/unban- Unban user (admin only)
3. Decks Router (app/routers/decks.py)
- Deck CRUD:
GET /- List user's decks with filteringPOST /- Create new user deck (DRAFT)GET /{deck_id}- Get specific deckPATCH /{deck_id}- Update deckDELETE /{deck_id}- Delete deck
- Deck Finalize:
POST /{deck_id}/finalize- Transition DRAFT to FINAL
- Deck Card Management:
POST /{deck_id}/cards- Add card to deckGET /{deck_id}/cards- Get all cards in deckPATCH /{deck_id}/cards/{card_id}- Update card in deckDELETE /{deck_id}/cards/{card_id}- Remove card from deck
- Deck Precedents:
GET /precedents- List available precedentsPOST /precedents- Create precedent (template)GET /precedents/{precedent_id}- Get specific precedentPOST /precedents/{precedent_id}/use- Clone precedent to new deck
- Card Search:
POST /search/cards- Search MTG cards
- Card Suggestions:
GET /{deck_id}/suggestions- Get card suggestionsPOST /{deck_id}/suggestions- Add suggestion
4. Additional Routers (exist but not fully documented)
app/routers/rooms.py- Rooms routerapp/routers/games/- Games router (directory)app/routers/admin.py- Admin routerapp/routers/card_router.py- Card routerapp/routers/interactions.py- Interactions routerapp/routers/refresh.py- Refresh routerapp/routers/card_import.py- Card import routerapp/routers/ws.py- WebSocket router
Test Cases:
- Verify all endpoints defined with correct HTTP methods
- Verify request/response schemas match
- Verify dependencies (auth, db session, etc.)
- Verify prefix paths are correct
- Verify tag assignments
- Verify all routers imported in
app/main.py - Check for missing endpoints
Verification: All routers compile without errors, endpoints are properly defined, no missing imports.
Phase 5: Service Layer Tests
Scope: Business logic, service functions
Sub-agent Task: Verify all service implementations are correct
Actual Service Structure:
1. Card Services
app/services/card_database.py- Card database managementapp/services/card_mirror_service.py- Card mirroringapp/services/card_search_service.py- Card searchapp/services/fuzzy_card_matcher.py- Fuzzy card matching
2. Deck Services
app/services/deck_manager.py- Deck managementapp/services/deck_parser.py- Deck parsingapp/services/deck_suggestion_service.py- Deck suggestions
3. File Services
app/services/file_parser.py- File parsing
4. Game Services
app/services/game_server.py- Game server logic
5. Import Services
app/services/import_batch_processor.py- Import batch processing
6. MTGJSON Services
app/services/mtgjson_downloader.py- MTGJSON data downloadapp/services/mtgjson_loader.py- MTGJSON data loadingapp/services/mtgjson_manager.py- MTGJSON data managementapp/services/mtgjson_uploader.py- MTGJSON data upload
Test Cases:
- Verify all functions defined with proper signatures
- Verify function implementations match expected behavior
- Verify service imports (models, schemas, utilities)
- Check for missing implementations
- Verify error handling
Verification: All services compile without errors, functions are properly implemented, no missing imports.
Phase 6: Utility & Helper Tests
Scope: Utility functions, helpers, constants
Sub-agent Task: Verify all utility implementations are correct
Actual Utility Structure:
1. Core Configuration (app/core/)
app/core/database.py- Database configuration, session managementapp/core/redis_client.py- Redis client setupapp/core/security.py- JWT tokens, password hashing, auth dependenciesapp/core/settings.py- Application settings, environment variables
2. Utilities (app/utils/)
app/utils/auth.py- Authentication utilitiesapp/utils/database.py- Database utilitiesapp/utils/errors.py- Custom exceptions and error handlersapp/utils/constants.py- Application constants
Test Cases:
- Verify all functions defined with proper signatures
- Verify function implementations
- Verify exception classes defined with proper error codes
- Verify constants defined with correct values
- Verify utility imports where needed
Verification: All utilities compile without errors, functions are properly implemented, no missing imports.
Phase 7: Configuration & Environment Tests
Scope: Settings, environment variables, configuration
Sub-agent Task: Verify all configuration is correct
Test Cases:
- Verify all settings defined in
app/core/settings.py - Verify default values are sensible
- Verify database URL configuration
- Verify async/sync engine setup in
app/core/database.py - Verify FastAPI app initialization in
app/main.py - Verify middleware setup
- Verify CORS configuration
- Verify all settings used in code match defined settings
- Verify environment variables match settings
Verification: All configuration compiles without errors, settings are properly defined, no missing configuration.
Phase 8: Integration Tests
Scope: Cross-component integration, API consistency
Sub-agent Task: Verify all components work together correctly
Test Cases:
-
Router-Service Integration
- Verify routers call correct service functions
- Verify service functions return correct types
- Check for integration issues
-
Service-Model Integration
- Verify services use correct models
- Verify model operations are correct
- Check for integration issues
-
Schema-Router Integration
- Verify routers use correct schemas
- Verify schemas match request/response
- Check for integration issues
-
Database-Model Integration
- Verify models match database schema (from migrations)
- Verify migrations create correct tables
- Check for integration issues
-
Overall Consistency
- Verify all imports are correct
- Verify all function calls are valid
- Check for circular dependencies
- Verify no orphaned code
Verification: All components integrate correctly, no circular dependencies, all imports valid.
Execution Strategy
Sub-Agent Execution Order:
- Phase 1: ✅ Database & Migration Tests (COMPLETE)
- Phase 2: Model Layer Tests
- Phase 3: Schema Layer Tests
- Phase 4: Router Layer Tests
- Phase 5: Service Layer Tests
- Phase 6: Utility & Helper Tests
- Phase 7: Configuration & Environment Tests
- Phase 8: Integration Tests
Context Management:
- Each sub-agent handles one phase at a time
- Sub-agents return only findings and issues
- Main agent aggregates results and coordinates fixes
- Maximum context usage per sub-agent: ~50,000 tokens
Verification Criteria:
- All files compile without syntax errors
- All imports resolve correctly
- All function signatures match across components
- All foreign keys reference existing tables
- All schemas have proper validation
- All routers have proper dependencies
- No circular dependencies
- No orphaned code
Issue Reporting:
Each sub-agent should report:
- Critical Issues: Missing files, broken imports, syntax errors
- Consistency Issues: Mismatched types, missing fields, incorrect references
- Recommendations: Improvements, missing features, best practices
Summary
This test plan provides a systematic approach to verifying the entire backend system by breaking it down into 8 manageable phases. Each phase can be executed by a sub-agent independently, ensuring comprehensive coverage while staying within context limits. The plan focuses on consistency, correctness, and completeness of the codebase.
Current Status: Phase 1 Complete
Next Phase: Phase 2 - Model Layer Tests