#!/usr/bin/env bash # run-local.sh — Spin up the Paper Dynasty Database API locally for testing. # # Connects to the dev PostgreSQL on the homelab (10.10.0.42) so you get real # card data for rendering. Playwright Chromium must be installed locally # (it already is on this workstation). # # Usage: # ./run-local.sh # start on default port 8000 # ./run-local.sh 8001 # start on custom port # ./run-local.sh --stop # kill a running instance # # Card rendering test URLs (after startup): # HTML preview: http://localhost:8000/api/v2/players/{id}/battingcard/{date}/{variant}?html=True # PNG render: http://localhost:8000/api/v2/players/{id}/battingcard/{date}/{variant} # API docs: http://localhost:8000/api/docs set -euo pipefail cd "$(dirname "$0")" PORT="${1:-8000}" PIDFILE=".run-local.pid" LOGFILE="logs/database/run-local.log" # ── Stop mode ──────────────────────────────────────────────────────────────── if [[ "${1:-}" == "--stop" ]]; then if [[ -f "$PIDFILE" ]]; then pid=$(cat "$PIDFILE") if kill -0 "$pid" 2>/dev/null; then kill "$pid" echo "Stopped local API (PID $pid)" else echo "PID $pid not running (stale pidfile)" fi rm -f "$PIDFILE" else echo "No pidfile found — nothing to stop" fi exit 0 fi # ── Pre-flight checks ─────────────────────────────────────────────────────── if [[ -f "$PIDFILE" ]] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then echo "Already running (PID $(cat "$PIDFILE")). Use './run-local.sh --stop' first." exit 1 fi # Check Python deps are importable python -c "import fastapi, peewee, playwright" 2>/dev/null || { echo "Missing Python dependencies. Install with: pip install -r requirements.txt" exit 1 } # Check Playwright Chromium is available python -c " from playwright.sync_api import sync_playwright p = sync_playwright().start() print(p.chromium.executable_path) p.stop() " >/dev/null 2>&1 || { echo "Playwright Chromium not installed. Run: playwright install chromium" exit 1 } # Check dev DB is reachable DB_HOST="${POSTGRES_HOST_LOCAL:-10.10.0.42}" python -c " import socket, sys s = socket.create_connection((sys.argv[1], 5432), timeout=3) s.close() " "$DB_HOST" 2>/dev/null || { echo "Cannot reach dev PostgreSQL at ${DB_HOST}:5432 — is the homelab up?" exit 1 } # ── Ensure directories exist ──────────────────────────────────────────────── mkdir -p logs/database mkdir -p storage/cards # ── Launch ─────────────────────────────────────────────────────────────────── echo "Starting Paper Dynasty Database API on http://localhost:${PORT}" echo " DB: paperdynasty_dev @ 10.10.0.42" echo " Logs: ${LOGFILE}" echo "" # Load .env, then .env.local overrides (for passwords not in version control) set -a # shellcheck source=/dev/null [[ -f .env ]] && source .env [[ -f .env.local ]] && source .env.local set +a # Override DB host to point at the dev server's IP (not Docker network name) export DATABASE_TYPE=postgresql export POSTGRES_HOST="$DB_HOST" export POSTGRES_PORT="${POSTGRES_PORT:-5432}" export POSTGRES_DB="${POSTGRES_DB:-paperdynasty_dev}" export POSTGRES_USER="${POSTGRES_USER:-sba_admin}" export LOG_LEVEL=INFO export TESTING=True if [[ -z "${POSTGRES_PASSWORD:-}" || "$POSTGRES_PASSWORD" == "your_production_password" ]]; then echo "ERROR: POSTGRES_PASSWORD not set or is the placeholder value." echo "Create .env.local with: POSTGRES_PASSWORD=" exit 1 fi uvicorn app.main:app \ --host 0.0.0.0 \ --port "$PORT" \ --reload \ --reload-dir app \ --reload-dir storage/templates \ 2>&1 | tee "$LOGFILE" & echo $! >"$PIDFILE" sleep 2 if kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then echo "" echo "API running (PID $(cat "$PIDFILE"))." echo "" echo "Quick test URLs:" echo " API docs: http://localhost:${PORT}/api/docs" echo " Health: curl -s http://localhost:${PORT}/api/v2/players/1/battingcard?html=True" echo "" echo "Stop with: ./run-local.sh --stop" else echo "Failed to start — check ${LOGFILE}" rm -f "$PIDFILE" exit 1 fi