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
微信扫一扫