# Migration Guide: From Supabase to Local PostgreSQL

This guide helps you migrate your QR Master application from Supabase to a local PostgreSQL database with Docker.

## What Changed

### ✅ Removed
- Supabase connection pooling (`DIRECT_URL` environment variable)
- Supabase-specific configurations
- External database dependency

### ✨ Added
- Local PostgreSQL 16 database in Docker
- Redis cache for better performance
- Adminer database management UI
- Complete Docker setup with docker-compose
- Database initialization scripts
- Development and production Docker configurations

## Migration Steps

### 1. Backup Your Supabase Database (IMPORTANT!)

Before making any changes, backup your existing data:

```bash
# If you have access to Supabase CLI
supabase db dump > backup_$(date +%Y%m%d).sql

# Or use pg_dump directly with your Supabase credentials
pg_dump "postgresql://postgres:[PASSWORD]@[PROJECT_REF].supabase.co:5432/postgres" > backup.sql
```

### 2. Update Your Codebase

Pull the latest changes or update these files:

#### Updated Files:
- ✏️ `prisma/schema.prisma` - Removed `directUrl` field
- ✏️ `src/lib/env.ts` - Removed `DIRECT_URL` variable
- ✏️ `docker-compose.yml` - Updated with PostgreSQL setup
- ✏️ `Dockerfile` - Enhanced with PostgreSQL support
- ✏️ `package.json` - Added Docker scripts and tsx

#### New Files:
- 📄 `docker-compose.dev.yml` - Development setup
- 📄 `docker/init-db.sh` - Database initialization
- 📄 `docker/README.md` - Docker documentation
- 📄 `DOCKER_SETUP.md` - Complete Docker guide
- 📄 `env.example` - Environment template
- 📄 `.dockerignore` - Docker build optimization

### 3. Set Up Environment Variables

1. Remove Supabase-specific variables:
```bash
# Remove these from .env:
# DIRECT_URL=...
# SUPABASE_URL=...
# SUPABASE_ANON_KEY=...
```

2. Update database connection:
```bash
# For Docker (default):
DATABASE_URL=postgresql://postgres:postgres@db:5432/qrmaster?schema=public

# For local development (without Docker):
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/qrmaster?schema=public
```

3. Copy from template:
```bash
cp env.example .env
```

4. Generate secure secrets:
```bash
# Linux/Mac
openssl rand -base64 32  # Use for NEXTAUTH_SECRET
openssl rand -base64 32  # Use for IP_SALT

# Windows PowerShell
[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))
```

### 4. Start Local PostgreSQL

#### Option A: Development Mode (Recommended)

```bash
# Start database only (run app on host)
npm run docker:dev

# Wait for database to be ready
docker-compose -f docker-compose.dev.yml logs -f db
```

#### Option B: Full Docker

```bash
# Start all services
npm run docker:prod

# Wait for all services to be ready
docker-compose logs -f
```

### 5. Restore Your Data

#### Option 1: Using Prisma Migrations (Clean Start)

```bash
# Generate Prisma client
npm run db:generate

# Run migrations
npm run db:migrate

# Seed with demo data
npm run db:seed
```

#### Option 2: Restore from Backup (Preserve Data)

```bash
# Restore your Supabase backup
cat backup.sql | docker-compose exec -T db psql -U postgres qrmaster

# Or if running locally
psql -U postgres -d qrmaster < backup.sql

# Then run migrations to update schema
npm run db:deploy
```

### 6. Verify Migration

1. **Check Database Connection:**
```bash
# Connect to database
npm run docker:db

# Or manually
docker-compose exec db psql -U postgres -d qrmaster

# Run test query
SELECT COUNT(*) FROM "User";
SELECT COUNT(*) FROM "QRCode";
```

2. **Access Adminer (Database UI):**
   - URL: http://localhost:8080
   - System: PostgreSQL
   - Server: db
   - Username: postgres
   - Password: postgres
   - Database: qrmaster

3. **Test Your Application:**
```bash
# Start the app (if using dev mode)
npm run dev

# Access: http://localhost:3050
```

### 7. Update Your Deployment

#### For Docker Production:

```bash
# Build and deploy
docker-compose up -d --build

# Run migrations
docker-compose exec web npx prisma migrate deploy

# Check logs
docker-compose logs -f web
```

#### For Other Platforms (Vercel, Railway, etc.):

Update your environment variables in the platform's dashboard:
- Remove: `DIRECT_URL`
- Update: `DATABASE_URL` to your new PostgreSQL connection string

## Troubleshooting

### Issue: Connection Refused

```bash
# Check if database is running
docker-compose ps

# Check database logs
docker-compose logs db

# Restart database
docker-compose restart db
```

### Issue: Migration Errors

```bash
# Reset migrations (⚠️ deletes data!)
npm run db:migrate reset

# Or manually reset
docker-compose down -v
docker-compose up -d db
npm run db:migrate
```

### Issue: Prisma Client Not Generated

```bash
# Regenerate Prisma client
npm run db:generate

# Or
npx prisma generate
```

### Issue: Data Not Migrated

```bash
# Check if backup was restored correctly
docker-compose exec db psql -U postgres -d qrmaster -c "
SELECT 
  schemaname,
  tablename,
  pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
"
```

## Differences: Supabase vs Local PostgreSQL

| Feature | Supabase | Local PostgreSQL |
|---------|----------|------------------|
| Hosting | Cloud (managed) | Self-hosted (Docker) |
| Connection Pooling | Built-in (Supavisor) | Prisma built-in |
| Database UI | Supabase Studio | Adminer (included) |
| Backups | Automatic | Manual (or scripted) |
| Cost | Free tier + paid | Free (infrastructure cost only) |
| Latency | Internet dependent | Local network |
| Setup | Account required | Docker only |
| Scaling | Automatic | Manual |

## Benefits of Local PostgreSQL

✅ **Full Control**: Own your data and infrastructure  
✅ **No Vendor Lock-in**: Standard PostgreSQL  
✅ **Lower Latency**: Local network speed  
✅ **Cost**: No monthly fees  
✅ **Privacy**: Data stays on your infrastructure  
✅ **Development**: Easy local testing  
✅ **Offline**: Works without internet  

## Next Steps

1. ✅ Verify all data migrated correctly
2. ✅ Test all application features
3. ✅ Update your CI/CD pipelines
4. ✅ Set up automated backups:
```bash
# Create backup script
cat > backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="./backups"
mkdir -p $BACKUP_DIR
docker-compose exec -T db pg_dump -U postgres qrmaster > "$BACKUP_DIR/backup_$(date +%Y%m%d_%H%M%S).sql"
EOF

chmod +x backup.sh

# Run daily backups (cron example)
# 0 2 * * * /path/to/backup.sh
```

5. ✅ Monitor your application
6. ✅ Update documentation

## Rollback Plan

If you need to rollback to Supabase:

1. Keep your Supabase project active during testing
2. Keep your backup files safe
3. To rollback, simply change `DATABASE_URL` back to Supabase
4. Add back `DIRECT_URL` to `prisma/schema.prisma`:
```prisma
datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}
```

## Support

For issues:
1. Check [DOCKER_SETUP.md](DOCKER_SETUP.md) for detailed Docker help
2. Check [docker/README.md](docker/README.md) for Docker commands
3. Review logs: `docker-compose logs -f`
4. Open an issue on GitHub

---

🎉 **Congratulations!** You've successfully migrated from Supabase to local PostgreSQL!







