# MODULE-MAP — DALSEEN / SAAED Frontend

> **Verified accurate:** 2026-05-02 — boot-sequence groups, namespace cheat sheet, dependency graph, routing model, and persistence table all hold against current source. **File census + script count are stale** — see updated numbers below.
> **Status:** active source-of-truth doc; the "read this first" map every other handoff references.

**Audience:** integration team taking the existing prototype and wiring it to the production backend.
**Goal of this doc:** a complete, browseable map of what code lives where, in what load order, what each file owns, and what depends on it. Read this **once** before touching any other doc — every other handoff doc references the file paths and module-namespace names canonized here.

> **Scope.** Frontend only — `index.html` plus everything under `front/`. Backend & `docs/openapi/` are separate.
> **File census** (verified 2026-05-02): **177 source files** across `front/`, broken down `front/accounting: 30 · front/api: 13 · front/common: 32 · front/dine: 4 · front/owner: 31 · front/pay: 3 · front/platform: 10 · front/retail: 53 · front/app-main.compiled.js: 1` — by extension `.js × 147 · .jsx × 30`. The growth since the original 146-file census is the eight `api-namespace-batch{1,3-8}.js` files plus per-batch screen files (`retail-screens-batch5`, `dine-screens-batch6`, `pay-screens-batch7`, `xcut-screens-batch7`, `accounting/batch1-*`, `accounting/batch3-screens`, `common/batch7-atoms`) and a handful of screen splits in retail/owner/accounting.
> **Script tag count** (verified 2026-05-02): **160 `<script src=…>` tags in `index.html`** (was ~110 at original write-up). The added 50 are batch namespaces, batch screen files, and screen splits.
> **Build artefacts.** Most files have a `.compiled.js` suffix — they are pre-Babel-transformed copies of `.jsx` source kept in the repo so the runtime can `<script src=…>` them directly without the in-browser Babel step paying for them. Treat the `.compiled.js` as the **canonical runtime artefact**; the `.jsx` source for each is alongside it where present, and is what the integration team should edit. Files loaded as `<script type="text/babel" src=…>` (every `.jsx` listed in `index.html`) are transformed at runtime by Babel-standalone — slower to boot, but simpler to iterate. Mixing both is intentional: hot-path files are pre-compiled, newer / edit-heavy files run through Babel.

---

## 0 · TL;DR for the integration team

- The whole app boots from a **single `index.html`** that imports ~160 inline `<script>` tags in a strict, dependency-ordered sequence. There is **no bundler, no module system, no JSX runtime resolver** beyond Babel-standalone.
- Components publish themselves on `window.*` (e.g. `window.RetailPOS`, `window.AcctStore`). Cross-file dependency is by global lookup, not import.
- The runtime split is **5 concerns**: (a) tokens / strings / roles, (b) the `window.API` mock backend, (c) per-system hooks (data layers), (d) screens (React components), (e) the shell (`app-main`) that picks which screen to render based on `nav` + `role`.
- **Eight functional modules** sit under `front/`:
  `api/` · `common/` · `retail/` · `pay/` · `dine/` · `owner/` (HR + Owner Console) · `accounting/` (Saaed Books) · `platform/` (DALSEEN Super Admin).
- Routing is a **string `nav` ID held in React state** in `app-main.compiled.js` — it is _not_ URL-based. The full nav catalogue is the `window.DALSEEN_NAV` array in `front/common/tokens.js`. Role gating is `window.canSee(role, navId)` in `front/common/roles.js`.
- The only persistence is `localStorage` + `sessionStorage`. There is no IndexedDB, no service worker, no cookies in use.

---

## 1 · Boot sequence (`index.html`)

The order matters. Each numbered group must finish loading before the next can run, because later groups read `window.*` symbols set by earlier ones.

```
index.html
└── <head>
    ├── Google Fonts: Fraunces · Inter Tight · IBM Plex Sans Arabic · Amiri
    ├── React 18.3.1 (UMD, dev build) + integrity pin
    ├── ReactDOM 18.3.1 (UMD, dev build) + integrity pin
    ├── @babel/standalone 7.29.0 + integrity pin
    └── inline <style>: CSS reset, RTL bidi rules, POS fullscreen overrides

└── <body>
    ├── #root            ← React mounts here
    │
    ├── ── 1. PRIMITIVES ─────────────────────────────────────
    │  front/common/tokens.js              window.DALSEEN_TOKENS, _SYSTEMS, _NAV, _PROFILES, _DATA, _KIND_LABEL, _RETAIL_GROUPS, _HR_GROUPS
    │  front/common/strings.js             window.STRINGS (en/ar), window.fmtSAR, window.fmtNum
    │  front/common/roles.js               window.DALSEEN_ROLES, _PERMS, _ROLE_POLICIES, _RETAIL, _PLATFORM, _ONBOARDING_STEPS, _HEALTH_FACTORS; window.canSee, isReadonly, getRolePolicy
    │  front/common/api.js                 legacy thin wrapper (kept for back-compat)
    │  front/common/loading.js             skeleton + spinner primitives
    │  front/common/api-seeds.js           seed data shared by api/ and legacy api.js
    │
    ├── ── 2. window.API foundation ──────────────────────────
    │  front/api/api-foundation.js         API.id (ULID), API.Money, API.Bilingual, ApiError class, in-memory store
    │  front/api/api-session.js            API.session.{user,tenant,branch,can,permissions,branchId,locale,set}
    │  front/api/api-fetch.js              API.call(method, path, opts) — routes through API.mock.register handlers
    │  front/api/api-namespace.js          Core endpoint definitions: /auth, /me, /catalog, /inventory, /crm, /purchasing, /sales, /shifts, /accounting, /owner, /platform — and the typed helper namespaces (API.catalog.products.*, API.crm.*, API.purchasing.*, API.sales.*, API.shifts.*, API.accounting.*, API.owner.*, API.platform.*)
    │  front/api/api-namespace-batch{1,3-8}.js   Eight batch-namespace expansions loaded AFTER api-namespace.js — they extend the API surface (vendor mgmt, customers/promotions/loyalty, pricing/vendor-360, etc.) without altering the load contract. See API-USAGE-MAP.md for the per-batch surface.
    │  front/api/api-hooks.jsx             React hooks: useApiQuery, useApiMutation, useApiInfinite
    │  front/api/api-states.jsx            Loading / Empty / Error UI primitives keyed off the hooks above
    │
    ├── ── 3. RETAIL DATA HOOKS (must precede screens) ───────
    │  front/retail/retail-hooks.js        window.RetailHooks — branches/products/stock/transfers/PO/RFQ/categories
    │  front/retail/ops-hooks.js           window.OpsHooks — receiving, returns, expiry
    │  front/retail/zero-friction-hooks.js window.ZFHooks — Zero-Friction (ambient inventory) data
    │
    ├── ── 4. ICONS + SHELL ─────────────────────────────────
    │  front/common/icons.compiled.js      window.Icon (single SVG-icon component, ~50 glyphs)
    │  front/common/shell.compiled.js      window.Sidebar, window.Topbar, window.systemColor, window.useT
    │  front/common/shell-polish.jsx       hover/focus polish layer (Babel-loaded)
    │  front/common/shared.compiled.js     window.SharedScreens.* generic placeholders
    │  front/common/dashboard.compiled.js  window.Dashboard
    │  front/common/dashboard-splash.compiled.js  window.DashboardSplash (first-load animation)
    │
    ├── ── 5. RETAIL SCREENS (~30 files) ────────────────────
    │  product-thumb · retail · retail-ext · retail-transfers · retail-inventory · retail-inventory-flows
    │  retail-expiry-wastage · retail-growth-ops · users-access · retail-flow · retail-receipts · retail-cfd
    │  zatca-qr · retail-checkout · retail-returns-flow · retail-receipt-share · retail-complete
    │  zf-ui-core · zf-screen-tabs1/2 · zf-screen-main
    │  pos-flow-data · pos-flow-mocks · pos-flow-ui
    │
    ├── ── 6. PAY SCREENS ───────────────────────────────────
    │  front/pay/pay.compiled.js           SoftPOS · Terminals · Settlements · Disputes · Methods · Payouts
    │  front/pay/pay-modules.compiled.js   shared pay sub-components
    │
    ├── ── 7. DINE SCREENS ──────────────────────────────────
    │  front/dine/dine.compiled.js         Order · Tables · KDS · Menu · Recipes · Waiter · Reservations · Delivery · Reports
    │  front/dine/dine-modules.compiled.js shared dine sub-components
    │
    ├── ── 8. SHARED MODULES ────────────────────────────────
    │  front/common/shared-modules.compiled.js  ZATCA · CRM · AI · BI · Manufacturing screens
    │
    ├── ── 9. PLATFORM (Super Admin) ────────────────────────
    │  platform · dalseen-billing-data · dalseen-commercial-screens · platform-screens · platform-admin
    │  tenant-actions · billing-actions · new-tenant-wizard · platform-health · platform-live (Babel)
    │
    ├── ── 10. OWNER + HR (~15 files) ───────────────────────
    │  owner-data · owner-home · owner-submodules · owner-console · owner-flows-goals-legal
    │  hr-staff · hr-staff-2 · hr-leave-v2 · hr-staff-3 · hr-extended · hr-roles-policies · hr-shell
    │  hr-ess · hr-ats · hr-contracts · hr-perf · hr-learning · hr-expenses · hr-loans
    │  hr-assets · hr-helpdesk · hr-org · hr-flows · hr-directory-flow · owner-live (Babel)
    │
    ├── ── 11. CROSS-CUTTING UI ────────────────────────────
    │  front/common/modals.compiled.js     window.Modal, ConfirmDialog, Sheet
    │  front/common/auth.compiled.js       window.AuthScreen (sign-in)
    │  front/common/roles-editor.compiled.js  in-app role editor
    │  front/common/devices.js             POS hardware mock (printer, scale, scanner)
    │  front/common/biometric-shift.compiled.js  window.BiometricPrompt + start-of-shift biometric gate
    │
    ├── ── 12. ACCOUNTING (Saaed Books, ~25 files) ─────────
    │  accounting-data · accounting-flow-engine · acct-invoice-helpers · pos-gl-bridge · stock-gl-bridge
    │  dalseen-integrations (cross-module event bus)
    │  accounting-hub · -sell · -collect · -spend · -pay · -bank · -vat · -coa · -journal · -gl
    │  accounting-recurring · -opening · -periods · -reports · -settings
    │  accounting-flow-ui · -flow-defs · -flow-defs-vouchers · -flow-defs-je-actions · -flow-summary  (all Babel)
    │
    ├── ── 13. INVENTORY HUB (Babel) ───────────────────────
    │  product-kinds · table-filter-bar · inventory-tabs-a · inventory-tabs-b · suppliers-market-v2
    │  inventory-hub · add-product-v2-fields · -preview · add-product-v2 · stocktake-flow · receiving-flow
    │  retail-po · ops-bundle
    │
    ├── ── 14. ZERO-FRICTION FLOW (Babel) ──────────────────
    │  zf-flow-scenes · zf-flow · zf-flow-wrap
    │
    ├── ── 15. APP MARKETPLACE (Babel) ─────────────────────
    │  dalseen-integrations-screen · app-marketplace-screen
    │
    └── ── 16. ROOT APP ────────────────────────────────────
       front/app-main.compiled.js           function App() — auth gate, system switcher, role-aware routing, tweaks panel, impersonation, active-screen render switch
```

**Key boot invariants the integration team must preserve:**

1. `tokens.js` → `strings.js` → `roles.js` must run before _anything_ that touches theme, locale, or permissions. Most screens read `window.DALSEEN_TOKENS[theme]` at module-load time.
2. The `front/api/*` chain (foundation → session → fetch → namespace → hooks → states) **must stay in that order**. The namespace file calls `API.mock.register(...)` which reads `API.call` and `API.session.can(...)`.
3. **Retail data hooks** (`retail-hooks.js`, `ops-hooks.js`, `zero-friction-hooks.js`) load _before_ retail screens because retail screens take the global hook objects as direct references. They are not React hooks; they are namespaced singleton stores.
4. **`accounting-flow-engine.js`** initialises a global event bus (`dalseen-integrations.js`) that POS/Stock screens fire into. If it loads after a screen that posts to it, those posts no-op silently.
5. `app-main.compiled.js` MUST be last. It assumes every `window.*Screen` lookup will succeed.

---

## 2 · Module catalog

The following table is the canonical map of every front-end module. Use it as the lookup index when triaging a bug or handing off a feature.

| Module | Folder | Files | Owner namespace | Routes (nav IDs) | Role audience | Owns |
|---|---|---|---|---|---|---|
| **API mock layer** | `front/api/` | 6 | `window.API` | n/a | n/a (infrastructure) | The entire fake backend: foundation primitives, session, `API.call`, registered handlers, typed helpers, React hooks, loading/empty/error UI |
| **Common / Shell** | `front/common/` | 21 | `window.DALSEEN_*`, `window.Sidebar`, `window.Topbar`, `window.Dashboard`, `window.Modal`, `window.AuthScreen`, `window.Icon`, `window.SharedScreens`, `window.BiometricPrompt` | `dashboard`, plus all chrome | All | Tokens, strings, roles, the shell, dashboards, modals, auth, the icon set, biometric gate, role-policy enforcement |
| **Retail** | `front/retail/` | 50 | `window.RetailHooks`, `window.OpsHooks`, `window.ZFHooks`, `window.RetailPOS`, `window.RetailFlow`, `window.InventoryHub`, `window.ZeroFrictionScreen` (and ~25 more `*Screen` exports) | `retail.pos`, `retail.posflow`, `retail.zerofriction`, `retail.returns`, `retail.receipts`, `retail.cfd`, `retail.inventory`, `retail.suppliers`, `retail.customers`, `retail.promo`, `retail.giftcards`, `retail.bundles`, `retail.layaway`, `retail.branches`, `retail.users`, `retail.roles` | `owner`, `manager`, `cashier`, `accountant`, `auditor`, `warehouse` | The POS, the Inventory Hub (tabbed), purchasing (PO + RFQ), receiving, stocktake, transfers, expiry/wastage, customers + loyalty, promotions, gift cards, bundles, layaway, the Customer Facing Display (CFD), receipts/invoices, returns, and the Zero-Friction (ambient inventory) flow |
| **Pay** | `front/pay/` | 2 | `window.PaySoftPOS`, `window.PayTerminals`, `window.PaySettlements`, `window.PayDisputes`, `window.PayMethods`, `window.PayPayouts` | `pay.softpos`, `pay.terminals`, `pay.settlements`, `pay.disputes`, `pay.methods`, `pay.payouts` | `owner`, `manager`, `cashier`, `accountant` | SoftPOS (Tap-to-Phone), terminal fleet, settlements, disputes/chargebacks, payment methods (mada / Visa / Mastercard / cards), payouts |
| **Dine** | `front/dine/` | 2 | `window.DineOrder`, `window.DineTables`, `window.DineKDS`, `window.DineMenu`, `window.DineRecipes`, `window.DineWaiter`, `window.DineReservations`, `window.DineDelivery`, `window.DineReports` | `dine.order`, `dine.tables`, `dine.kds`, `dine.menu`, `dine.recipes`, `dine.waiter`, `dine.reservations`, `dine.delivery`, `dine.reports` | `owner`, `manager`, `waiter`, `chef` | Restaurant POS (order screen), floor plan, KDS, menu + modifiers, recipes/ingredients, waiter handheld, reservations, delivery dispatch, dine reports |
| **Owner + HR** | `front/owner/` | 29 | `window.OwnerConsole`, `window.OwnerHome`, `window.OwnerPlan`, `window.OwnerInvoices`, `window.OwnerSupport`, `window.OwnerStaff`, `window.HR*` (Overview, Directory, Org, Attendance, Shifts, Leave, Payroll, EOSB, Expenses, Loans, Recruit/ATS, Performance, Learning, Saudization, Contracts, Policies, Documents, Assets, Helpdesk, ESS) | `owner.console`, `owner.staff`, `owner.plan`, `owner.invoices`, `owner.support`; `hr.overview`, `hr.directory`, `hr.org`, `hr.attendance`, `hr.shifts`, `hr.leave`, `hr.payroll`, `hr.eosb`, `hr.expenses`, `hr.loans`, `hr.recruit`, `hr.performance`, `hr.learning`, `hr.saudization`, `hr.contracts`, `hr.policies`, `hr.documents`, `hr.assets`, `hr.helpdesk`, `hr.ess` | `owner` (Owner system); `owner`, `manager`, `accountant` (HR system) | Two distinct surfaces co-located in one folder: the **Owner Console** (executive surface — only the `owner` role sees it) and the full **HR / People Ops** module (Directory, Org, Time-off & Attendance, Shifts, Payroll/WPS, EOSB, Expenses, Loans, ATS, Performance, LMS, Saudization/Nitaqat, Contracts, Policies, Documents, Assets, Helpdesk, ESS) |
| **Accounting (Saaed Books)** | `front/accounting/` | 25 | `window.AcctStore`, `window.AcctData`, `window.AcctFlow`, `window.AcctHub`, `window.AcctSell`, `window.AcctCollect`, `window.AcctSpend`, `window.AcctPay`, `window.AcctBank`, `window.AcctVAT`, `window.AcctCoA`, `window.AcctJournal`, `window.AcctGL`, `window.AcctReports`, `window.AcctSettings`, `window.AcctRecurring`, `window.AcctOpening`, `window.AcctPeriods` | `shared.accounting` (the hub — tabs inside route to `acct.sell`, `acct.collect`, `acct.spend`, `acct.pay`, `acct.bank`, `acct.vat`, `acct.coa`, `acct.journal`, `acct.reports`) | `owner`, `manager`, `accountant`, `auditor` | Sell · Collect · Spend · Pay · Banking · VAT/ZATCA · Chart of Accounts · Journal · GL · Reports (P&L, BS, TB) · Recurring · Opening Balances · Periods · Settings; the **flow engine** that wraps every voucher/invoice/journal action; the **POS↔GL** and **Stock↔GL** bridges |
| **Platform (Super Admin)** | `front/platform/` | 10 | `window.PlatformDashboard`, `window.PlatformTenants`, `window.PlatformSignups`, `window.PlatformOnboarding`, `window.PlatformWorkbench`, `window.PlatformPlans`, `window.PlatformBilling`, `window.PlatformSupport`, `window.PlatformHealth`, `window.PlatformCompliance`, `window.PlatformIncidents`, `window.PlatformReleases`, `window.PlatformAudit` | `platform`, `platform.tenants`, `platform.signups`, `platform.onboarding`, `platform.workbench`, `platform.plans`, `platform.billing`, `platform.support`, `platform.health`, `platform.compliance`, `platform.incidents`, `platform.releases`, `platform.audit` | `superadmin` only (`platform.releases` is public-readable per `canSee`) | The cross-tenant operator surface: tenant directory, signups inbox, onboarding tracker, plans & pricing, billing, support desk, system health, compliance, incidents, releases, audit log; tenant impersonation flow; new-tenant wizard |

> **Numbers caveat.** "Files" counts include the `.compiled.js` artefacts of files that also have a `.jsx` source — `front/retail/` contains both, hence the apparently-large 50-file count.

---

## 3 · The eight runtime namespaces (cheat sheet)

These are the global objects every screen reaches for. **Treat them as the public API of each module** for cross-module use.

| Global | Defined in | What it owns |
|---|---|---|
| `window.DALSEEN_TOKENS` | `common/tokens.js` | `light` + `dark` design-token bundles |
| `window.DALSEEN_SYSTEMS` | `common/tokens.js` | The 4 systems (Retail / Pay / Dine / HR) |
| `window.DALSEEN_NAV` | `common/tokens.js` | Catalogue of every nav entry — id, system, group, en/ar labels, icon, badge, hidden, hasScreen, etc. |
| `window.DALSEEN_DATA` | `common/tokens.js` | Demo business data: branches, products, restaurant menu, tables, KDS tickets, AI insights, settlements |
| `window.DALSEEN_ROLES`, `_PERMS`, `_ROLE_POLICIES` | `common/roles.js` | Role catalogue + permission matrix + biometric/high-value policies |
| `window.canSee(role, navId)` | `common/roles.js` | The single role-gate function used by sidebar, topbar, app-main |
| `window.API` | `front/api/*` | The mock backend (see §5) |
| `window.RetailHooks` / `OpsHooks` / `ZFHooks` | `retail/retail-hooks.js`, `ops-hooks.js`, `zero-friction-hooks.js` | Retail data layer — branches, products, stock, transfers, PO, RFQ, receiving, returns, expiry, ZF events |
| `window.AcctStore` | `accounting/accounting-data.js` (+ flow-engine) | Accounting data store: Chart of Accounts, journals, GL, vouchers, vat periods, settings.accountingMode |
| `window.AcctFlow` | `accounting/accounting-flow-engine.js` | The flow engine that wraps every voucher/invoice/journal action |
| `window.DALSEEN_OWNER` | `owner/owner-data.js` | Owner Console fixture data |
| `window.DALSEEN_PLATFORM` | `common/roles.js` (top) + `platform/dalseen-billing-data.js` | Platform Super-Admin fixtures |

---

## 4 · Inter-module dependency graph

```
                         ┌──────────────────────────────────────────────────────┐
                         │                  PRIMITIVES                          │
                         │  tokens · strings · roles · loading · icons          │
                         └──────────────────────────────────────────────────────┘
                                                │
                                                ▼
                         ┌──────────────────────────────────────────────────────┐
                         │                  window.API (mock backend)           │
                         │  foundation → session → fetch → namespace → hooks    │
                         └──────────────────────────────────────────────────────┘
                                                │
                ┌─────────────────┬─────────────┴─────────────┬─────────────────┐
                ▼                 ▼                           ▼                 ▼
       ┌─────────────────┐ ┌─────────────┐       ┌────────────────────┐ ┌─────────────┐
       │  RetailHooks    │ │   OpsHooks  │       │   AcctStore +      │ │  ZFHooks    │
       │  (data layer)   │ │             │       │   AcctFlow         │ │             │
       └─────────────────┘ └─────────────┘       └────────────────────┘ └─────────────┘
                │                 │                       │                   │
                ▼                 ▼                       ▼                   ▼
       ┌────────────────────────────────────────────────────────────────────────────┐
       │                     SCREEN MODULES                                         │
       │   Retail · Pay · Dine · Owner+HR · Accounting · Platform · Shared          │
       └────────────────────────────────────────────────────────────────────────────┘
                                                │
                                                ▼
                         ┌──────────────────────────────────────────────────────┐
                         │  Shell:  Sidebar · Topbar · Dashboard · AuthScreen   │
                         │  + cross-cutting:  Modal · Biometric · DevicesMock   │
                         └──────────────────────────────────────────────────────┘
                                                │
                                                ▼
                         ┌──────────────────────────────────────────────────────┐
                         │             app-main.compiled.js (App)               │
                         │   auth gate · system switcher · role-aware route     │
                         └──────────────────────────────────────────────────────┘
```

**Cross-module event bus** (`common/dalseen-integrations.js`) sits orthogonal to this graph. It is how POS posts a sale into Accounting and how Stock posts adjustments into the GL. POS → `dalseen:sale-completed` → `pos-gl-bridge.js` → `AcctFlow.recordSale(...)`. Stock → `dalseen:stock-adjusted` → `stock-gl-bridge.js` → `AcctFlow.recordStockMovement(...)`.

---

## 5 · The `window.API` mock backend (one-screen overview)

Full endpoint catalogue lives in **API-USAGE-MAP.md** (next deliverable). Headline:

- **Six files**: `api-foundation.js` (primitives) · `api-session.js` (session + permissions) · `api-fetch.js` (router) · `api-namespace.js` (1166 lines — every endpoint) · `api-hooks.jsx` (`useApiQuery`, `useApiMutation`, `useApiInfinite`) · `api-states.jsx` (`<ApiLoading>`, `<ApiEmpty>`, `<ApiError>`).
- **Resource roots registered**: `/auth`, `/me`, `/catalog/*`, `/inventory/*`, `/crm/*` (customers, suppliers), `/purchasing/*` (POs, RFQs), `/sales`, `/shifts`, `/accounting/*`, `/owner/*`, `/platform/*`.
- **Conventions** (canonical, copy these into the real backend):
  - IDs are ULIDs via `API.id()`
  - Money is `{ amount_minor: int, currency_code: 'SAR' }` via `API.Money.sar(halalas)`
  - Bilingual text is `{ name_en, name_ar }` (legacy `{ en, ar }` also accepted)
  - List endpoints accept `{ q, page, per_page, sort, ...filters }` and return `{ data: [...], meta: { total, page, per_page, last_page } }`
  - Errors throw `new API.ApiError({ code, http_status, message_en, message_ar, fields })`
  - Permission gating uses `API.session.can('catalog.products.create')` etc — strings match the `DALSEEN_PERMS` matrix
- **Persistence**: `localStorage` keys under the `api.store.*` prefix. Reload-safe.
- **Backend reference**: every handler comments back to `docs/handoff/BACKEND-MAPPING.md` where the real Laravel endpoint will live.

---

## 6 · Routing — there is no router

There is no `react-router`, no `history`, no URL routing of any kind. The "current screen" is a string ID held in React state inside `App()`:

```js
// app-main.compiled.js
const [nav, setNav] = useState(() => localStorage.getItem('dalseen:nav') || 'dashboard');
```

`renderScreen()` is a giant switch keyed off that `nav` string. It always:

1. Checks `window.canSee(role, nav)` — bounces to the role's home if denied.
2. Looks up `window.<ScreenName>` and renders it, passing `{ lang, theme, role, onNav, onRole }`.
3. Falls back to `<SharedScreens.Placeholder>` if the global is missing — useful sentinel during partial loads.

When migrating to the real app, this is the **single biggest refactor**: replace the `nav` string + switch with a real router. The good news is every screen already takes `(lang, theme, role, onNav, onRole)` props and is otherwise self-contained, so the lift is mechanical.

---

## 7 · State & persistence

| Where | Key | Owner | Lifecycle |
|---|---|---|---|
| `localStorage` | `dalseen:v3` | App tweaks (lang, theme, density, role, activeSystem, persona) | Persists forever |
| `localStorage` | `dalseen:nav` | Last-visited nav ID | Persists forever |
| `sessionStorage` | `dalseen:authed` | Authenticated user | Cleared on tab close or sign-out |
| `sessionStorage` | `dalseen:tweaks:open` | Whether the in-app Tweaks panel was opened this session | Cleared on tab close |
| `localStorage` | `api.store.*` | All `API.store` collections (catalog, crm, sales, shifts, purchasing, …) | Persists forever |
| `localStorage` | various `acct:*` | `AcctStore` (CoA, journals, GL, settings) | Persists forever |
| `localStorage` | various `dalseen:retail:*` | `RetailHooks` collections | Persists forever |
| in-memory only | `__vatSubmissions` | VAT filing submission ledger (api-namespace.js) | Lost on reload |
| in-memory only | impersonation state (`window.__impersonating`) | Super-admin impersonation context | Lost on reload |

**Production migration note**: the integration team should move `dalseen:authed` to a real session token (httpOnly cookie or short-lived JWT in memory), drop everything under `api.store.*` (replaced by real network), and keep only `dalseen:v3` (UI prefs) + `dalseen:nav` (last-route) on the client. Everything else either becomes server-side state or evaporates.

---

## 8 · What is intentionally _not_ here

- **No bundler config**, no `package.json`, no `node_modules` — there is nothing to `npm install`.
- **No tests**.
- **No translation files** beyond `STRINGS` in `common/strings.js`. Bilingual text in data is always paired `{en, ar}` or `name_en/name_ar`.
- **No icon library** beyond `common/icons.compiled.js` (~50 hand-drawn SVGs).
- **No animation library** — handful of CSS keyframes inline in `index.html` (`dalseenPulse`, `dalseenShake`, `dalseenFade`, `dalseenFadeOnly`, `dalseenFadeUp`).
- **No service worker / PWA / offline** support.
- **No analytics or telemetry**.

---

## 9 · Where to go next

| If you need to … | Read |
|---|---|
| Wire screens to real endpoints | **API-USAGE-MAP.md** (every screen → every endpoint it consumes) |
| Understand the full design language | **DESIGN-SYSTEM.md** (this turn) |
| Plan the production migration | **INTEGRATION-NOTES.md** (boot sequence, build pipeline, state, security) |
| Spec a single screen for a developer | **SCREENS-INVENTORY.md** (per-module catalogue, modals, sub-tabs) |
| Trace an end-to-end user journey | **USER-FLOWS.md** (cross-screen flows: open shift → sale → settle, hire → onboard → first payroll, etc.) |
