Files
mtgonline/backend/ARCHITECTURAL_REPORT.md
akadmin 0e6506d97f Update state.json and development plan to reflect actual progress (~15%)
- state.json: Phase 5 status changed to pending, next steps updated
- DEVELOPMENT_PLAN.md v1.1: Added actual progress, verified current state,
  renumbered phases 5-9, marked all remaining work as PENDING
- Deleted outdated plans (BACKEND_TEST_PLAN, DATA_LOADING_VERIFICATION,
  DOCKER_MIGRATION_PLAN, ENDPOINT_AUDIT, ROADMAP, SIMPLIFICATION_PLAN,
  STATEMENT_OF_INTENT, backend/TEST_PLAN)
- Added new files: DEVELOPMENT_PLAN.md, backend/ARCHITECTURAL_REPORT.md,
  backend/SIMPLIFICATION_SUMMARY.md, backend/run.py, backend/.dockerignore
2026-08-27 04:41:30 +00:00

51 KiB

MTG Online Backend - Comprehensive Architectural Report

Project: MTG Online Backend
Location: /home/wall-o/projects/mtgonline/backend/app/
Framework: FastAPI with SQLAlchemy async
Database: SQLite (dev) / PostgreSQL (prod) + Redis caching
Date: 2025-07-21


Executive Summary

The MTG Online backend is a FastAPI application providing card game management features including user authentication, deck building, card search with fuzzy matching, card collection management, and real-time game WebSocket support. The codebase exhibits significant architectural debt with multiple layers of duplicated functionality (old vs. new router patterns), inconsistent database models, and redundant services.

Key Issues Identified:

  1. Router Duplication: Every major feature has both old and new router implementations
  2. Model Inconsistency: Multiple model files with overlapping functionality
  3. Service Redundancy: Multiple services performing similar operations
  4. Schema Confusion: Duplicate schema definitions across files
  5. Mixed Database Patterns: Some services use ORM, others use raw SQL

Layer Analysis

1. Core Layer (app/core/)

Purpose: Application infrastructure - configuration, database, security, logging, caching

1.1 config.py (216 lines)

Purpose: Application configuration management with environment variable overrides

Key Classes/Functions:

  • Config class: Configuration with sensible defaults
  • get_config(): Singleton configuration instance
  • _load_env_file(): Load .env files

Imports From:

  • os (stdlib)
  • typing.Optional

Imported By:

  • database.py
  • security.py
  • settings.py (via config)

Dependencies: None (standalone)


1.2 database.py (193 lines)

Purpose: SQLAlchemy async engine and session management

Key Classes/Functions:

  • Base: DeclarativeBase for ORM models
  • engine: Async engine instance
  • async_session: Session factory
  • get_db(): FastAPI dependency for database sessions
  • create_tables(): Create all tables
  • Backward-compatible aliases: mtg_engine, mtg_async_session, mtg_get_db, mirror_get_db

Imports From:

  • app.core.config: get_config
  • sqlalchemy.ext.asyncio: AsyncSession, async_sessionmaker, create_async_engine
  • sqlalchemy.orm: DeclarativeBase

Imported By:

  • models/__init__.py
  • models/models.py
  • models/mtg_models.py
  • routers/*.py (multiple)
  • services/*.py (multiple)

Dependencies: config.py


1.3 logging.py (187 lines)

Purpose: Structured logging configuration with JSON/text support

Key Classes/Functions:

  • ContainerFormatter: Custom log formatter
  • configure_logging(): Configure application logging

Imports From:

  • json, logging, os, sys, datetime, typing

Imported By:

  • Imported by logging_config.py (duplicate)
  • Used by various services

Dependencies: None (standalone)


1.4 logging_config.py (97 lines)

Purpose: DUPLICATE of logging.py - structured logging configuration

Key Classes/Functions:

  • ContainerFormatter: Same as logging.py
  • configure_logging(): Same as logging.py

Imports From:

  • json, logging, os, sys, datetime

Imported By:

  • Auto-configures on import

Dependencies: None (standalone)

⚠️ ISSUE: Exact duplicate of logging.py. Should be removed.


1.5 redis_client.py (90 lines)

Purpose: Redis client and caching layer

Key Classes/Functions:

  • get_redis(): Get Redis client instance
  • close_redis(): Close Redis connection
  • cache_get(), cache_set(), cache_delete(), cache_invalidate_pattern(): Cache operations

Imports From:

  • app.core.settings: get_settings
  • redis.asyncio: aioredis

Imported By:

  • routers/card_router.py
  • routers/cards_router.py
  • routers/interactions.py

Dependencies: settings.py


1.6 security.py (238 lines)

Purpose: Authentication and password hashing utilities

Key Classes/Functions:

  • verify_password(), hash_password(): Password operations
  • create_access_token(), create_refresh_token(): JWT token creation
  • decode_token(): JWT token validation
  • get_current_user(): FastAPI dependency for auth

Imports From:

  • app.core.config: get_config
  • fastapi: Header, HTTPException, status
  • jose: JWTError, jwt
  • passlib.context: CryptContext

Imported By:

  • routers/auth.py
  • routers/auth_router.py
  • routers/users.py
  • routers/users_router.py
  • routers/admin.py
  • routers/rooms.py
  • routers/games_router.py

Dependencies: config.py


1.7 settings.py (29 lines)

Purpose: BACKWARD COMPATIBILITY SHIM - re-exports config module

Key Classes/Functions:

  • get_settings: Alias for get_config

Imports From:

  • app.core.config: Config, get_config

Imported By:

  • redis_client.py
  • services/mtgjson_loader.py
  • services/mtgjson_uploader.py

Dependencies: config.py

⚠️ ISSUE: Should be removed once all callers migrate to config.py


2. Models Layer (app/models/)

Purpose: SQLAlchemy ORM models for database entities

2.1 __init__.py (30 lines)

Purpose: Exports all models from models.py and mtg_models.py

Imports From:

  • app.models.models: All application models
  • app.models.mtg_models: MtgSet, MtgCard, MtgCardMirror, DeckCardLink

Imported By:

  • Various routers and services

Dependencies: models.py, mtg_models.py


2.2 models.py (968 lines)

Purpose: Main application ORM models

Key Classes:

  • Core: User, DecklistFolder, DecklistFile, Room, RoomGameType, Ban, GameLog, AuditLog
  • Card Mirror: MtgonlineCard (local copy for deckbuilding)
  • User Decks: UserDeck, UserDeckCard, DeckPrecedent, DeckPrecedentCard, CardSuggestion
  • User Data: UserSession, DeckVersion, GameReplay, ReplayPlayer, GameOutcome, UserStatistics, UserCardCollection, CardWishlist, UserGroup, GroupMember, GroupChatMessage, UserNetwork, NetworkMember, UserPreference, UserActivityLog
  • Card Imports: CardImportBatch, UserCardImportRecord, UserCardImport

Imports From:

  • app.core.database: Base
  • sqlalchemy: Various column types, relationships

Imported By:

  • models/__init__.py
  • routers/*.py (multiple)
  • services/*.py (multiple)

Dependencies: database.py


2.3 mtg_models.py (184 lines)

Purpose: MTG card data models

Key Classes:

  • MtgSet: MTG set data
  • MtgCard: MTG card data (canonical)
  • MtgCardMirror: Mirrored card data for fast queries
  • DeckCardLink: Junction table linking decks to mirrored cards

Imports From:

  • app.core.database: Base
  • sqlalchemy: Column types, relationships

Imported By:

  • models/__init__.py
  • routers/card_router.py
  • routers/cards_router.py
  • services/card_search_service.py
  • services/deck_suggestion_service.py

Dependencies: database.py


2.4 __backup__/ (Directory)

Purpose: Backup of old model files (not analyzed)


3. Routers Layer (app/routers/)

Purpose: FastAPI route handlers for API endpoints

⚠️ CRITICAL ISSUE: Every major feature has both old and new router implementations with significant duplication.

3.1 __init__.py (29 lines)

Purpose: Exports consolidated routers

Imports From:

  • app.routers.auth_router
  • app.routers.users_router
  • app.routers.decks_router
  • app.routers.cards_router
  • app.routers.user_data_router
  • app.routers.games_router

Imported By:

  • app/main.py

Dependencies: All router modules


3.2 auth.py (162 lines) - OLD VERSION

Purpose: Authentication endpoints (login, refresh, register, me)

Key Endpoints:

  • POST /login: Authenticate user
  • POST /refresh: Refresh access token
  • POST /register: Register new user
  • GET /me: Get current user

Imports From:

  • app.core.database: get_db
  • app.core.security: verify_password, hash_password, create_access_token, create_refresh_token, decode_token
  • app.models.models: User
  • app.schemas.schemas: Login/refresh/user schemas

Imported By: None (old version, superseded by auth_router.py)

Dependencies: database.py, security.py, models.py, schemas.py


3.3 auth_router.py (246 lines) - NEW VERSION

Purpose: Authentication endpoints (consolidated)

Key Endpoints: Same as auth.py but with better structure

Imports From:

  • app.core.database: get_db
  • app.core.security: Token functions
  • app.models.models: User
  • app.schemas.schemas: Login/refresh/user schemas

Imported By:

  • app/main.py

Dependencies: database.py, security.py, models.py, schemas.py


3.4 users.py (168 lines) - OLD VERSION

Purpose: User management endpoints

Key Endpoints:

  • GET /{user_id}: Get user
  • PATCH /{user_id}: Update user
  • POST /{user_id}/ban: Ban user
  • POST /{user_id}/unban: Unban user

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user, hash_password
  • app.models.models: User
  • app.schemas.schemas: User schemas

Imported By: None (old version, superseded by users_router.py)

Dependencies: database.py, security.py, models.py, schemas.py


3.5 users_router.py (549 lines) - NEW VERSION

Purpose: User management + admin operations (consolidated)

Key Endpoints:

  • User management: GET/PATCH user, ban/unban
  • Admin operations: List users, list bans, create ban, unban by ID, list logs, audit log

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user, hash_password
  • app.models.models: User, Ban, GameLog, AuditLog
  • app.schemas.schemas: User/ban schemas

Imported By:

  • app/main.py

Dependencies: database.py, security.py, models.py, schemas.py


3.6 decks.py (721 lines) - OLD VERSION

Purpose: Deck management endpoints

Key Endpoints:

  • CRUD for user decks
  • Deck card management
  • Precedent management
  • Card search integration
  • Card suggestions

Imports From:

  • app.core.database: get_db, mtg_get_db
  • app.core.security: get_current_user
  • app.models.models: User, DecklistFolder, MtgonlineCard
  • app.models.user_deck: UserDeck, UserDeckCard, etc.
  • app.services.deck_manager: DeckManager
  • app.services.deck_parser: DeckParser

Imported By: None (old version, superseded by decks_router.py)

Dependencies: Multiple


3.7 decks_router.py (810 lines) - NEW VERSION

Purpose: Deck management (consolidated)

Key Endpoints: Same as decks.py but with better structure

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user
  • app.models.mtg_models: MtgCard, MtgSet
  • app.models.models: MtgonlineCard, User, DecklistFolder
  • app.models.user_deck: Deck models
  • app.services.deck_manager: DeckManager
  • app.services.deck_parser: DeckParser

Imported By:

  • app/main.py

Dependencies: Multiple


3.8 card_router.py (292 lines) - OLD VERSION

Purpose: Card search endpoints

Key Endpoints:

  • GET /api/cards/search: Search cards
  • GET /api/cards/{card_id}: Get card by ID
  • GET /api/cards/sets: List sets
  • GET /api/cards/types: List card types
  • GET /api/cards/rarities: List rarities
  • GET /api/cards/suggest: Suggest cards

Imports From:

  • app.core.database: mtg_get_db
  • app.core.redis_client: cache_get, cache_set
  • app.services.card_search_service: CardSearchService
  • app.services.deck_suggestion_service: DeckSuggestionService
  • app.services.fuzzy_card_matcher: FuzzyCardMatcher
  • app.models.user_deck: UserDeck
  • app.models.mtg_models: MtgCard

Imported By: None (old version, superseded by cards_router.py)

Dependencies: Multiple


3.9 cards_router.py (995 lines) - NEW VERSION

Purpose: Card search + card interactions (consolidated)

Key Endpoints:

  • Card search: Same as card_router.py
  • Card interactions: synergies, counters, evolutions, recommendations, stats

Imports From:

  • app.core.database: mtg_get_db
  • app.core.redis_client: cache_get, cache_set
  • app.models.mtg_models: MtgCard
  • app.models.user_deck: UserDeck
  • app.schemas.card_search_schemas: Card schemas
  • app.services.card_search_service: CardSearchService
  • app.services.deck_suggestion_service: DeckSuggestionService
  • app.services.fuzzy_card_matcher: FuzzyCardMatcher

Imported By:

  • app/main.py

Dependencies: Multiple


3.10 interactions.py (674 lines) - OLD VERSION

Purpose: Card interaction endpoints (synergies, counters, evolutions)

Key Endpoints:

  • GET /interactions/synergies/{card_id}
  • GET /interactions/counters/{card_id}
  • GET /interactions/evolutions/{card_id}
  • GET /interactions/recommend/{card_id}
  • Search endpoints for each interaction type
  • GET /interactions/stats/{card_id}

Imports From:

  • app.core.database: mtg_get_db
  • app.core.redis_client: cache_get, cache_set

Imported By: None (old version, superseded by cards_router.py)

Dependencies: database.py, redis_client.py


3.11 user_data.py (1714 lines) - OLD VERSION

Purpose: User data endpoints (sessions, decks, replays, collections, groups, networks, preferences)

Key Endpoints:

  • Session management
  • Deck versions
  • Game replays
  • Card collection
  • Wishlist
  • Groups with chat
  • Networks
  • Preferences
  • Activity log

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user
  • app.models.models: User
  • app.models.user_data: Various user data models
  • app.schemas.user_card_collection: Collection schemas
  • app.schemas.user_data_schemas: User data schemas

Imported By: None (old version, superseded by user_data_router.py)

Dependencies: Multiple


3.12 user_data_router.py (69121 bytes) - NEW VERSION

Purpose: User data + card import (consolidated)

Key Endpoints:

  • All user_data.py endpoints
  • Card import endpoints (upload, status, results, confirm)

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user
  • app.models.models: User, MtgonlineCard
  • app.models.user_data: User data models
  • app.models.card_import_batch: CardImportBatch
  • app.models.user_card_import_record: UserCardImportRecord
  • app.models.user_deck: UserDeck, UserDeckCard
  • app.services.file_parser: FileParser
  • app.services.import_batch_processor: ImportBatchProcessor
  • app.services.fuzzy_card_matcher: FuzzyCardMatcher
  • app.schemas.*: Various schemas

Imported By:

  • app/main.py

Dependencies: Multiple


3.13 rooms.py (158 lines) - OLD VERSION

Purpose: Room management endpoints

Key Endpoints:

  • GET /: List rooms
  • GET /{room_id}: Get room
  • POST /: Create room (admin)
  • PATCH /{room_id}: Update room (admin)
  • DELETE /{room_id}: Delete room (admin)

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user
  • app.models.models: Room
  • app.schemas.schemas: RoomResponse

Imported By: None (old version, superseded by games_router.py)

Dependencies: database.py, security.py, models.py, schemas.py


3.14 games/__init__.py (4 lines)

Purpose: Games router package init

Imports From:

  • app.routers.games.router: router

Imported By: None

Dependencies: games/router.py


3.15 games/router.py (135 lines) - OLD VERSION

Purpose: Game management stubs

Key Endpoints:

  • GET /: List games (stub)
  • POST /: Create game (mock)
  • GET /{game_id}: Get game (mock)
  • POST /{game_id}/join: Join game (stub)
  • POST /{game_id}/leave: Leave game (stub)
  • POST /{game_id}/start: Start game (stub)
  • POST /{game_id}/end: End game (stub)

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user
  • app.models.models: User
  • app.schemas.schemas: GameCreate, GameResponse

Imported By: None (old version, superseded by games_router.py)

Dependencies: database.py, security.py, models.py, schemas.py


3.16 games_router.py (487 lines) - NEW VERSION

Purpose: Room management + game stubs + MTGJSON refresh + WebSocket (consolidated)

Key Endpoints:

  • Room CRUD (prefix: /rooms)
  • Game stubs (prefix: /games)
  • MTGJSON refresh (prefix: /mtgjson)
  • WebSocket (prefix: /ws/game/{game_id})

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user
  • app.models.models: Room, User
  • app.schemas.schemas: RoomResponse, GameCreate, GameResponse
  • app.services.mtgjson_manager: MTGJSONManager
  • app.services.game_server: game_websocket_endpoint

Imported By:

  • app/main.py

Dependencies: Multiple


3.17 refresh.py (101 lines) - OLD VERSION

Purpose: MTGJSON refresh endpoints

Key Endpoints:

  • POST /mtgjson/refresh: Trigger refresh
  • GET /mtgjson/status: Get status
  • POST /mtgjson/verify: Verify files

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user
  • app.services.mtgjson_manager: MTGJSONManager

Imported By: None (old version, superseded by games_router.py)

Dependencies: database.py, security.py, services/mtgjson_manager.py


3.18 card_import.py (368 lines) - OLD VERSION

Purpose: Card import endpoints

Key Endpoints:

  • POST /import: Upload import file
  • GET /import/{import_id}/status: Get status
  • GET /import/{import_id}/results: Get results
  • POST /import/{import_id}/confirm: Confirm import
  • GET /user/cards: List user cards
  • DELETE /user/cards/{card_import_id}: Delete card
  • GET /user/decks: List user decks

Imports From:

  • app.core.database: get_db
  • app.core.security: get_current_user
  • app.models.card_import_batch: CardImportBatch
  • app.models.user_card_import_record: UserCardImportRecord
  • app.models.user_data: UserCardCollection
  • app.models.models: MtgonlineCard
  • app.models.user_deck: UserDeck, UserDeckCard
  • app.services.file_parser: FileParser
  • app.services.import_batch_processor: ImportBatchProcessor
  • app.services.fuzzy_card_matcher: FuzzyCardMatcher

Imported By: None (old version, superseded by user_data_router.py)

Dependencies: Multiple


3.19 ws.py (512 bytes) - OLD VERSION

Purpose: WebSocket endpoint for game connections

Key Endpoints:

  • GET /ws/game/{game_id}: WebSocket connection

Imports From:

  • app.services.game_server: game_websocket_endpoint

Imported By: None (old version, superseded by games_router.py)

Dependencies: services/game_server.py


4. Schemas Layer (app/schemas/)

Purpose: Pydantic models for request/response validation

4.1 __init__.py (147 lines)

Purpose: Exports all schemas from various schema files

Imports From:

  • app.schemas.schemas: Basic schemas
  • app.schemas.user_data_schemas: User data schemas
  • app.schemas.user_card_collection: Collection schemas
  • app.schemas.user_deck_schemas: Deck schemas
  • app.schemas.card_import_schemas: Import schemas
  • app.schemas.card_search_schemas: Search schemas
  • app.schemas.game_schemas: Game schemas
  • app.schemas.mtg_card_schemas: MTG card schemas
  • app.schemas.proto_messages: Protocol messages
  • app.schemas.protocol_constants: Protocol constants

Imported By:

  • Various routers

Dependencies: All schema files


4.2 schemas.py (286 lines)

Purpose: Basic Pydantic models for auth, users, decks, games, bans

Key Classes:

  • Auth: 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

Imports From:

  • pydantic: BaseModel, EmailStr, Field, ConfigDict
  • typing: Optional, List, Dict
  • datetime: datetime

Imported By:

  • routers/auth.py
  • routers/auth_router.py
  • routers/users.py
  • routers/users_router.py
  • routers/rooms.py
  • routers/games_router.py

Dependencies: None (standalone)


4.3 user_data_schemas.py (434 lines)

Purpose: User data schemas (sessions, decks, replays, collections, groups, networks, preferences)

Key Classes:

  • 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
  • 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

Imports From:

  • pydantic: BaseModel, Field, ConfigDict
  • typing: Optional, List, Dict, Any
  • datetime: datetime
  • enum: Enum

Imported By:

  • routers/user_data.py
  • routers/user_data_router.py

Dependencies: None (standalone)


4.4 user_deck_schemas.py (217 lines)

Purpose: Deck building schemas

Key Classes:

  • Enums: DeckStatus, DeckZone, SuggestionType
  • Deck: UserDeckCreate, UserDeckUpdate, UserDeckResponse, UserDeckListResponse
  • Deck Card: DeckCardCreate, DeckCardUpdate, DeckCardResponse, DeckCardWithDetailsResponse, DeckCardListResponse
  • Precedent: PrecedentCreate, PrecedentUpdate, PrecedentResponse, PrecedentListResponse
  • Suggestion: SuggestionCreate, SuggestionResponse, SuggestionListResponse
  • Actions: DeckFinalizeRequest, DeckFinalizeResponse, DeckDeleteResponse
  • Search: CardSearchRequest

Imports From:

  • pydantic: BaseModel, Field, ConfigDict
  • typing: Optional, List, Dict, Any
  • datetime: datetime
  • enum: Enum

Imported By:

  • routers/decks.py
  • routers/decks_router.py
  • routers/card_import.py

Dependencies: None (standalone)


4.5 user_card_collection.py (157 lines)

Purpose: Card collection schemas

Key Classes:

  • Enums: CardCondition, AcquisitionMethod
  • Collection: CardCollectionCreate, CardCollectionUpdate, CardCollectionResponse, CardCollectionListResponse
  • Wishlist: WishlistCreate, WishlistUpdate, WishlistResponse, WishlistListResponse
  • Statistics: CollectionStatistics, CollectionSummaryResponse
  • Generic: MessageResponse, CountResponse, ErrorDetail

Imports From:

  • pydantic: BaseModel, Field, ConfigDict
  • typing: Optional, List, Dict, Any
  • datetime: datetime
  • enum: Enum

Imported By:

  • routers/user_data.py
  • routers/user_data_router.py

Dependencies: None (standalone)


4.6 card_import_schemas.py (113 lines)

Purpose: Card import schemas

Key Classes:

  • Import: CardImportRequest, CardImportResponse, CardImportStatusResponse
  • Match: CardMatchResult, CardImportSummary
  • Batch: CardImportBatchCreate, CardImportBatchResponse
  • User Import: UserCardImportCreate, UserCardImportResponse, UserCardImportRecordResponse

Imports From:

  • pydantic: BaseModel, Field, ConfigDict
  • typing: List, Optional, Dict, Any
  • datetime: datetime

Imported By:

  • routers/card_import.py
  • routers/user_data_router.py

Dependencies: None (standalone)


4.7 card_search_schemas.py (108 lines)

Purpose: Card search and import schemas

Key Classes:

  • Search: CardResponse, SetResponse, CardTypeResponse, CardSearchResponse
  • Import: CardImportResponse, CardImportStatusResponse, CardMatchResult, CardImportSummary
  • Generic: MessageResponse, CountResponse, ErrorResponse

Imports From:

  • pydantic: BaseModel, Field, ConfigDict
  • typing: List, Optional, Dict, Any
  • datetime: datetime

Imported By:

  • routers/card_router.py
  • routers/cards_router.py

Dependencies: None (standalone)


4.8 mtg_card_schemas.py (116 lines)

Purpose: MTG card schemas

Key Classes:

  • Card: MtgCardResponse, MtgCardSearchRequest, MtgCardSearchResponse
  • Set: MtgSetResponse
  • Mirror: MtgCardMirrorResponse
  • Link: DeckCardLinkResponse, DeckWithCardsResponse

Imports From:

  • pydantic: BaseModel, ConfigDict
  • typing: Optional, List
  • datetime: datetime

Imported By:

  • routers/cards_router.py

Dependencies: None (standalone)


4.9 game_schemas.py (59 lines)

Purpose: Game schemas

Key Classes:

  • Game: GameCreate, GameResponse, GameJoinRequest, GameLeaveRequest, GameListResponse, GamePlayerResponse, GameStateResponse

Imports From:

  • pydantic: BaseModel, Field, ConfigDict
  • typing: Optional, List
  • datetime: datetime

Imported By:

  • routers/games_router.py

Dependencies: None (standalone)


4.10 generic_schemas.py (29 lines)

Purpose: Generic response schemas

Key Classes:

  • MessageResponse, CountResponse, ErrorResponse, ValidationErrorResponse, ErrorDetail

Imports From:

  • pydantic: BaseModel
  • typing: Optional, List

Imported By:

  • routers/user_data.py
  • routers/user_data_router.py

Dependencies: None (standalone)


4.11 proto_messages.py (133 lines)

Purpose: Protocol buffer message models

Key Classes:

  • Base: ProtoMessageBase
  • Commands: SessionCommand, GameCommand, GameEvent, Response
  • Server Info: ServerInfoUser, ServerInfoDeckStorageFile, ServerInfoDeckStorageFolder, ServerInfoDeckStorageTreeItem, ServerInfoCard, ServerInfoZone, ServerInfoGame

Imports From:

  • pydantic: BaseModel
  • typing: Optional, List, Dict, Any
  • datetime: datetime

Imported By:

  • None (unused)

Dependencies: None (standalone)

⚠️ ISSUE: Protocol buffer messages defined but not used anywhere.


4.12 protocol_constants.py (170 lines)

Purpose: MTG Online protocol constants

Key Classes:

  • SessionCommandType: Session command types (PING, LOGIN, MESSAGE, etc.)
  • GameCommandType: Game command types (KICK, LEAVE, SHUFFLE, etc.)
  • GameEventType: Game event types (JOIN, LEAVE, DRAW_CARDS, etc.)
  • ResponseCode: Response codes (RespOk, RespInvalidCommand, etc.)
  • ZoneType: Zone types (PrivateZone, PublicZone, HiddenZone)
  • UserLevelFlag: User level flags (IsUser, IsModerator, IsAdmin, etc.)

Imports From:

  • enum: IntEnum, IntFlag

Imported By:

  • None (unused)

Dependencies: None (standalone)

⚠️ ISSUE: Protocol constants defined but not used anywhere.


5. Services Layer (app/services/)

Purpose: Business logic and data processing

5.1 __init__.py (60 lines)

Purpose: Exports all services

Imports From:

  • app.services.deck_parser: DeckParser
  • app.services.card_database: Various card database functions
  • app.services.card_mirror_service: Mirror service functions
  • app.services.mtgjson_manager: MTGJSONManager, get_manager
  • app.services.mtgjson_downloader: Download functions
  • app.services.mtgjson_loader: Loader functions
  • app.services.mtgjson_uploader: Uploader functions
  • app.services.file_parser: FileParser
  • app.services.fuzzy_card_matcher: FuzzyCardMatcher
  • app.services.import_batch_processor: ImportBatchProcessor
  • app.services.deck_manager: DeckManager
  • app.services.card_search_service: CardSearchService
  • app.services.deck_suggestion_service: DeckSuggestionService

Imported By:

  • Various routers

Dependencies: All service modules


5.2 card_database.py (350 lines)

Purpose: MTG card database queries

Key Functions:

  • search_cards(): Search cards by name/type/mana cost
  • get_card_by_name(): Get card by name
  • get_cards_by_set(): Get cards by set
  • get_card_types(): Get all card types
  • get_card_rarities(): Get all rarities
  • get_sets(): Get all sets
  • get_set_by_code(): Get set by code
  • get_card_statistics(): Get database statistics

Imports From:

  • app.models.mtg_models: MtgCard, MtgSet
  • app.core.database: mtg_get_db
  • sqlalchemy: select, and_, or_, func
  • sqlalchemy.orm: selectinload

Imported By:

  • routers/card_router.py

Dependencies: models/mtg_models.py, core/database.py


5.3 card_mirror_service.py (359 lines)

Purpose: Card mirror service for fast deckbuilding queries

Key Functions:

  • upsert_card_mirror(): Upsert card to mirror
  • get_card_mirror_by_name(): Get mirror by name
  • search_card_mirrors(): Search mirrors
  • add_card_to_deck(): Add card to deck
  • remove_card_from_deck(): Remove card from deck
  • get_deck_cards(): Get deck cards
  • get_user_deck_summaries(): Get user deck summaries
  • sync_mirrors_from_mtg_cards(): Sync mirrors
  • get_card_statistics(): Get mirror statistics

Imports From:

  • app.models.mtg_models: MtgCard, MtgSet
  • app.models.mirror_models: MtgCardMirror, DeckCardLink
  • app.core.database: mirror_get_db
  • sqlalchemy: select, func, update, delete
  • sqlalchemy.orm: selectinload

Imported By:

  • None (unused)

Dependencies: models/mtg_models.py, core/database.py

⚠️ ISSUE: Service defined but not used anywhere.


5.4 card_search_service.py (190 lines)

Purpose: Card search with filters

Key Classes/Functions:

  • CardSearchService.search_cards(): Search with filters
  • CardSearchService.get_card_by_id(): Get by ID
  • CardSearchService.get_sets(): Get all sets
  • CardSearchService.get_card_types(): Get card types
  • CardSearchService.get_card_rarities(): Get rarities

Imports From:

  • app.models.mtg_models: MtgCard, MtgSet
  • app.models.mirror_models: MtgCardMirror
  • sqlalchemy: select, or_, and_
  • sqlalchemy.orm: selectinload

Imported By:

  • routers/card_router.py
  • routers/cards_router.py

Dependencies: models/mtg_models.py, sqlalchemy


5.5 deck_manager.py (246 lines)

Purpose: Deck CRUD operations

Key Classes/Functions:

  • DeckManager.create_deck(): Create deck
  • DeckManager.get_deck(): Get deck
  • DeckManager.list_decks(): List decks
  • DeckManager.update_deck(): Update deck
  • DeckManager.delete_deck(): Delete deck
  • DeckManager.finalize_deck(): Finalize deck
  • DeckManager.add_card_to_deck(): Add card
  • DeckManager.get_deck_cards(): Get deck cards
  • DeckManager.update_deck_card(): Update card
  • DeckManager.remove_card_from_deck(): Remove card
  • DeckManager.clone_precedent(): Clone precedent

Imports From:

  • app.models.user_deck: UserDeck, UserDeckCard, DeckPrecedent, DeckPrecedentCard
  • app.models.models: MtgonlineCard
  • sqlalchemy: select, update, delete
  • sqlalchemy.orm: selectinload

Imported By:

  • routers/decks.py
  • routers/decks_router.py

Dependencies: models/user_deck.py, models/models.py, sqlalchemy


5.6 deck_parser.py (206 lines)

Purpose: Deck list parsing and serialization

Key Classes/Functions:

  • CardInfo: Dataclass for card information
  • DeckParser.parse_plain_text(): Parse plain text
  • DeckParser.format_plain_text(): Format as plain text
  • DeckParser.to_native_xml(): Convert to XML
  • DeckParser.from_native_xml(): Parse XML
  • parse_deck(): Convenience function
  • format_deck(): Convenience function

Imports From:

  • re: Regex patterns
  • typing: List, Dict, Tuple, Optional
  • dataclasses: dataclass

Imported By:

  • routers/decks.py
  • routers/decks_router.py

Dependencies: None (standalone)


5.7 deck_suggestion_service.py (209 lines)

Purpose: Card suggestion service

Key Classes/Functions:

  • DeckSuggestionService.suggest_cards(): Suggest cards
  • DeckSuggestionService.add_suggestion(): Add suggestion
  • DeckSuggestionService.get_deck_suggestions(): Get suggestions

Imports From:

  • app.models.user_deck: UserDeck, UserDeckCard, CardSuggestion
  • app.models.mtg_models: MtgCard
  • app.models.mirror_models: MtgCardMirror
  • app.services.fuzzy_card_matcher: FuzzyCardMatcher
  • sqlalchemy: select, or_, and_, func, case
  • sqlalchemy.orm: selectinload

Imported By:

  • routers/card_router.py
  • routers/cards_router.py

Dependencies: models/user_deck.py, models/mtg_models.py, services/fuzzy_card_matcher.py, sqlalchemy


5.8 file_parser.py (108 lines)

Purpose: File parser for card imports

Key Classes/Functions:

  • FileParser.parse_file(): Parse file (CSV, JSON, XLSX, ODS)
  • FileParser._parse_csv(): Parse CSV
  • FileParser._parse_json(): Parse JSON
  • FileParser._parse_xlsx(): Parse XLSX
  • FileParser._parse_ods(): Parse ODS

Imports From:

  • csv, json: Stdlib
  • pathlib: Path
  • openpyxl: XLSX parsing
  • pandas: ODS parsing

Imported By:

  • routers/card_import.py
  • routers/user_data_router.py

Dependencies: openpyxl, pandas


5.9 fuzzy_card_matcher.py (170 lines)

Purpose: Fuzzy matching for card names

Key Classes/Functions:

  • FuzzyCardMatcher.normalize_card_name(): Normalize name
  • FuzzyCardMatcher.exact_match(): Exact match
  • FuzzyCardMatcher.fuzzy_match(): Fuzzy match
  • FuzzyCardMatcher.find_best_match(): Find best match
  • FuzzyCardMatcher.batch_match(): Batch match
  • FuzzyCardMatcher.batch_match_with_database(): Match with DB

Imports From:

  • thefuzz: fuzz
  • typing: List, Tuple, Optional

Imported By:

  • routers/card_router.py
  • routers/cards_router.py
  • routers/card_import.py
  • routers/user_data_router.py
  • services/deck_suggestion_service.py
  • services/import_batch_processor.py

Dependencies: thefuzz


5.10 import_batch_processor.py (204 lines)

Purpose: Batch import processing

Key Classes/Functions:

  • ImportBatchProcessor.create_batch(): Create batch
  • ImportBatchProcessor.process_batch(): Process batch
  • ImportBatchProcessor.get_batch_status(): Get status
  • ImportBatchProcessor.get_batch_results(): Get results
  • ImportBatchProcessor.confirm_batch(): Confirm batch
  • ImportBatchProcessor.get_user_imports(): Get user imports
  • ImportBatchProcessor.delete_batch(): Delete batch

Imports From:

  • app.models.card_import_batch: CardImportBatch
  • app.models.user_card_import_record: UserCardImportRecord
  • app.models.user_data: UserCardCollection
  • app.models.models: MtgonlineCard
  • app.services.fuzzy_card_matcher: FuzzyCardMatcher
  • sqlalchemy: select, update, insert, delete
  • sqlalchemy.sql: func

Imported By:

  • routers/card_import.py
  • routers/user_data_router.py

Dependencies: models/card_import_batch.py, models/user_card_import_record.py, models/user_data.py, models/models.py, services/fuzzy_card_matcher.py, sqlalchemy


5.11 game_server.py (309 lines)

Purpose: WebSocket game server for real-time gameplay

Key Classes/Functions:

  • GameRoom: Manages single game room
  • GameServer: Manages all game rooms
  • game_websocket_endpoint(): WebSocket endpoint
  • process_game_command(): Process commands

Imports From:

  • asyncio: Lock
  • json: Serialization
  • typing: Dict, Set, Optional
  • datetime: datetime
  • fastapi: WebSocket, WebSocketDisconnect

Imported By:

  • routers/games_router.py
  • routers/ws.py

Dependencies: fastapi


5.12 mtgjson_downloader.py (137 lines)

Purpose: MTGJSON data downloader

Key Functions:

  • get_downloads_dir(): Get downloads directory
  • download_file(): Download single file
  • download_all_files(): Download all files
  • verify_downloads(): Verify downloads
  • get_file_list(): Get file list

Imports From:

  • gzip, json, os, sys: Stdlib
  • pathlib: Path
  • urllib.request: urlretrieve
  • urllib.parse: urljoin

Imported By:

  • services/__init__.py

Dependencies: None (standalone)


5.13 mtgjson_loader.py (838 lines)

Purpose: MTGJSON data loader (legacy)

Key Functions:

  • create_tables(): Create tables
  • download_file(): Download file
  • extract_zip(): Extract zip
  • get_all_printings_psql_file(): Get PSQL file
  • parse_psql_file(): Parse PSQL
  • import_cards(): Import cards
  • import_all_printings_psql(): Import AllPrintings
  • import_all_set_files(): Import set files
  • import_all_identifiers(): Import identifiers
  • import_all_deck_files(): Import deck files
  • import_simple_json(): Import JSON
  • create_indexes(): Create indexes
  • show_summary(): Show summary
  • main(): Main function

Imports From:

  • app.core.settings: get_settings
  • sqlalchemy.ext.asyncio: create_async_engine, AsyncSession
  • sqlalchemy.orm: sessionmaker
  • sqlalchemy: text, insert, update, select, Table, Column, etc.
  • sqlalchemy.dialects.postgresql: insert as pg_insert

Imported By:

  • services/__init__.py

Dependencies: core/settings.py, sqlalchemy


5.14 mtgjson_manager.py (1296 lines)

Purpose: MTGJSON data manager (local file processing)

Key Classes/Functions:

  • MTGJSONManager: Main manager class
  • get_last_refresh(): Get last refresh
  • get_health_status(): Get health status
  • check_required_files(): Check files
  • upsert_all(): Upsert all data
  • _upsert_sets(): Upsert sets
  • _upsert_cards(): Upsert cards
  • _upsert_cards_from_psql(): Upsert from PSQL
  • _upsert_identifiers(): Upsert identifiers
  • _upsert_card_types(): Upsert card types
  • _upsert_keywords(): Upsert keywords
  • _upsert_set_list(): Upsert set list
  • _upsert_deck_list(): Upsert deck list
  • _upsert_deck_files_from_zip(): Upsert deck files
  • log_refresh(): Log refresh
  • sync_mirrors(): Sync mirrors
  • run_refresh(): Run refresh
  • download_files(): Download files
  • verify_files(): Verify files
  • download_and_refresh(): Download and refresh
  • get_manager(): Get manager instance

Imports From:

  • app.core.database: mtg_async_session
  • json, logging, zipfile, tempfile, shutil: Stdlib
  • pathlib: Path
  • datetime: datetime
  • typing: Optional, Dict, List, Tuple
  • re: Regex
  • aiohttp: ClientSession, ClientTimeout
  • asyncio: sleep
  • gzip: Decompression
  • sqlalchemy: text

Imported By:

  • routers/games_router.py
  • routers/refresh.py
  • services/__init__.py

Dependencies: core/database.py, aiohttp, sqlalchemy


5.15 mtgjson_uploader.py (883 lines)

Purpose: MTGJSON data uploader (legacy)

Key Functions:

  • create_tables(): Create tables
  • import_all_printings_psql(): Import PSQL
  • import_all_set_files(): Import set files
  • import_all_identifiers(): Import identifiers
  • import_all_deck_files(): Import deck files
  • import_json_files(): Import JSON
  • download_file(): Download file
  • extract_zip(): Extract zip
  • main(): Main function

Imports From:

  • app.core.settings: get_settings
  • sqlalchemy.ext.asyncio: create_async_engine, AsyncSession
  • sqlalchemy.orm: sessionmaker
  • sqlalchemy: text, insert, update, select, and_, Table, MetaData, Column, etc.
  • sqlalchemy.dialects.postgresql: insert as pg_insert
  • gzip, json, os, sys, zipfile: Stdlib
  • pathlib: Path
  • datetime: datetime
  • typing: Any
  • urllib.request: urlretrieve

Imported By:

  • services/__init__.py

Dependencies: core/settings.py, sqlalchemy


Dependency Graph Summary

┌─────────────────────────────────────────────────────────────────────────┐
│                         DEPENDENCY GRAPH                                │
└─────────────────────────────────────────────────────────────────────────┘

core/
├── config.py (standalone)
│   └── imported by: database.py, security.py, settings.py
│
├── database.py
│   ├── imports: config.py
│   └── imported by: models/, routers/*, services/*
│
├── logging.py (standalone)
│   └── imported by: services/*
│
├── logging_config.py (DUPLICATE of logging.py)
│
├── redis_client.py
│   ├── imports: settings.py
│   └── imported by: routers/card_router.py, cards_router.py, interactions.py
│
├── security.py
│   ├── imports: config.py
│   └── imported by: routers/auth.py, auth_router.py, users.py, users_router.py, admin.py, rooms.py, games_router.py
│
└── settings.py
    ├── imports: config.py
    └── imported by: redis_client.py, services/mtgjson_loader.py, services/mtgjson_uploader.py

models/
├── models.py
│   ├── imports: database.py
│   └── imported by: models/__init__.py, routers/*, services/*
│
├── mtg_models.py
│   ├── imports: database.py
│   └── imported by: models/__init__.py, routers/card_router.py, cards_router.py, services/card_search_service.py, services/deck_suggestion_service.py
│
└── __init__.py
    ├── imports: models.py, mtg_models.py
    └── imported by: routers/*, services/*

routers/
├── auth.py (OLD - superseded by auth_router.py)
├── auth_router.py
│   ├── imports: database.py, security.py, models.py, schemas.py
│   └── imported by: app/main.py
│
├── users.py (OLD - superseded by users_router.py)
├── users_router.py
│   ├── imports: database.py, security.py, models.py, schemas.py
│   └── imported by: app/main.py
│
├── decks.py (OLD - superseded by decks_router.py)
├── decks_router.py
│   ├── imports: database.py, security.py, models.py, models/mtg_models.py, models/user_deck.py, services/deck_manager.py, services/deck_parser.py
│   └── imported by: app/main.py
│
├── card_router.py (OLD - superseded by cards_router.py)
├── cards_router.py
│   ├── imports: database.py, redis_client.py, models.py, models/user_deck.py, schemas/card_search_schemas.py, services/card_search_service.py, services/deck_suggestion_service.py, services/fuzzy_card_matcher.py
│   └── imported by: app/main.py
│
├── interactions.py (OLD - superseded by cards_router.py)
├── user_data.py (OLD - superseded by user_data_router.py)
├── user_data_router.py
│   ├── imports: database.py, security.py, models.py, models/user_data.py, models/card_import_batch.py, models/user_card_import_record.py, models/user_deck.py, services/file_parser.py, services/import_batch_processor.py, services/fuzzy_card_matcher.py, schemas/*
│   └── imported by: app/main.py
│
├── rooms.py (OLD - superseded by games_router.py)
├── games/__init__.py
├── games/router.py (OLD - superseded by games_router.py)
├── games_router.py
│   ├── imports: database.py, security.py, models.py, schemas.py, services/mtgjson_manager.py, services/game_server.py
│   └── imported by: app/main.py
│
├── refresh.py (OLD - superseded by games_router.py)
├── card_import.py (OLD - superseded by user_data_router.py)
├── ws.py (OLD - superseded by games_router.py)
│
└── __init__.py
    ├── imports: auth_router.py, users_router.py, decks_router.py, cards_router.py, user_data_router.py, games_router.py
    └── imported by: app/main.py

schemas/
├── schemas.py (standalone)
│   └── imported by: routers/auth.py, auth_router.py, users.py, users_router.py, rooms.py, games_router.py
│
├── user_data_schemas.py (standalone)
│   └── imported by: routers/user_data.py, user_data_router.py
│
├── user_deck_schemas.py (standalone)
│   └── imported by: routers/decks.py, decks_router.py, card_import.py
│
├── user_card_collection.py (standalone)
│   └── imported by: routers/user_data.py, user_data_router.py
│
├── card_import_schemas.py (standalone)
│   └── imported by: routers/card_import.py, user_data_router.py
│
├── card_search_schemas.py (standalone)
│   └── imported by: routers/card_router.py, cards_router.py
│
├── mtg_card_schemas.py (standalone)
│   └── imported by: routers/cards_router.py
│
├── game_schemas.py (standalone)
│   └── imported by: routers/games_router.py
│
├── generic_schemas.py (standalone)
│   └── imported by: routers/user_data.py, user_data_router.py
│
├── proto_messages.py (UNUSED)
├── protocol_constants.py (UNUSED)
│
└── __init__.py
    ├── imports: all schema files
    └── imported by: routers/*, services/*

services/
├── card_database.py
│   ├── imports: models/mtg_models.py, core/database.py
│   └── imported by: routers/card_router.py
│
├── card_mirror_service.py (UNUSED)
│   ├── imports: models/mtg_models.py, models/mirror_models.py, core/database.py
│
├── card_search_service.py
│   ├── imports: models/mtg_models.py, models/mirror_models.py
│   └── imported by: routers/card_router.py, cards_router.py
│
├── deck_manager.py
│   ├── imports: models/user_deck.py, models/models.py
│   └── imported by: routers/decks.py, decks_router.py
│
├── deck_parser.py (standalone)
│   └── imported by: routers/decks.py, decks_router.py
│
├── deck_suggestion_service.py
│   ├── imports: models/user_deck.py, models/mtg_models.py, models/mirror_models.py, services/fuzzy_card_matcher.py
│   └── imported by: routers/card_router.py, cards_router.py
│
├── file_parser.py
│   ├── imports: csv, json, pathlib, openpyxl, pandas
│   └── imported by: routers/card_import.py, user_data_router.py
│
├── fuzzy_card_matcher.py
│   ├── imports: thefuzz
│   └── imported by: routers/card_router.py, cards_router.py, card_import.py, user_data_router.py, services/deck_suggestion_service.py, services/import_batch_processor.py
│
├── import_batch_processor.py
│   ├── imports: models/card_import_batch.py, models/user_card_import_record.py, models/user_data.py, models/models.py, services/fuzzy_card_matcher.py
│   └── imported by: routers/card_import.py, user_data_router.py
│
├── game_server.py
│   ├── imports: asyncio, json, typing, datetime, fastapi
│   └── imported by: routers/games_router.py, routers/ws.py
│
├── mtgjson_downloader.py (standalone)
│   └── imported by: services/__init__.py
│
├── mtgjson_loader.py (LEGACY)
│   ├── imports: core/settings.py, sqlalchemy
│   └── imported by: services/__init__.py
│
├── mtgjson_manager.py
│   ├── imports: core/database.py, aiohttp, sqlalchemy
│   └── imported by: routers/games_router.py, routers/refresh.py, services/__init__.py
│
├── mtgjson_uploader.py (LEGACY)
│   ├── imports: core/settings.py, sqlalchemy
│   └── imported by: services/__init__.py
│
└── __init__.py
    ├── imports: all service modules
    └── imported by: routers/*

Critical Issues Summary

1. Router Duplication (HIGH PRIORITY)

Every major feature has both old and new implementations:

  • auth.py vs auth_router.py
  • users.py vs users_router.py
  • decks.py vs decks_router.py
  • card_router.py vs cards_router.py
  • interactions.py vs cards_router.py (interactions)
  • user_data.py vs user_data_router.py
  • rooms.py vs games_router.py (rooms)
  • games/router.py vs games_router.py (games)
  • refresh.py vs games_router.py (refresh)
  • card_import.py vs user_data_router.py (import)
  • ws.py vs games_router.py (websocket)

Recommendation: Remove all old versions and keep only the _router.py versions.

2. Logging Duplication (MEDIUM PRIORITY)

  • logging.py and logging_config.py are exact duplicates

Recommendation: Remove logging_config.py.

3. Settings Shim (LOW PRIORITY)

  • settings.py is just a backward compatibility shim for config.py

Recommendation: Remove once all callers migrate to config.py.

4. Unused Code (LOW PRIORITY)

  • services/card_mirror_service.py: Defined but not used
  • schemas/proto_messages.py: Protocol buffer messages defined but not used
  • schemas/protocol_constants.py: Protocol constants defined but not used

Recommendation: Remove or implement if needed.

5. Model Inconsistency (MEDIUM PRIORITY)

  • Multiple model files with overlapping functionality
  • models/user_deck.py, models/user_data.py, models/card_import_batch.py, etc. exist but models.py consolidates many of these

Recommendation: Consolidate all models into models.py and mtg_models.py.

6. Service Redundancy (MEDIUM PRIORITY)

  • mtgjson_loader.py and mtgjson_uploader.py are legacy scripts
  • mtgjson_manager.py is the current implementation

Recommendation: Remove legacy scripts.


Phase 1: Remove Duplicates

  1. Remove old router files (auth.py, users.py, decks.py, card_router.py, interactions.py, user_data.py, rooms.py, games/router.py, refresh.py, card_import.py, ws.py)
  2. Remove logging_config.py
  3. Remove settings.py (migrate callers to config.py)

Phase 2: Consolidate Models

  1. Move all models from user_deck.py, user_data.py, card_import_batch.py, etc. into models.py
  2. Remove individual model files

Phase 3: Clean Up Services

  1. Remove card_mirror_service.py (unused)
  2. Remove mtgjson_loader.py and mtgjson_uploader.py (legacy)
  3. Remove proto_messages.py and protocol_constants.py (unused)

Phase 4: Standardize Patterns

  1. Ensure all routers use consistent patterns
  2. Ensure all services use consistent patterns (ORM vs raw SQL)
  3. Add type hints and docstrings where missing

Statistics

  • Total Files Analyzed: 50+
  • Total Lines of Code: ~30,000+
  • Old Router Files (to remove): 11
  • New Router Files (to keep): 6
  • Duplicate Files: 2 (logging, settings)
  • Unused Files: 4 (card_mirror_service, proto_messages, protocol_constants, mtgjson_loader/uploader)

Conclusion

The MTG Online backend has significant architectural debt with multiple layers of duplication. The codebase is in a transition state where new consolidated routers and services have been created but old versions still exist.

Immediate Actions:

  1. Remove all old router files (11 files)
  2. Remove duplicate logging config
  3. Remove unused schema files
  4. Consolidate models

Long-term:

  1. Standardize on ORM or raw SQL (currently mixed)
  2. Add comprehensive tests
  3. Improve error handling
  4. Add proper logging throughout

The project is functional but needs cleanup to be maintainable.