---
name: portal_minified_no_build
description: Portal PWA has no JS build step; *.min.js and *.nomin.js are hand-maintained in parallel and the .min.js is what runs
metadata: 
  node_type: memory
  type: project
  originSessionId: 8704cd2a-039f-4e61-a610-8ea239d35ca3
---

The `portal` repo ([[workspace_repos]]) has **no JS build/minify pipeline** (package.json is only the web-push notification server; Node isn't even installed in code-server). Pairs like `js/backgroundDataFetch.6.{min,nomin}.js`, `js/offlineScripts.{min,nomin}.js`, `js/whs.{min,nomin}.js`, `tools.{js,nomin.js}` are **hand-maintained in parallel**.

Implications when editing portal JS:
- The runtime loads the **`.min.js`**, so a fix applied only to `.nomin.js` will NOT take effect. Edit the source, then regenerate the minified twin.
- **Preferred workflow (once Node is installed):** edit only the `.nomin.js`, then `cd portal && npm run minify` (regenerates every minified target from source via esbuild; `build-min.js`). `npm run minify -- <name>` does one file; `npm run minify:check` reports drift; `npm run check` runs `node --check` over all `*.js` (catches a botched minified edit). Node + esbuild are installed by [[codeserver_setup_scripts]] `install.sh` — if `node` is missing, run that first.
- **Pairing rule:** `X.nomin.js` → `X.min.js` if it exists, else `X.js` (e.g. `tools.nomin.js`→`tools.js`, `indexDB.nomin.js`→`indexDB.js`; the other 4 use `.min.js`).
- **First-time adoption caveat:** the committed `.min` files were hand-made, so the first `npm run minify` will rewrite them with esbuild output that differs textually — verify behavior (device test) before relying on it as the source of truth.
- **Fallback only (no Node):** to edit a minified single-line file by hand, extract the exact substring with `grep -oP` and do a literal `str_replace` via `php -r`; the line is too large for the line-based Read/Edit tools.

Live entry points: `index.php` loads `js/offlineScripts.min.js` (which registers the service worker). `src/index.js` is a near-duplicate used only by legacy `index2.php` / `index_suspect.php` / `dashboard_2.inc`.

Offline data sync: the service worker (`sw.4.js`) does NOT do form sync — its `SYNC_DATA` path is dead. Real offline sync runs in the `backgroundDataFetch` Web Worker (`pushTimesheets`/`pushWHSData`). Source of truth for unsynced records is IndexDB (records flagged `push:1`); that flag is only cleared on a confirmed successful push.
