You are an expert at managing the UFC Pokedex development environment, which supports multiple configurations and deployment modes.
Environment Overview
The UFC Pokedex supports multiple development modes:
- •Local Mode (Default) - Backend + Frontend on localhost
- •Tunnel Mode - Backend + Frontend exposed via Cloudflare tunnels
- •SQLite Mode - Lightweight database (no Docker required)
- •PostgreSQL Mode - Production-like database (requires Docker)
When to Use This Skill
Invoke this skill when the user wants to:
- •Start/stop development servers
- •Switch between environment modes
- •Troubleshoot startup failures
- •Resolve port conflicts
- •Configure Cloudflare tunnels
- •Manage environment variables
- •Clear build caches
- •Regenerate TypeScript types
- •Check service health
- •Reset development environment
Quick Start Commands
Start Development Environment
Option 1: Local Development (Recommended)
Backend + Frontend on localhost (no tunnels, no env file changes).
Command:
make dev-local
Ports:
- •Backend: http://localhost:8000
- •Frontend: http://localhost:3000
- •Database: PostgreSQL on localhost:5432 (via Docker)
Best for:
- •Daily development
- •No need for public URLs
- •Fastest startup
Option 2: With Cloudflare Tunnels
Backend + Frontend exposed via public URLs.
Command:
make dev
URLs:
- •Backend: https://api.ufc.wolfgangschoenberger.com
- •Frontend: https://ufc.wolfgangschoenberger.com
Best for:
- •Testing on mobile devices
- •Sharing work with others
- •Testing webhooks or external services
Note: Auto-configures environment variables in .env and frontend/.env.local
Option 3: SQLite Mode (No Docker)
Lightweight development without PostgreSQL.
Command:
make api:dev
What it does:
- •Uses SQLite database at
data/app.db - •No Docker required
- •Auto-creates tables on startup
- •Perfect for quick testing
Best for:
- •Quick prototyping
- •When Docker isn't available
- •Testing with small datasets
Limitations:
- •Single-writer (no concurrency)
- •Full dataset blocked (10K+ fighters)
- •Alembic migrations not supported
Option 4: Frontend Only
Start just the frontend (backend must be running separately).
Command:
make frontend
Port: http://localhost:3000
Stop Development Environment
Command:
make stop
What it stops:
- •Backend (port 8000)
- •Frontend (port 3000)
- •Cloudflare tunnels
- •Background processes
Clean and Restart
If you encounter webpack cache issues, module not found errors, or chunk 404s:
Command:
make dev-clean
What it does:
- •Stops all services
- •Removes
frontend/.nextdirectory - •Removes
frontend/node_modules/.cache - •Clears npm cache
- •Reinstalls dependencies
- •Restarts dev servers
Use when:
- •Webpack cache corruption
- •MODULE_NOT_FOUND errors
- •Chunk loading failures (404s)
- •Strange build behavior
Environment Modes Explained
Docker vs SQLite
PostgreSQL (Docker) Mode
Pros:
- •Production-like environment
- •Supports full dataset (10K+ fighters)
- •Alembic migrations work
- •Better concurrency
Setup:
# Start PostgreSQL docker-compose up -d # Run migrations make db-upgrade # Start backend make api
Environment variables:
DATABASE_URL=postgresql+psycopg://ufc_pokedex:ufc_pokedex@localhost:5432/ufc_pokedex
SQLite Mode
Pros:
- •No Docker required
- •Faster startup
- •Simpler setup
- •Great for quick testing
Setup:
# Just start the backend (SQLite auto-configured if DATABASE_URL not set) make api:dev # Or force SQLite mode even if DATABASE_URL is set make api:sqlite
Environment variables:
# Option 1: Unset DATABASE_URL (auto-detects SQLite) # No environment variable needed # Option 2: Force SQLite USE_SQLITE=1 # SQLite database location # DATABASE_URL=sqlite+aiosqlite:///./data/app.db
Auto-detects: If DATABASE_URL is not set, automatically uses sqlite+aiosqlite:///./data/app.db
Localhost vs Tunnel Mode
Localhost Mode (dev-local)
Pros:
- •Faster (no tunnel overhead)
- •Private (not exposed to internet)
- •No environment file changes
- •Simpler
Cons:
- •Can't test on external devices
- •Can't share with others
Use case: Daily development
Tunnel Mode (dev)
Pros:
- •Public URLs for testing
- •Works on mobile devices
- •Can share with others
- •Tests production-like setup
Cons:
- •Slower (tunnel overhead)
- •Modifies environment files
- •Requires Cloudflare authentication
Use case: Cross-device testing, demos
Service Management
Start Individual Services
Backend Only (PostgreSQL)
make api
Backend Only (SQLite)
make api:dev # Auto-detects SQLite if DATABASE_URL not set make api:sqlite # Forces SQLite even if DATABASE_URL set
Frontend Only
make frontend
Cloudflare Tunnels Only
# Frontend tunnel (port 3000) make tunnel-frontend # Backend tunnel (port 8000) make tunnel-api # Stop all tunnels make tunnel-stop
Check Service Status
Check if services are running:
# Backend (port 8000) lsof -ti :8000 # Frontend (port 3000) lsof -ti :3000 # Cloudflare tunnels ps aux | grep cloudflared # Docker (PostgreSQL) docker ps # Redis redis-cli ping
Test endpoints:
# Backend health check curl http://localhost:8000/health # Frontend curl http://localhost:3000 # Database connection PGPASSWORD=ufc_pokedex psql -h localhost -U ufc_pokedex -d ufc_pokedex -c "SELECT 1;" # Redis redis-cli ping
Environment Variables
Backend (.env)
Required for PostgreSQL mode:
DATABASE_URL=postgresql+psycopg://ufc_pokedex:ufc_pokedex@localhost:5432/ufc_pokedex
Optional:
# Force SQLite mode USE_SQLITE=1 # Redis cache (optional - gracefully degrades if unavailable) REDIS_URL=redis://localhost:6379/0 # API server API_HOST=0.0.0.0 API_PORT=8000 LOG_LEVEL=INFO # CORS (auto-configured by make dev) CORS_ALLOW_ORIGINS=http://localhost:3000 # Scraper settings SCRAPER_USER_AGENT=UFC-Pokedex-Scraper/0.1 SCRAPER_DELAY_SECONDS=1.5 SCRAPER_CONCURRENT_REQUESTS=4
Frontend (frontend/.env.local)
Required:
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
For tunnel mode (auto-configured by make dev):
NEXT_PUBLIC_API_BASE_URL=https://api.ufc.wolfgangschoenberger.com
Check Environment Variables
# Backend cat .env # Frontend cat frontend/.env.local # Check if set in environment echo $DATABASE_URL echo $NEXT_PUBLIC_API_BASE_URL
Cloudflare Tunnel Setup
One-Time Setup
Command:
bash scripts/setup_tunnel.sh
What it does:
- •Authenticates with Cloudflare (opens browser)
- •Creates tunnel named
ufc-pokedex - •Sets up DNS routes for subdomains
- •Generates config file at
~/.cloudflared/config.yml
You only need to run this once!
Check Tunnel Status
# List all tunnels cloudflared tunnel list # Get tunnel details cloudflared tunnel info ufc-pokedex # Check DNS routes cloudflared tunnel route dns list # Check tunnel logs tail -f /tmp/tunnel.log # Test connectivity curl https://api.ufc.wolfgangschoenberger.com/health curl https://ufc.wolfgangschoenberger.com # Verify DNS propagation nslookup ufc.wolfgangschoenberger.com nslookup api.ufc.wolfgangschoenberger.com
Troubleshooting Tunnels
Issue: Tunnel not starting
Solutions:
# Check if cloudflared is installed which cloudflared # Reinstall if needed brew install cloudflare/cloudflare/cloudflared # Check authentication cloudflared tunnel list # Re-run setup bash scripts/setup_tunnel.sh
Issue: DNS not resolving
Solutions:
# Check DNS propagation nslookup ufc.wolfgangschoenberger.com # Wait 5-10 minutes for DNS propagation # Or flush DNS cache sudo dscacheutil -flushcache sudo killall -HUP mDNSResponder
Issue: Tunnel connects but can't reach service
Solutions:
# Verify backend is running on port 8000 lsof -ti :8000 # Verify frontend is running on port 3000 lsof -ti :3000 # Check tunnel configuration cat ~/.cloudflared/config.yml
TypeScript Type Generation
The project uses OpenAPI → TypeScript code generation for type safety.
Regenerate Types
Command:
make types-generate
Prerequisite: Backend must be running (needs /openapi.json endpoint)
What it does:
- •Fetches OpenAPI schema from
http://localhost:8000/openapi.json - •Generates TypeScript types using
openapi-typescript - •Outputs to
frontend/src/lib/generated/api-schema.ts
Auto-generates: Types are automatically generated when you run make dev or make dev-local
Check if Types are Stale
# Check when types were last generated ls -lh frontend/src/lib/generated/api-schema.ts # Check for TypeScript errors cd frontend && npx tsc --noEmit
Port Conflict Resolution
Check What's Using Ports
# Check port 8000 (backend) lsof -ti :8000 # Check port 3000 (frontend) lsof -ti :3000 # Kill process on port 8000 lsof -ti :8000 | xargs kill -9 # Kill process on port 3000 lsof -ti :3000 | xargs kill -9
Note: make dev, make api, and make frontend automatically kill existing processes on their ports.
Database Management
Start PostgreSQL (Docker)
# Start PostgreSQL and Redis docker-compose up -d # Check if running docker ps # View logs docker-compose logs -f # Stop services docker-compose down
SQLite (No Docker)
# Just start the backend - SQLite auto-configured make api:dev # Check SQLite database ls -lh data/app.db # Query SQLite sqlite3 data/app.db "SELECT COUNT(*) FROM fighters;"
Run Migrations (PostgreSQL only)
# Apply pending migrations make db-upgrade # Rollback last migration make db-downgrade # Reset database (⚠️ destroys data!) make db-reset
Note: Alembic migrations do NOT work with SQLite mode. SQLite uses create_all() instead.
Seed Database
# Seed with 8 sample fighters (works on SQLite) make api:seed # Seed with all fighters (PostgreSQL recommended) make load-data # Seed with all fighters (SQLite - requires override) ALLOW_SQLITE_PROD_SEED=1 make api:seed-full
Troubleshooting
Issue: "Port already in use"
Solution:
# Stop all services make stop # Or kill specific ports lsof -ti :8000 | xargs kill -9 lsof -ti :3000 | xargs kill -9 # Restart make dev-local
Issue: "Module not found" or webpack cache errors
Solution:
make dev-clean
Issue: "Database connection failed"
Solutions:
# Check if PostgreSQL is running docker ps # Start PostgreSQL docker-compose up -d # Check connection PGPASSWORD=ufc_pokedex psql -h localhost -U ufc_pokedex -d ufc_pokedex -c "SELECT 1;" # Or switch to SQLite make api:sqlite
Issue: "TypeScript errors about API types"
Solution:
# Make sure backend is running make api # Regenerate types make types-generate # Check for errors cd frontend && npx tsc --noEmit
Issue: "Redis connection failed"
Note: Redis is optional! Backend gracefully degrades.
Solution (if you want Redis):
# Start Redis docker-compose up -d redis # Check connection redis-cli ping # If Redis not available, backend will log warning and continue without cache
Issue: "Frontend shows old data after API changes"
Solutions:
# 1. Clear Redis cache (if using Redis) redis-cli FLUSHDB # 2. Regenerate types make types-generate # 3. Restart frontend make frontend
Issue: "Cloudflare tunnel not connecting"
Solutions:
# Check tunnel status cloudflared tunnel list # Check logs tail -f /tmp/tunnel.log # Restart tunnel make tunnel-stop make dev
Issue: Environment variable mismatch
Symptoms:
- •Frontend can't reach backend
- •CORS errors
- •404 on API calls
Solution:
# Check current settings cat .env cat frontend/.env.local # For local development echo "NEXT_PUBLIC_API_BASE_URL=http://localhost:8000" > frontend/.env.local echo "CORS_ALLOW_ORIGINS=http://localhost:3000" > .env # For tunnel mode make dev # Auto-configures both files
Complete Diagnostic Workflow
When something isn't working, run through this checklist:
# 1. Check if services are running lsof -ti :8000 # Backend lsof -ti :3000 # Frontend docker ps # PostgreSQL # 2. Test endpoints curl http://localhost:8000/health curl http://localhost:3000 # 3. Check environment variables cat .env cat frontend/.env.local # 4. Check database connection PGPASSWORD=ufc_pokedex psql -h localhost -U ufc_pokedex -d ufc_pokedex -c "SELECT 1;" # OR sqlite3 data/app.db "SELECT 1;" # 5. Check logs tail -f /tmp/backend.log tail -f /tmp/frontend.log # 6. If still broken, clean restart make stop make dev-clean
Environment Reset Workflow
To completely reset your development environment:
# 1. Stop everything make stop docker-compose down # 2. Clean caches make dev-clean # 3. Reset database (⚠️ destroys data!) docker-compose down -v docker-compose up -d make db-upgrade # 4. Reseed database make api:seed # Sample data # OR make load-data # Full data # 5. Restart services make dev-local
Best Practices
- •Use dev-local for daily work - Faster, simpler, no tunnel overhead
- •Use dev for demos/mobile testing - When you need public URLs
- •Use SQLite for quick prototyping - No Docker overhead
- •Use PostgreSQL for realistic testing - Production-like environment
- •Run make stop before switching modes - Prevents port conflicts
- •Check environment variables - Ensure frontend/backend URLs match
- •Regenerate types after API changes - Keeps TypeScript in sync
- •Use dev-clean when webpack acts weird - Solves 90% of cache issues
- •Monitor logs during development -
tail -f /tmp/backend.log - •Test tunnel setup once - Run
scripts/setup_tunnel.shon new machine
Quick Reference
# Start development (localhost) make dev-local # Start development (with tunnels) make dev # Stop everything make stop # Clean and restart make dev-clean # Individual services make api # Backend (PostgreSQL) make api:dev # Backend (SQLite auto-detect) make api:sqlite # Backend (SQLite forced) make frontend # Frontend only # Database docker-compose up -d # Start PostgreSQL make db-upgrade # Run migrations make api:seed # Seed sample data # Types make types-generate # Regenerate TypeScript types # Diagnostics lsof -ti :8000 # Check backend port lsof -ti :3000 # Check frontend port curl localhost:8000/health # Test backend docker ps # Check Docker services
Related Skills
- •See
scraping-data-pipelineskill for scraping and loading data - •See
managing-fighter-imagesskill for image management