# Per-API scoped CORS rollout

Each API process (`devapi`, `hjapi`, `tsrapi`, etc.) should only allow browser origins for client master rows that share its `APIUrl`.

## Deploy steps

1. Merge backend changes and pull on the VPS (skcsolut deploy orchestrator).
2. **Redeploy backend per client** (API owner only when deploy reports `shared_api` skip).
3. Suggested order: HJ → TSR → devapi → remaining environments.
4. Each redeploy rewrites target `.env` with:
   - `CORS_API_URL` — normalized API base (e.g. `https://hjapi.hjenterprises.co.in/api/v1`)
   - `CORS_STATIC_ORIGINS` — short scoped list
   - `CORS_CLIENT_URL` / `CLIENT_URL` — site URL for dedicated tenant mode
   - `PUBLIC_HTML_ROOT` + `TENANT_MODE=dedicated` when applicable

5. Restart pm2 for that API host after deploy.

## Verification (per API)

```bash
curl -i -X OPTIONS "https://<api-host>/api/v1/hj-enquiry/createContactUsEnq" \
  -H "Origin: https://<matching-client-url>" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: content-type"
```

Expect `Access-Control-Allow-Origin: https://<matching-client-url>` and a 2xx status.

Wrong origin (e.g. another client’s site) should **not** receive that header.

## pm2 logs

On startup look for:

`CORS origins loaded: N total (scoped API <host>, M client row(s) from DB)`

Dedicated hosts may show `M=0` if master DB is unreachable; env origins must still apply.

## Dedicated tenant APIs

When `PUBLIC_HTML_ROOT` or `TENANT_MODE=dedicated` is set, `dbSwitcher` uses `DB_NAME_DEV` for request data (no master lookup per request).

Optional **scoped CORS refresh** from the `client` table uses [`MASTER_DB_*`](MASTER_DB_SETUP.md) on dedicated hosts. See **MASTER_DB_SETUP.md** for MySQL user and cPanel Remote MySQL steps.
