- Remove card_1..card_26 FK columns from Roster ORM model
- Add RosterSlot model with (roster, slot, card) and a unique index on (roster, slot)
- Activate get_cards() helper on Roster using the new junction table
- Register RosterSlot in create_tables for SQLite dev environments
- Add migrations/migrate_roster_junction_table.py to backfill existing data
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Support the Discord bot's new scouting feature where players can scout
cards from other teams' opened packs. Stores opportunities with expiry
timestamps and tracks which teams claim which cards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add explanatory comment clarifying that synchronous=OFF is a dev-only
trade-off (production uses PostgreSQL), and describing the crash-corruption
risk and how WAL mode partially mitigates it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moved logging.basicConfig() to app/main.py as the single source of truth.
Removed duplicate (no-op) calls from app/db_engine.py, app/dependencies.py,
and all 30 router files in app/routers_v2/. Removed the now-unused LOG_DATA
dict and date/log_level locals from dependencies.py and db_engine.py.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added missing 'human' key to gauntlet-9 cardset configuration.
This was causing 500 errors when players tried to start gauntlet
games because the legal-check endpoint couldn't validate cards.
Error: KeyError: 'human' at app/routers_v2/cards.py:242
when checking CARDSETS[rarity_name]['human']
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add explicit ORDER BY id to all queries for consistent results across SQLite and PostgreSQL
- PostgreSQL does not guarantee row order without ORDER BY, unlike SQLite
- Skip table creation when DATABASE_TYPE=postgresql (production tables already exist)
- Fix datetime handling in notifications (PostgreSQL native datetime vs SQLite timestamp)
- Fix grouped query count() calls that don't work in PostgreSQL
- Update .gitignore to include storage/templates/ directory
This completes the PostgreSQL migration compatibility layer while maintaining
backwards compatibility with SQLite for local development.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
PostgreSQL does not guarantee row order without ORDER BY, unlike SQLite
which implicitly returned rows by rowid. This caused bugs where queries
returned results in unexpected order (e.g., get_team_by_owner returning
gauntlet team instead of main team).
Override select() in BaseModel to add default ordering by id. Explicit
.order_by() calls will override this default.
Also mark legacy db_engine.py as deprecated.
- Add 2018 Promos (14) and 2022 Promos (4) to flashback mode legal cardsets
- Convert Unix timestamps to datetime in rewards POST/PATCH for PostgreSQL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix NULL handling for FK checks in stratplays.py: use x.field_id instead
of x.field to avoid triggering FK lookups on potentially missing rows
- Cast boolean is_start to integer for SUM() - PostgreSQL cannot sum booleans
- Add missing GROUP BY clause to Decision aggregate query
- Add Case import for boolean-to-integer casting
- Update migration script with boolean/datetime column mappings
- Exclude legacy battingstat/pitchingstat tables from migration
- Add comprehensive POSTGRES_MIGRATION_GUIDE.md documentation
Tested: /plays/batting and /plays/pitching endpoints work with group_by=player
- Add environment-based PostgreSQL configuration to db_engine.py
- Add table_name to all 30 models (Meta class)
- Update db_migrations.py to auto-select migrator based on DB type
- Add comprehensive PostgreSQL migration plan document