# Next.js Full-Stack Deployment with Docker Infrastructure

Deploy a Next.js + Prisma + PostgreSQL + MinIO app where code runs locally but infrastructure runs in Docker.

## Workflow

### 1. Clone from GitHub (HTTPS + stored token)

If the repo is private, use the stored token from `~/.git-credentials`:

```bash
git clone https://USERNAME:TOKEN@github.com/USER/REPO.git
```

Token is stored in `~/.git-credentials` (plaintext). Configure git to use it:
```bash
git config --global credential.helper store
```

### 2. Start Docker infrastructure

```bash
# PostgreSQL
sudo docker run -d --name app-postgres \
  -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD='pass' -e POSTGRES_DB=postgres \
  -p 5432:5432 --restart unless-stopped postgres:16-alpine

# MinIO
sudo docker run -d --name app-minio \
  -e MINIO_ROOT_USER=minioadmin -e MINIO_ROOT_PASSWORD=minioadmin \
  -p 9000:9000 -p 9001:9001 \
  -v minio_data:/data --restart unless-stopped \
  minio/minio server /data --console-address ":9001"
```

### 3. Create `.env` file

Key: use `localhost` (not Docker service names) since the app runs on the host:

```env
DATABASE_URL="postgresql://user:pass@localhost:5432/dbname?schema=public"
MINIO_ENDPOINT="http://localhost:9000"
MINIO_ACCESS_KEY="minioadmin"
MINIO_SECRET_KEY="minioadmin"
MINIO_BUCKET="my-bucket"
MINIO_USE_SSL="false"
```

### 4. Install dependencies and initialize DB

```bash
npm install
npx prisma db push      # creates tables from schema.prisma
npm run prisma:generate # if the project has a custom generate script
```

### 5. Start the app

```bash
npm run dev   # development
# or
npm run build && npm start  # production
```

### 6. Expose externally (if needed)

```bash
cloudflared tunnel --url http://localhost:3000 2>&1 | tee /tmp/cf.log &
grep "trycloudflare.com" /tmp/cf.log
```

## Code Modification Workflow

When modifying a Next.js app (adding features):

### API route changes
- Located in `src/app/api/` 
- Use `NextRequest` + `NextResponse`
- Parse query params with `searchParams.getAll()` for multi-value params
- Use Prisma `where` with `OR` / `AND` for complex filters
- Handle `AND` array merging carefully when combining status filters with other filters

### Frontend changes
- Pages in `src/app/(group)/page.tsx` (usually `"use client"`)
- State management with `useState` / `useEffect`
- For filter UI: role dropdown + tag display + searchable user picker
- Auto-populate filters from `/api/auth/me` on mount
- Pass filter params via `URLSearchParams` to API
- Use `useRef` + click-outside handler for dropdowns

### Rebuild and restart
```bash
# Kill existing dev server
ps aux | grep "next dev" | grep -v grep | awk '{print $2}' | xargs -r kill

# Restart
npm run dev
```

## Pitfalls

### P1: .env uses Docker service names but app runs on host
When the app runs on the host (not in Docker), use `localhost` + published ports, not Docker container names.

### P2: Prisma `where.AND` is an object, not array
When adding conditions to `where.AND`, normalize it to an array first:
```typescript
where.AND = where.AND || [];
if (!Array.isArray(where.AND)) where.AND = [where.AND];
(where.AND as any[]).push(newCondition);
```

### P3: `searchParams.get()` vs `searchParams.getAll()`
For multi-value query params (e.g., `?id=1&id=2`), use `getAll()` not `get()`.

### P4: Next.js hot reload doesn't pick up API changes
Sometimes `next dev` needs a manual restart for API route changes. Kill and restart if changes don't take effect.

### P5: Multiple dev servers / port conflict
If `next dev` starts on port 3001 instead of 3000, an old process is still holding port 3000. The background process won't show errors — it silently binds to the next available port. Symptoms: pages return 404 or old code is served. Fix:
```bash
# Find what's holding port 3000
ss -tlnp | grep 3000
# Kill ALL next processes
ps aux | grep next | grep -v grep | awk '{print $2}' | xargs -r kill -9
# Verify port is free, then restart
ss -tlnp | grep 3000
npm run dev
```
Always kill old processes before starting new ones — `pkill -f "next dev"` is unreliable in some shell contexts. The terminal tool may also block if it detects a long-lived process pattern; use `background=true` for dev servers.

### P6: `.next` cache causes 404 on valid routes
Stale `.next` build cache can cause valid routes (like `/login`) to return 404 even after code fixes and process restart. This is separate from the port conflict issue (P5). Symptoms: route exists in source, dev server is running on correct port, but still 404.

**Fix:** Delete the `.next` cache directory and restart:
```bash
rm -rf .next
npm run dev
```

**When to suspect this:** You've killed stale processes (P5), confirmed the port is correct, the route file exists, but pages still 404. The `.next` directory may hold stale server component manifests or route handlers from a previous build.

**Prevention:** When switching between branches or after significant code changes, `rm -rf .next` before restarting the dev server.
