# Experience Frontend Architecture

Torbat Pages (`frontend/modules/experience/`) mirrors the Delivery module layout.

## Layers

```
Browser → /api/experience BFF → experience-service:8008
```

- **BFF:** `frontend/app/api/experience/[...path]/route.ts`
- **API client:** `services/experience-api.ts` — normalizeList for array/paginated responses; PATCH includes `version` on updates
- **Soft delete:** `POST /api/v1/{resource}/{id}/delete` where backend uses that convention

## Module structure

| Path | Role |
| --- | --- |
| `components/` | PortalShell, ListCrudPage factory, PhaseGate, Breadcrumbs, WorkspaceSwitcher, createPortalLayout |
| `constants/` | portals.ts (nav groups), permissions.ts, phaseRegistry.ts |
| `design-system/` | tokens, TablePage, StatusChip, StatGrid, EmptyState, Skeleton |
| `features/` | Screen implementations |
| `hooks/` | useExperienceCapabilities, useExperiencePermissions, useExperienceWorkspace |
| `pages/shared.tsx` | Loaders, errors, CSV export |
| `types/` | API response types |

## Auth & tenant

- `AuthGuard` + `useMe` tenant gate (same as Delivery)
- `X-Tenant-ID` on all authenticated API calls
- Workspace switcher persists `experience.selectedWorkspaceId` in localStorage

## Builder ownership (ADR-002)

Visual builder UX is owned by Experience FE. `page_builder` capability flag is **reserved** — builder is not blocked when flag is false.

## publish_id (FE-11.5)

Presentation only: provisional `publish_id = resource.id` until FE-11.6+ registry. Labelled clearly in UI.

## Validation

```bash
npm run validate:experience
```
