--- # nuzlocke-tracker-l7e3 title: Database Schema Design status: completed type: task priority: normal created_at: 2026-02-04T15:46:54Z updated_at: 2026-02-05T12:29:19Z parent: nuzlocke-tracker-f5ob blocking: - nuzlocke-tracker-bkhs - nuzlocke-tracker-k5lm - nuzlocke-tracker-hy41 --- Design and implement the database schema for persistent storage. ## Decisions - **Database**: PostgreSQL 16 (already in docker-compose) - **ORM**: SQLAlchemy 2.0 (async) with asyncpg driver - **Migrations**: Alembic - **Async**: Full async — asyncpg + async SQLAlchemy sessions ## Checklist - [x] Choose database (PostgreSQL) - [x] Set up database connection and ORM/query builder (SQLAlchemy 2.0 async + asyncpg) - [x] Design and create tables/collections: - [x] Games (id, name, slug, generation, region, box_art_url, release_year) - [x] Routes (id, name, game_id, order) - [x] Pokemon (id, national_dex, name, types[], sprite_url) - [x] RouteEncounters (id, route_id, pokemon_id, encounter_method, encounter_rate) — unique(route, pokemon, method) - [x] NuzlockeRuns (id, game_id, name, status, rules jsonb, started_at, completed_at) - [x] Encounters (id, run_id, route_id, pokemon_id, nickname, status, catch_level, faint_level, caught_at) - [x] Set up migrations system (Alembic) - [ ] Add seed data for initial games/routes/Pokémon - [x] Create indexes for common queries (FK indexes on routes, route_encounters, nuzlocke_runs, encounters; status index on nuzlocke_runs) ## Notes - Use foreign keys for referential integrity - Status fields should be enums - Use PostgreSQL enums or check constraints for status/type fields