# Managing Dev Environment

> Use this skill when starting, stopping, or troubleshooting the development environment including managing backend/frontend services, handling port conflicts, setting up Docker vs SQLite modes, configuring Cloudflare tunnels, managing environment variables, regenerating TypeScript types, clearing caches, or diagnosing startup failures. Supports multiple modes (local, tunnel, SQLite, PostgreSQL).

- Skill: `majiayu000/managing-dev-environment` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/managing-dev-environment`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/managing-dev-environment/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/managing-dev-environment

---


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:

1. **Local Mode** (Default) - Backend + Frontend on localhost
2. **Tunnel Mode** - Backend + Frontend exposed via Cloudflare tunnels
3. **SQLite Mode** - Lightweight database (no Docker required)
4. **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:**
```bash
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:**
```bash
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:**
```bash
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:**
```bash
make frontend
```

**Port:** http://localhost:3000

## Stop Development Environment

**Command:**
```bash
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:**
```bash
make dev-clean
```

**What it does:**
- Stops all services
- Removes `frontend/.next` directory
- 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:**
```bash
# Start PostgreSQL
docker-compose up -d

# Run migrations
make db-upgrade

# Start backend
make api
```

**Environment variables:**
```bash
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:**
```bash
# 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:**
```bash
# 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)
```bash
make api
```

### Backend Only (SQLite)
```bash
make api:dev    # Auto-detects SQLite if DATABASE_URL not set
make api:sqlite # Forces SQLite even if DATABASE_URL set
```

### Frontend Only
```bash
make frontend
```

### Cloudflare Tunnels Only
```bash
# 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:
```bash
# 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:
```bash
# 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:**
```bash
DATABASE_URL=postgresql+psycopg://ufc_pokedex:ufc_pokedex@localhost:5432/ufc_pokedex
```

**Optional:**
```bash
# 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:**
```bash
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
```

**For tunnel mode (auto-configured by make dev):**
```bash
NEXT_PUBLIC_API_BASE_URL=https://api.ufc.wolfgangschoenberger.com
```

## Check Environment Variables

```bash
# 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
bash scripts/setup_tunnel.sh
```

**What it does:**
1. Authenticates with Cloudflare (opens browser)
2. Creates tunnel named `ufc-pokedex`
3. Sets up DNS routes for subdomains
4. Generates config file at `~/.cloudflared/config.yml`

**You only need to run this once!**

## Check Tunnel Status

```bash
# 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:**
```bash
# 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:**
```bash
# 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:**
```bash
# 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:**
```bash
make types-generate
```

**Prerequisite:** Backend must be running (needs `/openapi.json` endpoint)

**What it does:**
1. Fetches OpenAPI schema from `http://localhost:8000/openapi.json`
2. Generates TypeScript types using `openapi-typescript`
3. 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

```bash
# 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

```bash
# 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)

```bash
# 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)

```bash
# 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)

```bash
# 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

```bash
# 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:**
```bash
# 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:**
```bash
make dev-clean
```

## Issue: "Database connection failed"

**Solutions:**
```bash
# 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:**
```bash
# 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):**
```bash
# 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:**
```bash
# 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:**
```bash
# 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:**
```bash
# 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:

```bash
# 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:

```bash
# 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

1. **Use dev-local for daily work** - Faster, simpler, no tunnel overhead
2. **Use dev for demos/mobile testing** - When you need public URLs
3. **Use SQLite for quick prototyping** - No Docker overhead
4. **Use PostgreSQL for realistic testing** - Production-like environment
5. **Run make stop before switching modes** - Prevents port conflicts
6. **Check environment variables** - Ensure frontend/backend URLs match
7. **Regenerate types after API changes** - Keeps TypeScript in sync
8. **Use dev-clean when webpack acts weird** - Solves 90% of cache issues
9. **Monitor logs during development** - `tail -f /tmp/backend.log`
10. **Test tunnel setup once** - Run `scripts/setup_tunnel.sh` on new machine

# Quick Reference

```bash
# 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-pipeline` skill for scraping and loading data
- See `managing-fighter-images` skill for image management

