Files
mtgonline/BACKEND_TEST_PLAN.md
T
akadmin bea91db64d Phase 3: Schema Layer - Pydantic v2 migration, deduplication, and missing schemas
- 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
2026-08-16 05:22:17 +00:00

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.py and __init__.py consistent

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_login
  • MtonlineCard (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_at
  • DecklistFolder (mtgonline_decklist_folders) - owner_id, name, parent_id, creation_date
  • DecklistFile (mtgonline_decklist_files) - folder_id, owner_id, name, content, format, status, creation_date
  • Room (mtgonline_rooms) - name, description, is_password_protected, password_hash, creation_date
  • RoomGameType (mtgonline_rooms_gametypes) - room_id, name, description
  • Ban (mtgonline_bans) - user_id, server_id, reason, moderators, ip_address, expiration_time, active, creation_date
  • GameLog (mtgonline_log) - room_id, player_id, message, timestamp
  • AuditLog (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_at
  • MtgCard (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_at
  • DeckCardLink (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_active
  • DeckVersion (deck_versions) - deck_id, version_number, content, status, comment, created_at
  • GameReplay (game_replays) - game_uuid, room_id, game_type, format, duration_seconds, start_time, end_time, status, replay_data, created_at, updated_at
  • ReplayPlayer (replay_players) - replay_id, user_id, position, deck_id, won, lost, concession, turn_one, created_at
  • GameOutcome (game_outcomes) - user_id, game_uuid, outcome, opponent_id, format, rating_before, rating_after, rating_change, created_at
  • UserStatistics (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_at
  • UserCardCollection (user_card_collection) - user_id, card_id, quantity, condition, language, is_foil, is_alt_art, acquired_date, acquisition_method, notes, created_at, updated_at
  • CardWishlist (card_wishlist) - user_id, card_id, max_price, notes, created_at
  • UserGroup (user_groups) - name, description, owner_id, is_public, max_members, created_at, updated_at
  • GroupMember (group_members) - group_id, user_id, role, joined_at
  • GroupChatMessage (group_chat_messages) - group_id, sender_id, message, created_at
  • UserNetwork (user_networks) - name, description, creator_id, is_public, created_at
  • NetworkMember (network_members) - network_id, user_id, role, joined_at
  • UserPreference (user_preferences) - user_id (PK), theme, notifications_enabled, email_notifications, auto_save_decks, default_format, language, updated_at
  • UserActivityLog (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_at
  • UserDeckCard (user_deck_cards) - deck_id, card_id, quantity, zone, position
  • DeckPrecedent (deck_precedents) - name, description, format, is_public, created_by, created_at, updated_at
  • DeckPrecedentCard (deck_precedent_cards) - precedent_id, card_id, quantity, zone
  • CardSuggestion (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_at
  • UserCardImportRecord (user_card_imports_confirmed) - user_id, batch_id, is_confirmed, confirmed_at

Test Cases:

  1. Verify all models have proper __tablename__
  2. Verify all foreign keys reference correct tables
  3. Verify all relationships are bidirectional where needed
  4. Verify cascade delete behavior
  5. Verify indexes on FK columns
  6. Verify unique constraints
  7. Verify model imports in app/models/__init__.py
  8. 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, CardImportStatusResponse
  • CardMatchResult, CardImportSummary
  • MessageResponse, CountResponse, ErrorResponse

5. Card Search Schemas (app/schemas/card_search_schemas.py)

  • CardResponse, SetResponse, CardTypeResponse, CardSearchResponse
  • CardImportResponse, CardImportStatusResponse
  • CardMatchResult, CardImportSummary
  • MessageResponse, 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:

  1. Verify all schemas have proper model_config
  2. Verify required vs optional fields
  3. Verify validation rules (min/max length, patterns, etc.)
  4. Verify schema imports in app/schemas/__init__.py
  5. Check for missing fields compared to model definitions
  6. 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 tokens
  • POST /refresh - Refresh access token
  • POST /register - Register new user
  • GET /me - Get current authenticated user

2. Users Router (app/routers/users.py)

  • GET /{user_id} - Get user by ID
  • PATCH /{user_id} - Update user profile
  • POST /{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 filtering
    • POST / - Create new user deck (DRAFT)
    • GET /{deck_id} - Get specific deck
    • PATCH /{deck_id} - Update deck
    • DELETE /{deck_id} - Delete deck
  • Deck Finalize:
    • POST /{deck_id}/finalize - Transition DRAFT to FINAL
  • Deck Card Management:
    • POST /{deck_id}/cards - Add card to deck
    • GET /{deck_id}/cards - Get all cards in deck
    • PATCH /{deck_id}/cards/{card_id} - Update card in deck
    • DELETE /{deck_id}/cards/{card_id} - Remove card from deck
  • Deck Precedents:
    • GET /precedents - List available precedents
    • POST /precedents - Create precedent (template)
    • GET /precedents/{precedent_id} - Get specific precedent
    • POST /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 suggestions
    • POST /{deck_id}/suggestions - Add suggestion

4. Additional Routers (exist but not fully documented)

  • app/routers/rooms.py - Rooms router
  • app/routers/games/ - Games router (directory)
  • app/routers/admin.py - Admin router
  • app/routers/card_router.py - Card router
  • app/routers/interactions.py - Interactions router
  • app/routers/refresh.py - Refresh router
  • app/routers/card_import.py - Card import router
  • app/routers/ws.py - WebSocket router

Test Cases:

  1. Verify all endpoints defined with correct HTTP methods
  2. Verify request/response schemas match
  3. Verify dependencies (auth, db session, etc.)
  4. Verify prefix paths are correct
  5. Verify tag assignments
  6. Verify all routers imported in app/main.py
  7. 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 management
  • app/services/card_mirror_service.py - Card mirroring
  • app/services/card_search_service.py - Card search
  • app/services/fuzzy_card_matcher.py - Fuzzy card matching

2. Deck Services

  • app/services/deck_manager.py - Deck management
  • app/services/deck_parser.py - Deck parsing
  • app/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 download
  • app/services/mtgjson_loader.py - MTGJSON data loading
  • app/services/mtgjson_manager.py - MTGJSON data management
  • app/services/mtgjson_uploader.py - MTGJSON data upload

Test Cases:

  1. Verify all functions defined with proper signatures
  2. Verify function implementations match expected behavior
  3. Verify service imports (models, schemas, utilities)
  4. Check for missing implementations
  5. 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 management
  • app/core/redis_client.py - Redis client setup
  • app/core/security.py - JWT tokens, password hashing, auth dependencies
  • app/core/settings.py - Application settings, environment variables

2. Utilities (app/utils/)

  • app/utils/auth.py - Authentication utilities
  • app/utils/database.py - Database utilities
  • app/utils/errors.py - Custom exceptions and error handlers
  • app/utils/constants.py - Application constants

Test Cases:

  1. Verify all functions defined with proper signatures
  2. Verify function implementations
  3. Verify exception classes defined with proper error codes
  4. Verify constants defined with correct values
  5. 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:

  1. Verify all settings defined in app/core/settings.py
  2. Verify default values are sensible
  3. Verify database URL configuration
  4. Verify async/sync engine setup in app/core/database.py
  5. Verify FastAPI app initialization in app/main.py
  6. Verify middleware setup
  7. Verify CORS configuration
  8. Verify all settings used in code match defined settings
  9. 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:

  1. Router-Service Integration

    • Verify routers call correct service functions
    • Verify service functions return correct types
    • Check for integration issues
  2. Service-Model Integration

    • Verify services use correct models
    • Verify model operations are correct
    • Check for integration issues
  3. Schema-Router Integration

    • Verify routers use correct schemas
    • Verify schemas match request/response
    • Check for integration issues
  4. Database-Model Integration

    • Verify models match database schema (from migrations)
    • Verify migrations create correct tables
    • Check for integration issues
  5. 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:

  1. Phase 1: Database & Migration Tests (COMPLETE)
  2. Phase 2: Model Layer Tests
  3. Phase 3: Schema Layer Tests
  4. Phase 4: Router Layer Tests
  5. Phase 5: Service Layer Tests
  6. Phase 6: Utility & Helper Tests
  7. Phase 7: Configuration & Environment Tests
  8. 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:

  1. Critical Issues: Missing files, broken imports, syntax errors
  2. Consistency Issues: Mismatched types, missing fields, incorrect references
  3. 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