From d92ab86aa7bf94244c35fbac0a802130ef22e538 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Sat, 4 Apr 2026 11:20:05 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20visual=20tuning=20from=20live=20preview?= =?UTF-8?q?=20=E2=80=94=20diamond=20position,=20borders,=20corners,=20head?= =?UTF-8?q?er=20z-index?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move diamond left to align bottom point with center column divider - Keep all border widths uniform across tiers (remove T4 bold borders) - Remove corner accents entirely (T4 differentiated by glow + prismatic) - Fix T4 header z-index: don't override position on absolutely-positioned topright stat elements (stealing, running, bunting, hit & run) - Add ?tier= query param for dev preview of tier styling on base cards - Add run-local.sh for local API testing against dev database - Add .env.local and .run-local.pid to .gitignore Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitignore | 2 + app/routers_v2/players.py | 11 ++- run-local.sh | 132 +++++++++++++++++++++++++++++ storage/templates/player_card.html | 6 -- storage/templates/tier_style.html | 22 +---- 5 files changed, 146 insertions(+), 27 deletions(-) create mode 100755 run-local.sh diff --git a/.gitignore b/.gitignore index 2725e46..583b76f 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,8 @@ pyenv.cfg pyvenv.cfg docker-compose.override.yml docker-compose.*.yml +.run-local.pid +.env.local *.db venv .claude/ diff --git a/app/routers_v2/players.py b/app/routers_v2/players.py index 0fa7bb1..0f0d380 100644 --- a/app/routers_v2/players.py +++ b/app/routers_v2/players.py @@ -737,6 +737,9 @@ async def get_batter_card( variant: int = 0, d: str = None, html: Optional[bool] = False, + tier: Optional[int] = Query( + None, ge=0, le=4, description="Override refractor tier for preview (dev only)" + ), ): try: this_player = Player.get_by_id(player_id) @@ -800,7 +803,9 @@ async def get_batter_card( card_data["cardset_name"] = this_player.cardset.name else: card_data["cardset_name"] = this_player.description - card_data["refractor_tier"] = resolve_refractor_tier(player_id, variant) + card_data["refractor_tier"] = ( + tier if tier is not None else resolve_refractor_tier(player_id, variant) + ) card_data["request"] = request html_response = templates.TemplateResponse("player_card.html", card_data) @@ -838,7 +843,9 @@ async def get_batter_card( card_data["cardset_name"] = this_player.cardset.name else: card_data["cardset_name"] = this_player.description - card_data["refractor_tier"] = resolve_refractor_tier(player_id, variant) + card_data["refractor_tier"] = ( + tier if tier is not None else resolve_refractor_tier(player_id, variant) + ) card_data["request"] = request html_response = templates.TemplateResponse("player_card.html", card_data) diff --git a/run-local.sh b/run-local.sh new file mode 100755 index 0000000..df7b0ad --- /dev/null +++ b/run-local.sh @@ -0,0 +1,132 @@ +#!/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() +b = p.chromium.launch(args=['--no-sandbox']) +b.close() +p.stop() +" 2>/dev/null || { + echo "Playwright Chromium not installed. Run: playwright install chromium" + exit 1 +} + +# Check dev DB is reachable +python -c " +import socket +s = socket.create_connection(('10.10.0.42', 5432), timeout=3) +s.close() +" 2>/dev/null || { + echo "Cannot reach dev PostgreSQL at 10.10.0.42: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="${POSTGRES_HOST_LOCAL:-10.10.0.42}" +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 diff --git a/storage/templates/player_card.html b/storage/templates/player_card.html index e9caf8b..81f522b 100644 --- a/storage/templates/player_card.html +++ b/storage/templates/player_card.html @@ -21,12 +21,6 @@
= 3 %}style="background: {{ filled_bg }};"{% endif %}>
= 4 %}style="background: {{ filled_bg }};"{% endif %}>
- {% if refractor_tier == 4 %} -
-
-
-
- {% endif %} {% endif %}