# Integration Notes

> **Verified accurate:** 2026-05-02 — naming reconciliation (acct→accounting, retail.products→catalog, captureSale→sales.capture), backend-vs-frontend status drift warning, 8-stage cut-over sequence, HR split plan, AI-mock-only stance, and the 73-glyph icon catalogue all hold. The "treat OpenAPI as live source of truth" stance is now reinforced by the 2026-05-02 R-SWEEP reconciliation pass; keep this doc as the **contract & pattern reference**, not a status snapshot.
> **Status:** active source-of-truth doc; the cut-over plan + decision record + icon catalog.

**Audience:** integration engineers cutting the Dalseen front-end over to the real Laravel backend.
**Companion docs:** `MODULE-MAP.md`, `DESIGN-SYSTEM.md`, `API-USAGE-MAP.md`, `SCREENS-INVENTORY.md`, `USER-FLOWS.md`.

This file consolidates **decisions** (what's been settled), **drift** (where the FE and BE have diverged), **priorities** (the cut-over sequence), **open questions** (resolved here, with rationale), and an **icon catalogue appendix** lifted from the source.

---

## TL;DR

- Three FE-vs-BE naming conflicts are now settled in favour of the backend's canonical names (`accounting`, `catalog`, `sales.capture`).
- The frontend handoff docs were a snapshot — **the backend has moved on**. Treat Laravel code + `docs/openapi/openapi.yaml` (379 operations) as the live source of truth; treat these handoff docs as **contract & pattern reference**, not status reference.
- Cut-over is **8-stage** (Auth → Catalog → Sales → Inventory → Accounting → Workflows §1.8 → Stage modules → Platform admin). Stages 1–4 unblock the daily retail loop; everything after that is dependent layers.
- HR co-located in `front/owner/` will be split into `front/hr/` to mirror the backend module layout.
- AI panel ships **mock-only in v1.0** — backend has no streaming endpoints yet; revisit SSE for v1.1.
- Icon library is **73 glyphs**, all in `front/common/icons.compiled.js` — full catalogue at the end of this doc.

---

## A · Naming reconciliation

The frontend was written against an internal terminology that has since drifted from the backend's REST surface. The backend wins — its routes are now the contract. Three of the conflicts I called out in API-USAGE-MAP are decided:

| Frontend (current)               | Backend (canonical)            | Status                     | Action at cut-over                                                   |
|-----------------------------------|--------------------------------|----------------------------|----------------------------------------------------------------------|
| `API.acct.*`                      | `/accounting/*`                | **Decided — accounting**   | Rename namespace at `defineResource` site; add 1-line shim `window.API.acct = window.API.accounting` for transition; delete shim in v1.1. |
| `API.retail.products.*`           | `/catalog/products`            | **Decided — catalog**      | Move `retail.products`, `retail.categories` (if present), `retail.brands` to a new `catalog` namespace. Mirror `retail.customers` / `retail.suppliers` decision separately if backend has `crm` module — otherwise keep under `retail`. |
| `API.sales.captureSale(payload)`  | `POST /sales` → `sales.capture`| **Decided — sales.capture**| Rename method; keep `captureSale` as deprecated alias that logs a `console.warn` once per session and forwards to `capture`; remove in v1.1. |
| `retail.sales.*` (auto-CRUD)      | `sales.*`                      | Promote                    | Promote `sales` to a top-level namespace (sibling of `retail`), add the four backend custom routes (`POST /sales`, `POST /sales/{id}/void`, `POST /sales/{id}/share`, `GET /sales/{id}/receipt`). Drop `retail.sales` after migration window. |

**Other namespace-level inconsistencies found while auditing:**

| Frontend reference                | Backend canonical              | Action                                                                |
|-----------------------------------|--------------------------------|-----------------------------------------------------------------------|
| `API.accounting.vat.file()` / `.status()` (used in `accounting-vat.compiled.js`) | `accounting.vat.*` (route registered inline, not in `api-seeds.js`) | Move both registrations into `api-seeds.js` so the route registry is **single-file**. Today VAT is the only namespace where `defineRoute` lives outside the seed file — remove that exception. |
| `API.platform.tenants.suspend / .reactivate / .changePlan / .message / .impersonate` (registered inline in `platform-live.jsx`) | Same actions exist on backend | Move all five into `api-seeds.js` for parity; otherwise the registry isn't the SSoT we claim it is. |
| `window.useApi` / `window.useMutation` (global) | n/a — pure frontend convention | No change. Keep globals; React components rely on them.              |
| `API._call('GET', '/owner/subscription')` (raw call, no wrapper) | `subscriptions.current` or similar | Add a typed wrapper at cut-over: `API.subscriptions.current()`. |

**Decision rule for any future conflict:** **backend route name wins**. The integration team should not be holding two vocabularies in their head.

---

## B · Backend-vs-frontend status drift

This section is the **single most important warning** in the handoff package.

The frontend `BACKEND-MAPPING.md` and the status icons (✅ wired / ⚠ partial / ❓ unknown / ❌ missing) sprinkled through these handoff docs were written **at a snapshot in time**. Since then the backend has shipped **10 git tags through `v1.0-cutover-ready`**. The backend is materially ahead of where the FE handoff docs claim it is.

**Concretely, this means:**

- ✅/⚠/❓ icons in `BACKEND-MAPPING.md` and earlier README revisions **are not current truth.**
- An endpoint marked ❓ in those docs may now be live, audited, and OpenAPI-documented.
- An endpoint described as "FE-only / no backend yet" may have a real implementation that the FE simply hasn't migrated to consume.
- The mock router (`api-seeds.js`) is **not** a faithful mirror of the backend — it's a useful seed for offline dev, nothing more.

### Sources of truth, in priority order

| Rank | Source                                          | What it is                                                               | When to consult                                              |
|-----:|-------------------------------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------|
| 1    | **Laravel backend code**                        | Actual implementation. Routes in `routes/api.php`, controllers, FormRequests, Resources. | Always. Anything ambiguous — read the code.                  |
| 2    | **`docs/openapi/openapi.yaml`** (379 operations)| Auto-regenerated from backend; canonical wire contract.                  | When you need shape/schema/required fields without grep.     |
| 3    | **`docs/handoff/*.md`** (these files)           | Frontend contracts, patterns, decisions, vocabulary.                     | For consumer patterns, design tokens, boot sequence, naming decisions. **Never** for live status. |
| 4    | `BACKEND-MAPPING.md` and earlier wired-status notes | Historical FE perspective.                                          | Archaeology only — confirm against §1 and §2 before trusting. |

### Practical implication for the integration team

Do **not** start by asking "is this endpoint wired?" against the handoff docs. Start by checking `routes/api.php` and the OpenAPI bundle. If both confirm the endpoint exists and its shape, then come back to the handoff docs to learn how the FE consumes it (consumer file, hook pattern, idempotency strategy, error display).

This file (and the rest of the handoff set) is **frontend documentation**, not a backend status board. We've avoided putting status icons on individual endpoints precisely so this drift can't bite the integration team again.

---

## C · Cut-over priorities

Eight-stage rollout, in dependency order. Each stage assumes the previous stages are live and stable.

### Stage 1 — Auth + Session (blocker for everything)

- **Endpoints:** `POST /auth/sign-in`, `POST /auth/sign-out`, `POST /auth/refresh`, `GET /me`, `PATCH /me/branch`, `PATCH /me/locale`.
- **FE files to verify:** `front/api/api-session.js`, `front/api/api-fetch.js`, `front/common/topbar.js` (locale switcher), `front/common/sidebar.js` (branch switcher).
- **Done when:** signing in returns a real `{ token, user, tenant, permissions[], activeBranchId }`; refresh works on 401; `hasPermission(perm)` reflects backend-issued permissions, not the seed file.
- **Rollback:** flip `MOCK_MODE = true` for any session whose tenant isn't migrated yet.

### Stage 2 — Catalog + Products

- **Endpoints:** `/catalog/products`, `/catalog/categories`, `/catalog/brands`, plus per-product `GET /catalog/products/:id/stock`.
- **FE files:** `front/retail/retail-hooks.js` (the synchronous façade — switch its underlying calls from `API.retail.products.*` to `API.catalog.products.*`).
- **Done when:** the inventory list, product detail, and category/brand pickers populate from the backend; mutations write through and the audit log records them.
- **Caveat:** the FE is built around eventual consistency between catalogue and stock (stock updates lag sales by ≤ 1 minute today). Confirm backend behaviour before tightening the polling interval.

### Stage 3 — Sales + POS + Shifts

- **Endpoints:** `POST /sales` (capture), `POST /sales/{id}/void`, `POST /sales/{id}/share`, `GET /sales/{id}/receipt`, plus full CRUD on `/shifts`.
- **FE files:** `retail-pos*.compiled.js`, `retail-checkout*.compiled.js`, `retail-shift*.compiled.js`.
- **Critical contract:**
  - `sales.capture` MUST be idempotent on `Idempotency-Key` (the FE generates one per cart-submit).
  - `void` MUST short-circuit on already-voided sales (return `IDEMPOTENT_REPLAY`, not `409 CONFLICT`).
  - `receipt` returns ZATCA-compliant payload (QR-code, hash, PIH) — schema is in OpenAPI.
- **Done when:** a full POS loop (open shift → ring → take payment → print receipt → close shift) runs against real backend with no mock fallback.

### Stage 4 — Inventory

- **Endpoints:** `/inventory/purchase-orders`, `/inventory/receivings`, `/inventory/transfers`, `/inventory/stocktakes`, `/inventory/write-offs`, `/inventory/expiry-alerts`, `/inventory/price-changes`.
- **FE files:** `retail-purchasing*.compiled.js`, `retail-stocktake*.compiled.js`, `retail-expiry*.compiled.js`, `retail-write-offs*.compiled.js`.
- **Done when:** a PO can be created → received → variance reconciled → cost feeds into Stage 5's GL.
- **Caveat:** inventory writes generate accounting events. Stage 5 must be ready *before* this is fully cut over, or the GL will fall behind.

### Stage 5 — Accounting (the big one)

Sub-stages, all under the canonical `accounting` namespace:

1. **TB** — Trial Balance read endpoints (`/accounting/reports/trial-balance`).
2. **P&L** — Profit & Loss (`/accounting/reports/profit-loss`).
3. **BS** — Balance Sheet (`/accounting/reports/balance-sheet`).
4. **Cashflow** — Cashflow statement (`/accounting/reports/cashflow`).
5. **AR/AP** — Receivables/Payables (`/accounting/customers`, `/accounting/vendors`, `/accounting/invoices`, `/accounting/bills`).
6. **CoA** — Chart of Accounts (`/accounting/coa`).
7. **Bank** — Bank reconciliation (`/accounting/bank-txns`, reconciliation actions).
8. **VAT** — VAT periods + return filing (`/accounting/vat-periods`, `POST /accounting/vat-returns/{id}/file`, `GET /accounting/vat-returns/{id}/submission-status`).
9. **ZATCA** — invoice clearance integration (sub-routes under `/accounting/zatca/*`).

- **FE files:** `accounting-*.compiled.js` (one file per sub-stage roughly).
- **Done when:** every retail/inventory/payroll write produces a ledger entry; reports balance; VAT return can be filed end-to-end against ZATCA sandbox.

### Stage 6 — Workflows §1.8 (highest-value upgrade)

The §1.8 workflow engine (approval chains, multi-step forms, escalations) is the highest-leverage piece because it unlocks: payroll approval, leave approval, expense approval, plan-change approval, dispute resolution, ticket lifecycle.

- **Endpoints:** `/workflows/*` (definitions, instances, transitions, audit trail).
- **FE files:** Owner approvals, HR leave/payroll, ticket close, dispute resolve all consume this.
- **Done when:** a single canonical workflow engine drives every multi-step approval in the product, with consistent UI and audit.

### Stage 7 — Stage-specific modules

Now that the foundation is live, ship the vertical modules:

- **HR** — full hire-to-retire, attendance, payroll, EOSB, GOSI, MOL, WPS file.
- **Pay (payments)** — terminal fleet, settlements, payouts, disputes, SoftPOS device management.
- **Dine (restaurant)** — tables, KDS, reservations, delivery, recipes.
- **E-com** — webstore catalogue, orders, fulfillment.
- **Loyalty** — programs, tiers, redemptions.

These are large but **mostly self-contained** by this stage. Ship them in any order based on customer demand.

### Stage 8 — Platform admin

- **Endpoints:** `/platform/dashboard`, `/platform/tenants/*`, `/platform/health`, `/platform/plans`, `/platform/services`, `/platform/subscriptions`, `/platform/platformInvoices`.
- **FE files:** `front/platform/*.compiled.js`, `front/platform/platform-live.jsx`.
- **Why last:** Super Admin observes everything else. It needs the underlying modules' real APIs in place for tenant-level views to be meaningful.
- **Done when:** ops can suspend/reactivate/changePlan/message/impersonate against real tenants, with a real audit trail.

---

## D · Open questions (resolved)

These are the open questions I flagged across MODULE-MAP, DESIGN-SYSTEM, and API-USAGE-MAP. Each is now decided.

### D.1 — Split HR out of `front/owner/`?

**Decision: YES — split into `front/hr/`.**

**Rationale:**
- The backend already treats HR as a first-class module (`/hr/*` route group, separate controllers, separate Eloquent namespace).
- `front/owner/` currently mixes two distinct surfaces — owner dashboard/approvals (small, ~5 files) and HR (~24 files: roster, leave, payroll, attendance, contracts, goals, kudos, expenses, loans, assets, courses, policies, candidates).
- Co-location made sense in the prototype era because HR mounted into the owner sidebar. With HR getting its own `/hr` route group on the backend, the FE folder layout should follow.

**Migration path:**
1. Create `front/hr/` directory.
2. Move all `hr-*.compiled.js` files (`hr-leave-v2`, `hr-payroll-v2`, `hr-roster-v2`, etc.) verbatim — no code changes, just `git mv`.
3. Update `index.html` boot order: HR scripts come *after* owner scripts (HR depends on `OwnerConsole` shell mounting).
4. Update the seed-file resource keys: rename `owner.staff` → `hr.staff`, `owner.leaveRequests` → `hr.leaveRequests`, etc. Match the backend's `/hr/*` route group exactly.
5. Add a 1-line shim per resource (`window.API.owner.staff = window.API.hr.staff`) for the migration window. Remove in v1.1.

**Cost:** ~half a day. Worth doing **before** Stage 7 cut-over so the HR module ships under its real name.

### D.2 — Deprecate legacy `common/api.js` + `common/api-seeds.js`?

**Decision: NO — keep both, repurpose them.**

**Rationale:**
- `common/api.js` is **the integration seam**. It contains `_call`, `defineResource`, `defineRoute`, the envelope handling, and the mock-vs-real switch. None of that is legacy; all of it is load-bearing.
- `common/api-seeds.js` is the **registry** — the single declarative list of every namespace/resource/route the FE knows about. Deleting it would scatter `defineResource` calls across 140 files.
- What *is* legacy: ad-hoc `defineRoute` calls living *outside* `api-seeds.js` (VAT routes in `accounting-vat.compiled.js`, platform mutations in `platform-live.jsx`). Those should move into `api-seeds.js` so it remains the SSoT (see §A above).

**Action:** rename `api-seeds.js` → `api-registry.js` to better reflect its post-cut-over role (it stops being "seeds" once the mock is mostly off). Optional but improves the mental model.

### D.3 — Density: global CSS custom property on `<html>`?

**Decision: YES — promote density to a global.**

**Implementation:**
```css
:root { --density: 1.00; --density-sm: 1.00; }
[data-density="comfy"]   { --density: 1.10; --density-sm: 1.05; }
[data-density="compact"] { --density: 0.92; --density-sm: 0.96; }
```
- Set `<html data-density="comfy">` from the App-level toggle.
- Components opt in by multiplying spacing/sizing tokens by `var(--density-sm)` (line-height, button padding) or `var(--density)` (gap, max-width, card padding).
- Components currently honouring density via inline style continue to work — the CSS approach is **additive**, not a rewrite.

**Migration:** ship as a follow-up after cut-over, not a blocker. Track as a v1.1 ticket. Until then, density behaves as it does today (App-level toggle, opportunistic per-screen).

### D.4 — AI panel inverted styling: bug or brand?

**Decision: BRAND — preserve.**

**Rationale:**
- The AI panel is intentionally always navy-on-navy (`aiBg`/`aiInk`/`aiAccent` tokens) regardless of light/dark mode — it reads as a distinct surface, like a dock or a heads-up display.
- This is consistent with the design language ("AI is its own context, not a panel of the page").
- Tokens are already isolated under `ai*` keys in `front/common/tokens.js`; no change needed.

**Action:** none. Document in DESIGN-SYSTEM (already done) and in any future visual-QA pass so reviewers don't flag it as a contrast bug.

### D.5 — AI panel real-backend wiring?

**Decision: MOCK-ONLY in v1.0.**

**Rationale:**
- The backend has zero streaming/SSE endpoints today. The FE's AI panel is request/response (`API.shared.aiThreads.create()`, `.list()`) and the mock returns canned responses.
- Wiring a real LLM through request/response is fine for v1.0 (latency hidden behind a spinner) but a much better UX is SSE.
- v1.1 should consider SSE if AI features move to production.

**Action:**
- Keep the AI panel wired to `API.shared.aiThreads.*` so the surface area doesn't change.
- v1.0 release notes: "AI assistant is a tech preview; responses are simulated."
- v1.1 backlog: spec `GET /shared/ai-threads/{id}/stream` (SSE) and add `API.shared.aiThreads.stream(threadId, onChunk)` to the consumer hooks.

### D.6 — `platform.health`: wired or missing?

**RESOLVED — confirmed wired.** `Route::get('platform/health', PlatformHealthOverviewController::class)` exists in the backend and was confirmed live in Stage 1.F-1. The ⚠ in `API-USAGE-MAP.md §4.7` is dropped — `API.platform.health.list()` is real.

**Action:** add a `D('platform.health', …)` line to `api-seeds.js` so the resource registers explicitly (currently it works because `platform-live.jsx` calls through `_call` directly, but the mock layer doesn't have a fixture for it — meaning offline dev sees an empty health panel).

---

## E · Icon library — full glyph catalogue

Audited from `front/common/icons.compiled.js` end-to-end. **73 glyphs**, all defined as path/group fragments inside a single `IconPaths` object and rendered through the `<Icon name="…" />` component (see DESIGN-SYSTEM §6).

### Catalogue (alphabetical)

| Glyph         | Typical use                                            |
|---------------|--------------------------------------------------------|
| `admin`       | Super Admin / platform-side actions                    |
| `alert`       | Warnings, attention                                    |
| `archive`     | Archived items, historical lists                       |
| `arrow`       | Generic directional arrow (mirror in RTL)              |
| `bag`         | Cart, retail bag, customer order                       |
| `bank`        | Banking, settlements, payouts                          |
| `beaker`      | Lab/test, beta features                                |
| `bell`        | Notifications, alerts inbox                            |
| `bike`        | Delivery rider                                         |
| `box`         | Product, package, inventory unit                       |
| `branch`      | Branch / location                                      |
| `calendar`    | Date pickers, schedules                                |
| `camera`      | Photo capture, scan                                    |
| `card`        | Payment card, credit/debit                             |
| `chair`       | Restaurant table seat / chair                          |
| `chart`       | BI, analytics                                          |
| `check`       | Confirmation, success                                  |
| `chev`        | Generic chevron (compact form)                         |
| `chevron`     | Standard chevron — disclosure, dropdown                |
| `clipboard`   | Copy, list, form                                       |
| `close`       | Dismiss, close modal                                   |
| `cog`         | Settings                                               |
| `coin`        | Currency, balance                                      |
| `copy`        | Duplicate, copy-to-clipboard                           |
| `crown`       | Owner, premium, admin role                             |
| `device`      | Generic device / terminal                              |
| `doc`         | Document, file                                         |
| `dot`         | Status dot, bullet                                     |
| `dots`        | Overflow menu (… kebab)                                |
| `download`    | Download (listed twice — likely a stylistic variant; consolidate at cut-over) |
| `drawer`      | Cash drawer (POS)                                      |
| `edit`        | Edit / pencil                                          |
| `envelope`    | Email, message                                         |
| `filter`      | Filter list                                            |
| `flag`        | Flag for review, mark                                  |
| `flame`       | Hot / popular / urgent                                 |
| `fork`        | Restaurant / food                                      |
| `globe`       | Web, language, internationalisation                    |
| `grid`        | Dashboard, grid view                                   |
| `heart`       | Favourite, loyalty                                     |
| `info`        | Information / help tooltip                             |
| `ledger`      | Accounting ledger                                      |
| `link`        | External link / chain                                  |
| `lock`        | Locked, secured                                        |
| `logout`      | Sign out                                               |
| `mail`        | Mail (separate from `envelope` — visual variant)       |
| `menu`        | Hamburger / mobile nav                                 |
| `pause`       | Pause action                                           |
| `phone`       | Phone, contact                                         |
| `play`        | Play / start                                           |
| `plus`        | Add, create                                            |
| `pos`         | Point-of-sale terminal                                 |
| `printer`     | Print receipt                                          |
| `receipt`     | Receipt / invoice                                      |
| `repeat`      | Recurring, loop                                        |
| `search`      | Search                                                 |
| `server`      | Backend / infra                                        |
| `shield`      | Security, permissions                                  |
| `spark`       | AI, magic, suggestion                                  |
| `split`       | Split bill / split payment                             |
| `star`        | Rating, favourite                                      |
| `sync`        | Refresh / synchronise                                  |
| `tablet`      | Tablet device (Dine FOH)                               |
| `tag`         | Tag / label / price                                    |
| `trash`       | Delete                                                 |
| `truck`       | Delivery / shipment                                    |
| `upload`      | Upload                                                 |
| `user`        | Single user                                            |
| `users`       | Group / team                                           |
| `wand`        | Magic wand — AI, automation                            |
| `warn`        | Warning (alternate to `alert`)                         |
| `x`           | Close (alternate to `close`)                           |

### Findings & cleanup recommendations

1. **`download` is registered twice.** The second definition shadows the first. Consolidate to a single `download` glyph at cut-over — pick the visually correct one and delete the other.
2. **Three near-duplicate pairs:** `chev`/`chevron`, `close`/`x`, `alert`/`warn`, `envelope`/`mail`. Each pair has a stylistic difference (size, weight, fill) and is referenced by different screens. **Don't dedupe** — keep both, but document which is the "small / inline" form (`chev`, `x`) and which is the "standard / card-header" form (`chevron`, `close`).
3. **No icon for: `barcode`, `qr`, `currency-sar`, `signature`, `attachment`, `clock`, `gear-with-badge`.** Several screens fall back to text or emoji where these would be ideal. Plan an icon-additions pass for v1.1.
4. **All glyphs use a 20×20 viewBox with 2-unit padding.** Consistency is good — keep the rule for any new glyphs.
5. **No icon is currently mirrored for RTL.** The `<Icon>` component supports it (DESIGN-SYSTEM §6) but no explicit `mirror: true` flags are set in the IconPaths object today. Audit `arrow`, `chev`, `chevron`, `bike`, `truck` — these likely should mirror in Arabic.

---

## F · Pointer index for the integration team

**Start here, in this order, on Day 1:**

1. `routes/api.php` (backend) — see what's actually routable.
2. `docs/openapi/openapi.yaml` (backend) — see the full schema.
3. `docs/handoff/MODULE-MAP.md` — file/module geography.
4. `docs/handoff/API-USAGE-MAP.md` — wire contract + consumer patterns.
5. `docs/handoff/INTEGRATION-NOTES.md` — this file. Naming, drift, priorities, decisions.
6. `front/common/api.js` + `front/common/api-seeds.js` — the integration seam.

**Then, per stage of the cut-over (§C above):**

- `docs/handoff/SCREENS-INVENTORY.md` — find the consumer for each endpoint.
- `docs/handoff/USER-FLOWS.md` — see how endpoints chain end-to-end.
- `docs/handoff/DESIGN-SYSTEM.md` — when a screen needs visual fidelity verification.

---

**End of INTEGRATION-NOTES.md.**
