# EHS: Project optimization guide

Practical recommendations for improving **dev speed**, **frontend performance**, **backend efficiency**, and **repo maintainability** in the EHS monorepo.

For ports, apps, and API boundaries, see **`APPS-AND-API-BOUNDARIES.md`**.  
For folder layout, see **`PROJECT-FOLDER-STRUCTURE.md`**.  
For SSO and deployment entry points, see **`EHS-SSO-ACCESS-AND-ENTRY-POINT-GUIDE.md`**.

---

## Overview

The EHS platform is a **multi-app monorepo**:

| Layer | Packages |
|-------|----------|
| Frontends | Master Dashboard, SAT, ORAC (Risk Assessment), SWI, PTW |
| Backends | SAT, ORAC, SWI, PTW, Master Dashboard APIs |
| Unified server | `combined-server.mjs` (default port **5012**) |

Optimization should target the area that hurts most: **local dev**, **bundle size**, **runtime**, or **maintenance**.

---

## Priority matrix

| Priority | Area | Effort | Impact |
|----------|------|--------|--------|
| 1 | Dev scripts (API + one UI only) | Low | Faster daily development |
| 2 | PTW/SWI lazy routes + lazy heavy libs | Medium | Smaller initial page load |
| 3 | `.gitignore` + remove deprecated root files | Low | Cleaner repo, fewer accidental commits |
| 4 | Split PTW CSS by route | Medium | Faster first paint on PTW |
| 5 | npm workspaces | Medium | Single install, fewer duplicate deps |
| 6 | SAT → Vite migration | High | Long-term dev/build alignment |
| 7 | DB indexes + query review | Medium | Lower API latency under load |

---

## 1. Development workflow

### Problem

Root `npm run dev` starts **six processes** at once:

- Unified API (`dev-api`)
- Master Dashboard UI
- SAT UI
- ORAC UI
- SWI UI
- PTW UI

That uses significant CPU/RAM and slows startup when you only work on one app.

### Recommendations

**Run only what you need.** Examples:

| Task | Commands |
|------|----------|
| PTW | `npm run dev-api` + `npm run dev-ptw-ui` |
| SWI | `npm run dev-api` + `npm run dev-swi-ui` |
| SAT | `npm run dev-api` + `npm run dev-sat` |
| ORAC | `npm run dev-api` + `npm run dev-orac-ui` |
| Master only | `npm run dev-master-ui` (API if login needed) |

**Suggested profile scripts** in root `package.json`:

- `dev:ptw` — API + PTW UI
- `dev:swi` — API + SWI UI
- `dev:sat` — API + SAT UI
- `dev:orac` — API + ORAC UI
- `dev:master` — API + Master Dashboard UI

**Avoid full reinstalls** unless setting up a new machine. Use per-app install scripts (`install-ptw-ui`, etc.) for the package you touch, not always `install-all`.

### API logging

`combined-server.mjs` logs every request (`console.log("[SERVER]", ...)`).

- **Development:** acceptable for debugging
- **Production:** disable or gate behind `NODE_ENV !== 'production'`; rely on structured logging or `morgan` in dev only

---

## 2. Frontend bundle size

### Current state

| App | Stack | Code splitting |
|-----|--------|----------------|
| SAT | Create React App | Yes — `React.lazy` in feature routes |
| ORAC, SWI, PTW | Vite + React | Mostly **eager** imports of all admin pages |
| PTW build | ~1.8 MB single JS chunk | Vite chunk-size warning |

PTW `AdminApp.jsx` imports every admin page up front (overview, forms, permits, tickets, etc.). SWI has no `React.lazy` usage in the same pattern.

### Recommendations

#### Route-level code splitting

Lazy-load heavy screens, especially:

- `AdminFormFillPage` (PTW)
- `AdminPermitPreviewPage` (PTW)
- Dashboard/chart pages
- SWI document editor flows

Pattern (same as SAT):

```jsx
const AdminFormFillPage = React.lazy(() => import("./AdminFormFillPage.jsx"));
```

Wrap routes in `<Suspense>` with a small loading fallback.

#### Lazy-load heavy libraries

| Library | App | Load when |
|---------|-----|-----------|
| `exceljs` | PTW | User triggers Excel export |
| `recharts` | PTW, ORAC | Dashboard route only |
| `fabric`, `cropperjs` | SWI | Editor route only |

Use dynamic `import()` inside the action or route, not at app entry.

#### Vite `manualChunks` (optional)

In each Vite app’s `vite.config.js`, split vendors:

- `react-vendor` — `react`, `react-dom`
- `chart-vendor` — `recharts` (if kept as static import on chart routes)

### SAT → Vite (long-term)

SAT still uses **CRA** (`react-scripts`); other UIs use **Vite**. That causes:

- Different env prefixes (`REACT_APP_*` vs `VITE_*`)
- Different proxies (`setupProxy.js` vs `vite.config.js`)
- Slower CRA cold starts

See **`APPS-AND-API-BOUNDARIES.md`** § “Frontend tooling alignment” for a phased migration plan.

---

## 3. CSS optimization (PTW)

### Problem

PTW loads a large stylesheet chain via `index.css`:

```css
@import "./styles/ptw-form-fill-hub.css";
@import "./ptw.css";
```

`ptw.css` is thousands of lines (admin, document form, print, management). **Every route** downloads styles for screens the user may never open.

### Recommendations

1. **Split CSS by area:**
   - `portal-shell.css` — layout, sidebar, buttons (already in `index.css`)
   - `ptw-document-form.css` — permit document / fill form
   - `ptw-admin-mgmt.css` — CRUD management screens

2. **Import document CSS only on form routes** (e.g. `AdminFormFillPage`, `AdminPermitPreviewPage`).

3. **Deduplicate** rules that exist in both `ptw-form-fill-hub.css` and `ptw.css` (e.g. `.ptw-form-fill-page`).

---

## 4. Repository and dependency hygiene

### Legacy root entry files (done)

Former repo-root stubs (`app.js`, `server.js`, `index1.js`, `index2.js`) are **archived** under `archive/legacy-servers/`. Use **`combined-server.mjs`** (`npm start` / `npm run dev-api`) or per-app `*/src/server.js` for standalone backends. See **`PROJECT-FOLDER-STRUCTURE.md`**.

### `.gitignore` (done)

Root `.gitignore` now covers all apps: `node_modules/`, `dist/`, `build/`, `.cache/`, and `*.eslintcache`. Per-app `.gitignore` files exist under Vite packages; `ptw_frontend/` and `ptw_backend/` were added where missing.

### Shared packages

| Package | Role |
|---------|------|
| `shared/hse-auth` | JWT storage, login redirect, API client — **extend this** instead of duplicating `authUtils.js` per app |
| `ehs-unified-api": "file:.."` | Present in several frontends — review whether UI packages need a dependency on the repo root |

### npm workspaces (optional)

A root `workspaces` field can:

- Run one `npm install` at repo root
- Align `axios` / `react` versions
- Reduce duplicate `node_modules` on disk

Trade-off: one-time migration effort and lockfile changes.

---

## 5. Backend and API

### Architecture

`combined-server.mjs` mounts:

| Prefix | Backend |
|--------|---------|
| `/api/sat/*` | SAT |
| `/api/*`, `/api/orac/*` | ORAC |
| `/api/swi/*` | SWI |
| `/api/ptw/*` | PTW |
| `/api/master/*` | Master Dashboard |

### Recommendations

**Database**

- Shared MySQL database `hse` across services
- Apply `docs/sql/add_performance_indexes.sql` once per environment (idempotent `CREATE INDEX IF NOT EXISTS`)
- Review repositories for N+1 query patterns (loops that query per row)

**Request bodies**

- JSON limit is **50mb** in unified server — appropriate for some media metadata; enforce upload size in middleware as well as frontend

**Static files**

- ORAC `/uploads` — in production, prefer nginx/CDN with cache headers instead of serving large files only through Node

**Error types**

- Multiple `ApiError` classes (ORAC, SWI, PTW, Master) — consider one shared error module under `shared/` over time

---

## 6. Production deployment

1. **Single public entry** — reverse proxy routes `/sat`, `/orac`, `/swi`, `/ptw`, `/master` to built static assets and `/api/*` to Node (see SSO guide).

2. **Build frontends** — `npm run build` per app; serve `dist/` with long-cache headers for hashed assets.

3. **API process** — use PM2, systemd, or container orchestration; not `node --watch`.

4. **Environment** — `NODE_ENV=production`; reduce verbose logging.

5. **Security** — run `npm run audit:all` periodically; keep `helmet` and JWT secrets per environment.

---

## 7. What not to optimize (yet)

| Avoid | Reason |
|-------|--------|
| Merging all UIs into one SPA | SSO + Master launcher is intentional |
| Removing `shared/hse-auth` | Correct consolidation point for auth |
| Microservices split | Unified API matches current scale and dev model |
| Premature DB sharding | Single `hse` DB is fine until measured bottlenecks |

---

## 8. Suggested implementation phases

### Phase A — Quick wins (1–2 days)

- [x] Document and use API + single-UI dev commands (`dev:ptw`, `dev:swi`, `dev:sat`, `dev:orac`, `dev:master`)
- [x] Extend `.gitignore` (root + PTW packages)
- [x] Gate per-request `console.log` and `morgan` to development only (`combined-server.mjs`)
- [x] Remove deprecated root server files (archived under `archive/legacy-servers/`)
- [x] Stop committing `ptw_frontend/dist/` and `swi_frontend/dist/` (untracked from git)
- [x] Remove prototype folders (`ptw form design/`, `swi_DocTestingPages`)
- [x] Update `PROJECT-FOLDER-STRUCTURE.md` (5 frontends, 5 backends, PTW, Master)

### Phase B — Frontend performance (3–5 days)

- [x] Lazy routes in PTW `AdminApp.jsx`
- [x] Lazy routes in SWI router (`AdminApp.jsx`, `UserApp.jsx`)
- [x] Lazy routes in ORAC `App.jsx`
- [x] Dynamic import for `exceljs` in PTW export
- [x] Vite `manualChunks` (function form; PTW, SWI, ORAC)

### Phase C — CSS and structure (2–4 days)

- [x] Split PTW CSS; route-scoped imports (`ptw-document-form.css` + `ptw-form-fill-hub.css` on form routes)
- [ ] Deduplicate hub vs `ptw.css` rules

### Phase D — Platform (ongoing)

- [ ] npm workspaces
- [ ] SAT → Vite migration
- [x] DB index audit (`docs/sql/add_performance_indexes.sql`)
- [ ] Reintroduce targeted automated tests if desired (smoke + critical paths)

---

## 9. Measuring success

| Metric | How to measure |
|--------|----------------|
| Dev startup | Time until UI + API ready with profile script vs full `npm run dev` |
| PTW first load | Network tab: JS/CSS transferred on first visit to admin home |
| Form fill load | JS size when opening Fill Permit Form only |
| API latency | p95 response time on list endpoints (permits, submissions) |
| Install size | Total `node_modules` disk usage after workspace migration |

---

## Related documents

| Document | Topic |
|----------|--------|
| `APPS-AND-API-BOUNDARIES.md` | Ports, scripts, API prefixes, Vite vs CRA |
| `PROJECT-FOLDER-STRUCTURE.md` | Folder layout and naming |
| `EHS-SSO-ACCESS-AND-ENTRY-POINT-GUIDE.md` | Login, JWT, reverse proxy |
| `AUTH-AND-JWT-REFERENCE.md` | Auth flows and secrets |

---

*Last updated: June 2026*
