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
261 lines
8.4 KiB
JSON
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"]
|
|
}
|