mantimon-tcg/backend/PROJECT_PLAN_MASTER.json
Cal Corum 50684a1b11 Add database infrastructure with SQLAlchemy models and test suite
Phase 1 Database Implementation (DB-001 through DB-012):

Models:
- User: OAuth support (Google/Discord), premium subscriptions
- Collection: Card ownership with CardSource enum
- Deck: JSONB cards/energy_cards, validation state
- CampaignProgress: One-to-one with User, medals/NPCs as JSONB
- ActiveGame: In-progress games with GameType enum
- GameHistory: Completed games with EndReason enum, replay data

Infrastructure:
- Alembic migrations with sync psycopg2 (avoids async issues)
- Docker Compose for Postgres (5433) and Redis (6380)
- App config with Pydantic settings
- Redis client helper

Test Infrastructure:
- 68 database tests (47 model + 21 relationship)
- Async factory pattern for test data creation
- Sync TRUNCATE cleanup (solves pytest-asyncio event loop mismatch)
- Uses dev containers instead of testcontainers for reliability

Key technical decisions:
- passive_deletes=True for ON DELETE SET NULL relationships
- NullPool for test sessions (no connection reuse)
- expire_on_commit=False with manual expire() for relationship tests
2026-01-27 10:17:30 -06:00

261 lines
8.4 KiB
JSON

{
"meta": {
"version": "1.0.0",
"created": "2026-01-27",
"lastUpdated": "2026-01-27",
"planType": "master",
"projectName": "Mantimon TCG - Backend Services",
"description": "Live service backend for play.mantimon.com - server-authoritative multiplayer TCG with campaign mode, free-play, and F2P monetization",
"totalPhases": 6,
"completedPhases": 1,
"status": "Phase 0 complete, Phase 1 in progress"
},
"architectureDecisions": {
"deployment": "Online-first live service at play.mantimon.com",
"database": "PostgreSQL 15+ for durable storage",
"cache": "Redis 7+ for game state, matchmaking, sessions",
"gameState": "Redis primary (fast), Postgres write-behind at turn boundaries",
"api": "FastAPI REST + python-socketio WebSocket",
"auth": "OAuth 2.0 (Google, Discord) with JWT sessions",
"cardData": "Bundled JSON in repo, loaded at runtime",
"offlineSupport": "Core engine forkable, full offline mode deferred",
"replayData": "Capture from start for future replay feature"
},
"businessRules": {
"monetization": {
"model": "F2P with optional purchases",
"fullCollectionF2P": true,
"premiumFeatures": ["cosmetics", "convenience", "battle_pass"],
"premiumDuration": "time-limited (subscription style)",
"noPay2Win": true
},
"currency": {
"name": "Mantibucks",
"symbol": "₼"
},
"deckLimits": {
"free": 5,
"premium": "unlimited"
},
"starterDecks": {
"count": 5,
"types": ["grass", "fire", "water", "psychic", "lightning"],
"rotation": "Two deck types rotate with current set releases",
"classic": ["grass", "fire", "water"],
"rotating": ["psychic", "lightning"]
},
"boosterPacks": {
"structure": "X slots per pack, each slot has individual rarity probabilities",
"acquisition": ["campaign_wins", "daily_rewards", "purchases"]
},
"energyDeck": {
"default": true,
"configurable": true,
"note": "Mantimon house rules default, standard Pokemon TCG supported"
},
"deckValidation": {
"campaign": "Requires card ownership",
"freeplay": "Full collection unlocked"
}
},
"phases": [
{
"id": "PHASE_0",
"name": "Core Game Engine",
"status": "COMPLETE",
"description": "Pure game logic - GameEngine, models, effects, validation, turn management",
"planFile": "PROJECT_PLAN.json",
"deliverables": [
"GameEngine orchestrator",
"RulesConfig system",
"All action types and validation",
"Effect handler system with 12 built-in handlers",
"Turn manager with status conditions",
"Win condition checker",
"Visibility filter (hidden info security)",
"Card scraper with 372 cards + images",
"833 tests at 97% coverage"
],
"completedDate": "2026-01-27"
},
{
"id": "PHASE_1",
"name": "Database + Infrastructure",
"status": "IN_PROGRESS",
"description": "PostgreSQL models, Redis caching, CardService, environment config",
"planFile": "project_plans/PHASE_1_DATABASE.json",
"estimatedWeeks": "2-3",
"dependencies": ["PHASE_0"],
"deliverables": [
"SQLAlchemy async models",
"Alembic migrations",
"Redis connection utilities",
"GameStateManager (Redis + Postgres write-behind)",
"CardService (JSON → CardDefinition)",
"Environment config (dev/staging/prod)",
"Docker compose for local dev"
]
},
{
"id": "PHASE_2",
"name": "Authentication",
"status": "NOT_STARTED",
"description": "OAuth login, JWT sessions, user management",
"planFile": "project_plans/PHASE_2_AUTH.json",
"estimatedWeeks": "1-2",
"dependencies": ["PHASE_1"],
"deliverables": [
"OAuth integration (Google, Discord)",
"JWT token management",
"User creation/login endpoints",
"Session middleware",
"Account linking (multiple providers)",
"Premium tier with expiration tracking"
]
},
{
"id": "PHASE_3",
"name": "Collections + Decks",
"status": "NOT_STARTED",
"description": "Card ownership, deck building, starter deck selection",
"planFile": "project_plans/PHASE_3_COLLECTION_DECKS.json",
"estimatedWeeks": "1-2",
"dependencies": ["PHASE_2"],
"deliverables": [
"CollectionService (owned cards CRUD)",
"DeckService (create, edit, validate, delete)",
"Mode-aware deck validation (owned vs full collection)",
"Deck slot limits (free vs premium)",
"Starter deck selection flow",
"5 starter deck definitions",
"REST endpoints"
]
},
{
"id": "PHASE_4",
"name": "Game Service + WebSocket",
"status": "NOT_STARTED",
"description": "Real-time gameplay, reconnection, turn timeouts",
"planFile": "project_plans/PHASE_4_GAME_SERVICE.json",
"estimatedWeeks": "2-3",
"dependencies": ["PHASE_3"],
"deliverables": [
"WebSocket connection manager",
"Message protocol specification",
"GameService (create, execute, persist, resume)",
"Turn-boundary persistence to Postgres",
"Reconnection handling",
"Turn timeout system",
"Replay data capture",
"Spectator mode (optional)"
]
},
{
"id": "PHASE_5",
"name": "Campaign Mode",
"status": "NOT_STARTED",
"description": "Single-player experience with NPCs, progression, rewards",
"planFile": "project_plans/PHASE_5_CAMPAIGN.json",
"estimatedWeeks": "3-4",
"dependencies": ["PHASE_4"],
"deliverables": [
"Club and NPC data structures",
"CampaignService (progression, save/load)",
"AI system (RuleBasedAI, DifficultyScaledAI)",
"NPC deck definitions",
"Reward system (medals, booster packs, Mantibucks)",
"Booster pack opening with slot-based rarities",
"Campaign REST endpoints"
]
},
{
"id": "PHASE_6",
"name": "Free-Play Multiplayer",
"status": "NOT_STARTED",
"description": "PvP matchmaking, custom rules, ranked mode",
"planFile": "project_plans/PHASE_6_MULTIPLAYER.json",
"estimatedWeeks": "2-3",
"dependencies": ["PHASE_4"],
"deliverables": [
"Matchmaking queue (Redis-backed)",
"Invite link system (private games)",
"RulesConfig customization API",
"Match history",
"Ranked mode with Elo/MMR (optional)",
"Leaderboards (optional)"
]
}
],
"futurePhases": [
{
"id": "FUTURE_P2P",
"name": "P2P Multiplayer",
"description": "Peer-to-peer for offline/LAN play (host-authoritative)",
"priority": "nice-to-have"
},
{
"id": "FUTURE_REPLAYS",
"name": "Replay System",
"description": "Playback recorded games (data captured from Phase 4)",
"priority": "nice-to-have"
},
{
"id": "FUTURE_ML_AI",
"name": "ML-Based AI",
"description": "Neural network opponents",
"priority": "nice-to-have"
},
{
"id": "FUTURE_OFFLINE",
"name": "Offline Fork",
"description": "Standalone offline package with SQLite",
"priority": "nice-to-have"
},
{
"id": "FUTURE_TRADING",
"name": "Trading System",
"description": "Player-to-player card trading",
"priority": "nice-to-have"
},
{
"id": "FUTURE_TOURNAMENTS",
"name": "Tournament Mode",
"description": "Organized competitive events",
"priority": "nice-to-have"
}
],
"infrastructure": {
"required": {
"postgresql": "15+",
"redis": "7+",
"python": "3.11+"
},
"development": {
"docker": "Docker compose for local Postgres + Redis",
"testing": "pytest-asyncio, testcontainers"
},
"production": {
"deployment": "Kubernetes (future)",
"cdn": "Card images served via CDN",
"monitoring": "TBD"
}
},
"securityConsiderations": [
"All game logic server-authoritative",
"Hidden information never sent to clients (from Phase 0)",
"OAuth tokens never stored, only OAuth IDs",
"JWT tokens short-lived with refresh mechanism",
"Rate limiting on all endpoints",
"Action validation on every request (from Phase 0)"
],
"totalEstimatedWeeks": "12-17",
"criticalPath": ["PHASE_1", "PHASE_2", "PHASE_3", "PHASE_4", "PHASE_5"]
}