# staging.passlabb.com — the test copy of Passlabb

Every change goes to **staging.passlabb.com** first (branch `staging`). When it looks right, the same commit is
promoted to **passlabb.com** (branch `main`). Staging has its own database: no real bookings, no real emails,
hidden from Google, and protected by a password.

## One-time setup (cPanel, about 15 minutes)

1. **Subdomain:** cPanel › Domains › Create a new domain: `staging.passlabb.com`
   (untick "Share document root"; the folder it suggests is fine).
2. **DNS (Cloudflare):** add a record `staging` pointing to the same server as `passlabb.com` (same type and target
   as the existing `@` / `www` record), proxied (orange cloud). SSL works like the main site.
3. **Database:** cPanel › PostgreSQL Databases:
   - create a database, e.g. `passlabb_staging` (cPanel adds your account prefix: note the full name);
   - create a user with a strong password (note it);
   - add the user to the database with all privileges.
4. **Node.js app:** cPanel › Setup Node.js App › Create application:
   - Node.js version: the same as the live app;
   - Application mode: Production;
   - Application root: `passlabb-staging/app`;
   - Application URL: `staging.passlabb.com`;
   - Application startup file: `app.cjs`.
   Create it, then stop it (it has no code yet).
5. **Settings file:** cPanel › File Manager › `passlabb-staging/app/` › create a file named `.env` with:

   ```
   NODE_ENV=production
   STAGING=1
   STAGING_PASSWORD=choose-a-password-for-the-team
   DATABASE_URL=postgres://FULL_DB_USER:DB_PASSWORD@127.0.0.1:5432/FULL_DB_NAME
   APP_URL=https://staging.passlabb.com
   SITE_URL=https://staging.passlabb.com
   TRUST_PROXY=1
   OWNER_EMAIL=amine@passlabb.com
   OWNER_PASSWORD=a-strong-password-for-staging-only
   EMAIL_WORKER=0
   ```

   - Leave out every `SMTP_*`, `BREVO_API_KEY` and payment key: staging never sends real emails.
   - `STAGING_PASSWORD` is what the browser asks for when anyone opens staging (any user name).
   - Never put these passwords in Git or in a chat.
6. Tell Claude "staging is ready": the first deploy then loads the code, creates the tables and imports the
   catalogue and the page. Sign in at https://staging.passlabb.com/#admin with `OWNER_PASSWORD`, then remove that
   line from `.env`.

## Day to day

- Claude pushes changes to the `staging` branch → tests → **staging.passlabb.com** is updated (passlabb.com is not).
- You check staging (browser password = `STAGING_PASSWORD`).
- You say "promote" → the same commit goes to `main` → tests → **passlabb.com** is updated.
- In staging, set Ops Hub › Payments to **test mode** so checkouts never take money.

## How it works

- `.github/workflows/ci.yml`, job `deploy-staging`: uploads the app folder of the commit and
  `deploy/scripts/deploy-staging.sh` to `~/passlabb-staging-incoming/`, then runs the script on the server.
- The script refuses to run unless `passlabb-staging/app/.env` contains `STAGING=1`, so it can never overwrite the
  live app. It keeps `.env` and `uploads/`, installs packages, runs the migrations, loads the page and restarts the app.
- With `STAGING=1` the app sends `X-Robots-Tag: noindex`, answers `robots.txt` with "Disallow: /", loads no
  analytics, shows a red "STAGING · not the live site" label, and (with `STAGING_PASSWORD`) asks for the password.
