# Environment Matrix

What runs where + what each environment exists for.

| Env          | Purpose                            | Branch / Ref          | Domain                                          | Data                                  | DB engine                             |
| ------------ | ---------------------------------- | --------------------- | ----------------------------------------------- | ------------------------------------- | ------------------------------------- |
| `local`      | Day-to-day dev                     | working tree          | `localhost:4200` (web) / `localhost:5080` (API) | Synthetic seed                        | Postgres (Docker)                     |
| `staging`    | Pre-prod verification, integration | `main` (auto)         | `staging.loma-portal.example`                   | Recent anonymized snapshot            | Postgres                              |
| `uat`        | Customer / business sign-off       | manual deploy         | `uat.loma-portal.example`                       | Anonymized snapshot, refreshed weekly | Postgres                              |
| `production` | Real users                         | `vX.Y.Z` tag + manual | `portal.loma-group.example`                     | Real                                  | Postgres + optional SQL Server mirror |

## Per-env config

Generated from `.env.example` (root + `platform/secrets/.env.example`). Per-env files NEVER committed; pulled from the secret manager at deploy time.

| Variable                      | local                   | staging           | production                      |
| ----------------------------- | ----------------------- | ----------------- | ------------------------------- |
| `NODE_ENV`                    | `development`           | `staging`         | `production`                    |
| `ASPNETCORE_ENVIRONMENT`      | `Development`           | `Staging`         | `Production`                    |
| `DATABASE_URL`                | local Postgres          | managed Postgres  | managed Postgres + read replica |
| `REDIS_URL`                   | local Redis             | managed Redis     | managed Redis cluster           |
| `JWT_ACCESS_SECRET`           | dev placeholder         | secret manager    | secret manager                  |
| `S3_ENDPOINT`                 | MinIO local             | provider          | provider                        |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4318` | cluster collector | cluster collector               |
| `SENTRY_DSN`                  | —                       | staging DSN       | production DSN                  |
| `APP_LOG_LEVEL`               | `debug`                 | `info`            | `info`                          |

## CORS allowlist per env

- local: `http://localhost:4200`, `http://localhost:3000`
- staging: `https://staging.loma-portal.example`
- production: `https://portal.loma-group.example`

## Promotion path

```
local  →  staging (auto on merge to main)  →  uat (manual)  →  production (tag + manual)
```

Skip steps only with explicit DPO + Eng-lead sign-off.

## Resets

- `staging` DB refreshed nightly from a sanitized production snapshot.
- `uat` DB refreshed weekly OR on demand (kept stable for testers).
- `production` DB has continuous WAL backup + nightly base; never reset.
