# EHS: Which app is which

Use this when onboarding or wiring a new screen so you hit the **correct API** and **matching port**.

---

## Canonical repo paths (ORAC / Risk Assessment)

The ORAC stack lives in two top-level folders that differ only in how **`assessment`** is cased in the folder name. **Copy the strings below verbatim** into root `npm` scripts (`--prefix`), shell commands, `import`/`require` paths from the repo root, and documentation so tools behave the same on Windows, Linux, and CI.

**Mnemonic:** backend directory uses a **lowercase** `a` in `assessment` (`Risk_assessment_*`); the frontend directory uses an **uppercase** `A` (`Risk_Assessment_*`). Do not “fix” this by normalizing paths in scripts—folder renames are disruptive; match reality.

| Role | Folder (exact spelling) | `package.json` name (for logs / `npm ls`, not a path) |
|------|-------------------------|-------------------------------------------------------|
| ORAC **API** (Express, mounted by `combined-server.mjs`) | `Risk_assessment_backend/` | `orac-risk-assessments-api` |
| ORAC **UI** (Vite + React) | `Risk_Assessment_Frontend/` | `orac-risk-assessment-ui` |
| SWI **API** | `swi_backend/` | `swi-api` |

Renaming folders is intentionally out of scope for day-to-day work; treat this table as the naming source of truth when you add scripts or docs.

---

## Applications (frontends)

| App | Folder | Stack | Typical dev URL | What it is |
|-----|--------|--------|-----------------|------------|
| **Master Dashboard** (sole HSE login) | `Master_Dashboard_Frontend/` | Vite + React | `http://localhost:5174` | Login + project launcher; auth at `/api/master/auth/*` |
| **SAT Portal** (satellite) | `SAT_Frontend/` | Create React App (React 18) | `http://localhost:3000/dashboard` | Audits, forms, tickets — SSO from Master |
| **ORAC Risk Assessment UI** | `Risk_Assessment_Frontend/` | Vite + React 19 | `http://localhost:5173` (Vite default) | Risk assessment flows (admin / user / executor). Proxies `/api` to the unified API in dev. |
| **SWI Admin UI** | `swi_frontend/` | Vite + React 18 | `http://localhost:5175` (default) | Admin: create & assign documents. SSO from Master Dashboard. |
| **PTW Admin UI** | `ptw_frontend/` | Vite + React 18 | `http://localhost:5176` (default) | Permit to Work admin. SSO from Master Dashboard. |

**Port clash:** Risk Assessment uses **5173**; Master Dashboard uses **5174** by default.

---

## Frontend tooling alignment (CRA vs Vite)

**Today:** `SAT_Frontend` ships on **Create React App** (`react-scripts` 5.x, React 18). `Risk_Assessment_Frontend` and `Master_Dashboard_Frontend` use **Vite** (React 19 on those trees). That split is historical, not intentional long-term architecture.

**Why align:** Same repo, different tooling means duplicated mental load — env prefixes (`REACT_APP_*` vs `VITE_*`), dev proxies (`SAT_Frontend/src/setupProxy.js` vs Vite `server.proxy`), ESLint setup (CRA preset vs flat config), tests (`react-scripts test` vs Vitest), and slower CRA cold starts. Documenting either a **migration path** or an explicit **stay-on-CRA decision** avoids silent drift and “which pattern do I copy?” confusion.

### Recommended direction: gradual SAT → Vite

Use when SAT remains actively developed and you want one modern default for new UI work.

1. **Env and build parity** — Inventory `REACT_APP_*` in SAT; plan a `VITE_*` map (and `.env.example` updates). Confirm `public/` assets and any `%PUBLIC_URL%`-style usage; Vite uses root `index.html` + `/public`.
2. **Scaffold Vite beside existing** — Add `vite.config.js`, `index.html` at package root, `@vitejs/plugin-react`. Mirror Risk’s proxy targets (`VITE_DEV_API_PROXY_TARGET` → same port as unified API) so behaviour matches `setupProxy.js` / `REACT_APP_PROXY_TARGET`.
3. **Cut over dev first** — Point `package.json` `dev` at Vite; keep `react-scripts build` until dev is stable, or switch both once smoke-tested.
4. **Tests and lint** — Prefer **Vitest** + Risk-style ESLint when dropping `react-scripts test`; align CI with the chosen commands.
5. **React version** — Vite does not require React 19 immediately; you can migrate bundler first (stay on React 18), then upgrade React in a follow-up for closer parity with Risk/Master.
6. **Root scripts and deploy** — Update repo root `dev` / `build-sat` and any pipeline or Docker build that assumes `react-scripts build`.

After migration, **deprecate** `react-scripts` and remove CRA-only files (`setupProxy.js`, `reportWebVitals` if unused, etc.) in the same PR series so the tree has one story.

### When CRA might stay (document it explicitly)

Keeping SAT on CRA is reasonable if migration ROI is low (maintenance-only app, no SAT roadmap), external hosting/build constraints require it, or capacity is limited. In that case, **record the decision here or in team notes** (owner, review date, reason) so contributors know new satellite UIs should still default to **Vite** and SAT is the documented exception — not an ambiguous second standard.

---

## Unified API (backend in one process)

| Piece | Folder / entry | Purpose |
|-------|------------------|--------|
| **Unified server** | Repo root: `combined-server.mjs` | One Node process serves **SAT** and **ORAC** APIs together. |
| **ORAC API implementation** | `Risk_assessment_backend/` | Express routers, JWT, uploads; imported by `combined-server.mjs` (exact name: [Canonical repo paths](#canonical-repo-paths-orac--risk-assessment)). |
| **SWI API** | `swi_backend/` | `/api/swi/*` — mounted in `combined-server.mjs`; see `swi_backend/API_DOCUMENTATION.md`. |

- **Listen port:** `PORT` or `APP_PORT` from the environment (see [Env files](#environment-files)). Code default: **5000** (`combined-server.mjs`).
- **Static files:** `/uploads` → `Risk_assessment_backend/uploads/`.

**How to run locally (single source of truth):** use **`combined-server.mjs`** from the repo root so SAT (`/api/sat/*`) and ORAC (`/api/*`) always match deployment. Prefer this doc + root `package.json` scripts over tribal knowledge or alternate entry files.

| Goal | Command (from repo root unless noted) |
|------|----------------------------------------|
| Full stack (API + Master + SAT + ORAC + SWI + PTW) | `npm run dev` |
| API only | `npm start` or `npm run dev-api` |
| Integration / API smoke tests (auth guards, health, validation) | `npm test` |
| ORAC UI unit / Vitest | `npm test` in `Risk_Assessment_Frontend/` |
| SAT UI tests (Jest via CRA) | `npm test` in `SAT_Frontend/` (set `CI=true` in CI for non-interactive runs) |
| `npm audit` on root + every app/backend package | `npm run audit:all` |

**Local dev (recommended):** from repo root, `npm run dev` runs:

1. **API** — `node --watch combined-server.mjs`
2. **Master Dashboard** — `Master_Dashboard_Frontend` on port **5174**
3. **SAT**, **ORAC UI**, **SWI**, **PTW** — respective dev servers

---

## NPM scripts (repo root)

`--prefix` values use **exact folder names** from [Canonical repo paths](#canonical-repo-paths-orac--risk-assessment) (`SAT_Frontend`, `Risk_Assessment_Frontend`, …). Prefer **`orac-*` script names** for the ORAC UI/API so script names do not depend on the fragile `assessment` / `Assessment` folder split; `*-risk` entries remain as aliases.

| Script | What it runs |
|--------|----------------|
| `npm start` | Unified API only: `node combined-server.mjs` |
| `npm test` | Unified API integration tests (`tests/integration/`, Vitest + supertest) — no server listen |
| `npm run audit:all` | Runs `npm audit` in root, `SAT_Frontend`, `SAT_backend`, `Risk_assessment_backend`, `Risk_Assessment_Frontend` |
| `npm run dev` | API (watch) + Master Dashboard + SAT + ORAC UI + SWI + PTW (via `concurrently`) |
| `npm run dev-master-ui` | Master Dashboard frontend only |
| `npm run dev-api` | Unified API with `--watch` only |
| `npm run dev-sat` | SAT frontend only |
| `npm run dev-orac-ui` | ORAC Risk Assessment frontend only (same as `npm run dev-risk`) |
| `npm run dev-orac-api` | ORAC API package only (`nodemon` in `Risk_assessment_backend/`) — use when debugging the standalone server, not the unified `combined-server.mjs` |
| `npm run build-sat` / `npm run build-orac-ui` | Production builds (`build-risk` is an alias of `build-orac-ui`) |
| `npm run install-orac-api` / `npm run install-orac-ui` | Installs dependencies in ORAC backend / UI (`install-risk` aliases `install-orac-ui`) |
| `npm run install-all` | Root install + ORAC API + SAT + ORAC UI |

**Note:** Master Dashboard in `SAT_Frontend` has been removed from routes; use `Master_Dashboard_Frontend/` as the shell.

---

## Master & personalized dashboard — source of truth

| Deployment | Canonical location | Routes (SAT app) |
|------------|-------------------|------------------|
| **Embedded in SAT (production-style)** | `SAT_Frontend/src/components/features/master-dashboard/` | `/` → **Master Dashboard**, `/personalized-dashboard` → **Personalized Dashboard** (`SAT_Frontend/src/App.js`). |

**Rules for contributors**

1. **Implement and review all master/personalized dashboard changes only under `SAT_Frontend`** — styling, routing, tiles, links to Risk Assessment (`REACT_APP_RISK_ASSESSMENT_URL`), etc.
2. **`Master_Dashboard_Frontend/`** mirrors older/copied UI files but **`src/App.jsx` is still the default Vite starter** — it does **not** mount the dashboard shell. Treat this folder as **not shipped** unless you deliberately finish wiring `BrowserRouter`, auth, and parity with SAT and add it to CI/root scripts.
3. **Do not** copy fixes into both trees indefinitely. If you need a standalone Vite shell later, either promote one codebase (migrate SAT to Vite) or wire `Master_Dashboard_Frontend` once and delete duplication — avoid silent divergence.

---

## Environment files

Files are loaded in **this order** by `combined-server.mjs` (later values override earlier ones for duplicate keys):

1. **Repo root** — `.env` (optional; not always present in repo)
2. **`SAT_backend/.env`**
3. **`Risk_assessment_backend/.env`**

**Templates (safe to commit):**

- `SAT_backend/.env.example` — MySQL (`MYSQL_*` or shared `DB_*` from ORAC env), JWT / Google hints for SAT.
- `Risk_assessment_backend/.env.example` — `APP_PORT`, `DB_*`, JWT role secrets, `ALLOWED_ORIGINS`, etc.
- `Risk_Assessment_Frontend/.env.example` — `VITE_DEV_API_PROXY_TARGET`, optional `VITE_API_BASE_URL`, SAT/master URLs for redirects.

Copy examples to real `.env` files locally; **never commit real secrets.**

### Port alignment (avoid 502 / CORS surprises)

Everyone must agree on **one** HTTP port for the unified API:

- Set **`PORT` or `APP_PORT`** consistently (root `.env` and/or backend `.env` files).
- **Risk Assessment (Vite):** `VITE_DEV_API_PROXY_TARGET` must point at that same origin, e.g. `http://localhost:5000` or `http://localhost:5001`. Default in `vite.config.js` is **5000**; `Risk_assessment_backend/.env.example` suggests **5001** for `APP_PORT` — pick one and match the Vite env.
- **SAT (CRA):** `SAT_Frontend/src/setupProxy.js` defaults the proxy target to **`http://127.0.0.1:5001`**. Override with **`REACT_APP_PROXY_TARGET`** so it matches your unified API port.

---

## API boundaries: SAT vs ORAC

Both run in the **same** `combined-server.mjs` process but use **different URL prefixes** and **different auth styles**.

### SAT — prefix `/api/sat`

- **Audience:** SAT Portal (audits, forms, ticketing, SAT users, Google OAuth session, etc.).
- **Examples:**
  - `POST /api/sat/login` — email/password login
  - `GET /api/sat/health` — health check
  - Google OAuth routes under `/api/sat/auth/google`, etc.
- **Auth:** SAT’s own login + Passport/Google as implemented in `SAT_backend` (mounted under `/api/sat`).

### SWI — prefix `/api/swi`

- **Audience:** SWI application (scaffold; routes to be added under `swi_backend/src/routes/`).
- **Health:** `GET /api/swi/health` (standalone `swi_backend` on `APP_PORT`, default **5002**).
- **Login:** `POST /api/swi/auth/login` (issues same JWT family as ORAC).
- **Auth:** `Authorization: Bearer` — verifies `JWT_SECRET`, `JWT_USER_SECRET`, `JWT_ADMIN_SECRET`, `JWT_EXECUTOR_SECRET` (from `Risk_assessment_backend/.env` / SAT).
- **CRUD:** `/api/swi/<table>` — SWI document tables + shared `hse` lookups; admin-only for `users`, `roles`, etc.

### ORAC (Risk Assessment API) — prefix `/api` (not under `/sat`)

- **Health:** `GET /api/health`
- **Login (JWT issuance for ORAC):** `POST /api/auth/login`
- **All ORAC business APIs:** under **`/api/orac`** — JWT required (`Authorization: Bearer …`). Role-specific secrets (user / admin / executor, etc.) are validated in `Risk_assessment_backend` middleware.
- **Admin-only:** routes under `/api/orac` that use `requireAdmin` (users, roles, countries, …).

**Rule of thumb:**

- Building or debugging **SAT Portal** → call **`/api/sat/...`** (or rely on CRA proxy: browser uses `/api`, dev server forwards to the host/port in `setupProxy.js`).
- Building or debugging **Risk Assessment UI** → call **`/api/...`** (Vite proxies `/api` and `/uploads` to the unified server); protected resources are under **`/api/orac/...`** with the ORAC JWT.

### Same database schema

SAT and ORAC backends both use the **`hse`** MySQL schema (see comments in `SAT_backend/.env.example` and `Risk_assessment_backend/.env.example`). They are still **separate APIs** — do not mix SAT and ORAC tokens or route prefixes in one client without a deliberate integration design.

### Overlapping concepts across APIs

*Examples:* users, tickets, RPN, and similar terms — they may appear in both SAT and ORAC with **different auth models** and **different route trees**. That is expected at the boundary layer. **Do not** treat “duplicate concepts” as a signal to blindly merge `SAT_backend` and `Risk_assessment_backend` into one codebase — that usually collapses unrelated auth and coupling without clarifying ownership.

Prefer **product and platform** improvements instead:

| Lever | Purpose |
|-------|--------|
| **Shared OpenAPI (or equivalent contracts)** | Document each prefix (`/api/sat/*` vs `/api/orac/*`), security schemes (session/Google vs Bearer JWT), and schemas so teams see whether two endpoints refer to the **same** resource or **homonyms**. |
| **Shared DB naming conventions** | Where both sides touch `hse`, align table/column naming and document **who owns writes** so parallel routes do not silently diverge on meaning. |
| **Explicit duplication rules** | Per entity or table: decide **system of record**, **read-only mirror**, **sync/event**, or **intentionally separate domains** — including “never expose this entity from both APIs” when that is the rule. |

When you need **one** client flow spanning SAT and ORAC, design **integration** (which token, which calls, redirects) explicitly; see the checklist below.

---

## Quick checklist for new work

1. Which UI am I in — **SAT** or **Risk Assessment**?
2. Which prefix — **`/api/sat`** vs **`/api`** / **`/api/orac`**?
3. Is unified API port the same in **`.env`**, **Vite `VITE_DEV_API_PROXY_TARGET`**, and **`REACT_APP_PROXY_TARGET`** (SAT)?
4. ORAC-only: did I attach the **ORAC JWT** for `/api/orac/*`?
5. Cross-cutting entity (user, ticket, RPN, …): does this change respect **which API owns it** and any **documented duplication rule** ([Overlapping concepts across APIs](#overlapping-concepts-across-apis))?

---

## Legacy / alternate entrypoints

**Do not use archived root stubs for local development.** Former repo-root files (`app.js`, `server.js`, `index1.js`, `index2.js`) were removed; copies are in **`archive/legacy-servers/`** for reference only. **`combined-server.mjs`** is the supported unified entry (see [Unified API](#unified-api-backend-in-one-process)).

| Entry | Role |
|-------|------|
| `combined-server.mjs` | **Default** — one process, production-style URL prefixes |
| `SAT_backend/src/index.js` | Standalone SAT backend if you intentionally skip unified routing |
| `Risk_assessment_backend/src/server.js` | Standalone ORAC backend |
| `swi_backend/src/server.js` | Standalone SWI backend |
| `ptw_backend/src/server.js` | Standalone PTW backend |
| `master_dashboard_backend/src/server.js` | Standalone Master Dashboard backend |

For **local development aligned with this doc**, use **`npm start`** or **`npm run dev-api`** with **`combined-server.mjs`** at the repo root unless your team documents a different process.

---

## Related documentation

| Doc | Purpose |
|-----|---------|
| **`PROJECT-FOLDER-STRUCTURE.md`** | Full repo tree, backend/frontend layout, feature folders, “where to look” map |
| **`EHS-PROJECT-OPTIMIZATION-GUIDE.md`** | Dev workflow, bundle/CSS/backend optimization, deployment |
| **`AUTH-AND-JWT-REFERENCE.md`** | JWT secrets, roles, login endpoints |
| **`RPN-HOW-IT-WORKS.md`** | Risk Priority Number logic |
