feat: MTG database integration with Redis caching

- Added MTG card ORM models (mtg_cards, mtg_sets tables)
- Created card_database service with search, get_by_name, get_by_set
- Added Redis client with caching layer (3600s TTL default)
- Created card router with caching on all endpoints:
  - Search cards (5min cache)
  - Get card by name (10min cache)
  - Get cards by set (15min cache)
  - Get card types/rarities (30min cache)
  - Get sets (1hr cache)
  - Get statistics (1hr cache)
- Updated settings.py:
  - Added JWT_SECRET_KEY field
  - Added DB_CONFIG and REDIS_CONFIG dictionaries
- Updated security.py to use JWT_SECRET_KEY with fallback
- Updated auth.py to use timezone-aware datetimes
- Updated refresh_mtg.py to use settings instead of os.environ
- Updated mtg_monitor.py to use settings for connections
- Added services package with __init__.py

All 20 tests passing.
This commit is contained in:
2026-07-18 18:41:05 +00:00
parent 167a352d44
commit 915242b330
20 changed files with 1804 additions and 287 deletions
+101
View File
@@ -0,0 +1,101 @@
version: "3.8"
services:
# PostgreSQL - hosts both Cockatrice app data and mtgjson data
postgres:
image: postgres:16-alpine
container_name: mtg_postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-cockatrice}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-cockatrice_pass}
POSTGRES_DB: ${POSTGRES_DB:-cockatrice}
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
ports:
- "${POSTGRES_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init.sql
networks:
- mtg_network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-cockatrice}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
# Backend API
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: mtg_backend
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
- DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://cockatrice:cockatrice_pass@postgres:5432/cockatrice}
- MTG_DATABASE_URL=${MTG_DATABASE_URL:-postgresql+asyncpg://cockatrice:cockatrice_pass@postgres:5432/mtgdata}
- JWT_SECRET_KEY=${JWT_SECRET_KEY:-change-me-in-production}
- JWT_ALGORITHM=${JWT_ALGORITHM:-HS256}
- ACCESS_TOKEN_EXPIRE_MINUTES=${ACCESS_TOKEN_EXPIRE_MINUTES:-60}
- REFRESH_TOKEN_EXPIRE_DAYS=${REFRESH_TOKEN_EXPIRE_DAYS:-7}
- CORS_ORIGINS=${CORS_ORIGINS:-["http://localhost:3000","http://localhost:8000"]}
- APP_NAME=${APP_NAME:-Cockatrice Web}
- APP_VERSION=${APP_VERSION:-0.2.0}
- DEBUG=${DEBUG:-False}
- MTG_REFRESH_INTERVAL_DAYS=${MTG_REFRESH_INTERVAL_DAYS:-7}
- DATA_DIR=${DATA_DIR:-/app/data}
- UPLOAD_DIR=${UPLOAD_DIR:-/app/uploads}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
ports:
- "${BACKEND_PORT:-8000}:8000"
volumes:
- mtg_data:/app/data
- mtg_uploads:/app/uploads
- mtg_logs:/app/logs
networks:
- mtg_network
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Weekly database refresh (runs on a schedule)
mtg-refresh:
build:
context: ./backend
dockerfile: Dockerfile
container_name: mtg_refresh
restart: "no"
depends_on:
postgres:
condition: service_healthy
environment:
- DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://cockatrice:cockatrice_pass@postgres:5432/cockatrice}
- MTG_DATABASE_URL=${MTG_DATABASE_URL:-postgresql+asyncpg://cockatrice:cockatrice_pass@postgres:5432/mtgdata}
- DATA_DIR=${DATA_DIR:-/app/data}
- MTG_REFRESH_INTERVAL_DAYS=${MTG_REFRESH_INTERVAL_DAYS:-7}
volumes:
- mtg_data:/app/data
command: ["python", "-m", "app.scripts.refresh_mtg"]
networks:
- mtg_network
volumes:
postgres_data:
driver: local
mtg_data:
driver: local
mtg_uploads:
driver: local
mtg_logs:
driver: local
networks:
mtg_network:
driver: bridge