Staging Setup
Source: docs/runbooks/staging-setup.md
# Staging Environment Setup
Step-by-step guide for provisioning the RGL8R staging environment on Render + Vercel.
---
## Prerequisites
- Render account with access to the RGL8R team
- Vercel account with access to the RGL8R project
- Access to Clerk dashboard (for staging org)
- `.env.staging.example` from repo root (template for all env vars)
---
## 1. Render: Staging Database
1. **Create Postgres instance**
- Dashboard → New → PostgreSQL
- Name: `rgl8r-staging-db`
- Region: Same as production (Oregon recommended)
- Plan: Starter (sufficient for staging)
- Click **Create Database**
2. **Copy the Internal Database URL** — you'll need this for the API service env vars
3. Note: The `app` schema will be created automatically by Prisma migrations
---
## 2. Render: Staging API Service
1. **Create Web Service**
- Dashboard → New → Web Service
- Connect the `rgl8r-platform` repo
- Name: `rgl8r-staging-api`
- Region: Same as database
- Branch: `main` (or a staging branch if preferred)
- Root Directory: *(leave blank — repo root required for pnpm workspaces)*
- Build Command: `pnpm install --frozen-lockfile && pnpm --filter @rgl8r/api exec prisma generate --schema prisma/schema.prisma && pnpm --filter @rgl8r/api... build`
- Use one line exactly as shown (no `\` line-continuation characters in the Render UI field)
- Start Command: `node apps/api/dist/index.js`
2. **Configure environment variables** (from `.env.staging.example`):
```
DATABASE_URL=<internal URL from step 1>
NODE_ENV=staging
# Do not set PORT manually on Render; Render injects this automatically
JWT_PRIVATE_KEY=<see JWT key generation steps below>
JWT_PUBLIC_KEY=<see JWT key generation steps below>
CLERK_SECRET_KEY=<from Clerk staging instance>
ALLOW_API_KEY_FALLBACK=false
VALID_API_KEYS=<comma-separated list; generate each with: openssl rand -hex 16>
KEY_HASH_SECRET=<generate: openssl rand -hex 32>
TRADE_DETECTOR_MODE=legacy
```
3. **Generate JWT keys** (RS256):
```bash
# Generate private key
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
# Extract public key
openssl pkey -in private.pem -pubout -out public.pem
```
Copy the contents of each file into the corresponding env var, replacing newlines with `\n`.
4. **Deploy and verify health check:**
```bash
curl https://rgl8r-staging-api.onrender.com/health
# Should return: { "status": "ok" }
```
---
## 3. Apply Migrations + Seed
After the API service deploys successfully:
```bash
# Option A: Render Shell (from service dashboard → Shell tab)
cd /opt/render/project/src
pnpm --filter @rgl8r/api exec prisma migrate deploy --schema prisma/schema.prisma
# Option B: Local machine (using the External Database URL from Render)
DATABASE_URL="<staging-db-external-url>" \
pnpm --filter @rgl8r/api exec prisma migrate deploy --schema prisma/schema.prisma
```
### Seed staging data
```bash
# Option A: Render Shell
pnpm dlx tsx apps/api/prisma/seed-staging.ts
# Option B: Local machine (using the External Database URL from Render)
DATABASE_URL="<staging-db-external-url>" pnpm dlx tsx apps/api/prisma/seed-staging.ts
```
This creates:
- A staging tenant with synthetic test data
- Sample SIMA outcomes, SHIP shipments + findings across workflow states
- A completed job for each module
---
## 4. Vercel: Staging Web App
1. **Create new Vercel project** (or add a Preview deployment):
- Import `rgl8r-platform` repo
- Framework: Next.js
- Root Directory: `apps/web`
2. **Configure environment variables:**
```
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=<staging Clerk key>
CLERK_SECRET_KEY=<staging Clerk secret>
CLERK_SIGN_IN_URL=/sign-in
CLERK_SIGN_UP_URL=/sign-up
CLERK_AFTER_SIGN_IN_URL=/
CLERK_AFTER_SIGN_UP_URL=/
API_URL=https://rgl8r-staging-api.onrender.com
ALLOW_API_KEY_FALLBACK=false
API_KEY=<one of the keys from VALID_API_KEYS above>
ORG_ID=<staging tenant ID from seed output>
```
3. **Deploy** and verify the dashboard loads at the Vercel preview URL.
---
## 5. Verification Checklist
- [ ] `GET /health` returns 200 on staging API
- [ ] Migrations applied (no pending migrations)
- [ ] Staging seed data visible in dashboard
- [ ] SIMA tab shows screening results
- [ ] SHIP tab shows shipment audit data
- [ ] Jobs page shows completed seed jobs
- [ ] Clerk sign-in works on staging web app
---
## Notes
- **Staging data is synthetic** — never use real customer data in staging
- **ALLOW_API_KEY_FALLBACK=false** — use integration keys (`POST /api/integration-keys`) for Postman/CLI testing instead
- **Branch strategy:** Deploy `main` to staging. Production deploys from tagged releases.
- **Cost:** Render Starter Postgres (~$7/mo) + Free tier web service. Vercel free tier for preview.
- **Reset staging:** Re-run `seed-staging.ts` to reset to clean state (it clears before seeding)