# Frontend Phase 0 — Foundations: app shells, design system & the data/contract patterns

> **Mission:** turn the inherited starter into a clean Balinyaar foundation for the three actor
> experiences (family/customer, nurse, admin). Remove the demo leftovers, build the **app shells** and
> route groups each actor needs, and lock in the **patterns** every later frontend phase will follow:
> how a `services/{domain}` talks to the API, how TanStack Query caches it, how types come from the
> published contract, and where shareable components live. No real feature data yet (no backend
> dependency) — this phase makes f1–f15 fast, consistent, and re-render-cheap.
>
> **Track:** frontend · **Depends on:** nothing (`frontend-phase-0`, no backend phase required) ·
> **Unlocks:** every frontend phase
> **Before you start, read [`../_shared/agent-operating-rules.md`](../_shared/agent-operating-rules.md).** It is not optional.

---

## 1. Context — where this sits

The client (`client/`, **Next.js 16 App Router + React 19 + MUI v9 + next-intl**, `fa` default & RTL)
already ships a full app shell and an `App*` component library — you **keep and build on** these and
**remove** the demo bits.

**What already exists (do not rebuild) — confirmed in the codebase:**
- Root layout `src/app/[locale]/layout.tsx` (renders `<html lang dir>`, providers: NextIntl → Auth →
  Theme → Query → Notistack), `(private-routes)`/`(public-routes)` groups, the `TopBarAndSideBarLayout`
  engine + `TopBar`/`SideBar`/`BottomBar`.
- Theme system (brand tokens **teal `#1d4a40`**, **terracotta `#d98c6a`**, cream in `theme/colors.ts` +
  `tokens.css`; `APP_THEME_LTR/RTL`, dark mode), i18n (`routing.ts`, `request.ts`), the cookie manager,
  `clientFetch`/`serverFetch` + `ApiError`, TanStack Query (`makeQueryClient`/`QueryProvider`), the toast
  bridge, `AuthContext`, the middleware auth gate.
- The `App*` library: `AppButton`, `AppIconButton`, `AppAlert`, `AppIcon`, `AppImage`, `AppLink`,
  `AppLoading` (+ `ErrorBoundary`, `UserInfo`); the `auth` service (`useLogin`/`useLogout`/`useCurrentUser`).

**What is demo scaffolding you will remove in this phase:**
- The `toastDemo` i18n namespace (both `en.json`/`fa.json`) and the placeholder `HomePage`
  (`<Typography>Balin yaar</Typography>` with its unused `t`).
- The unregistered dead icons `AppIcon/icons/CurrencyIcon.tsx` and `YellowPlanIcon.tsx`.
- Fix the small drift noted in the audit: `AppLoading` missing from the `@/components` barrel export;
  `BottomBar` reading global `location` instead of `usePathname`.

> **Auth note:** login is currently **username/password**. It becomes **phone-OTP** in **f1-b2** — don't
> wire login screens here; this phase only prepares the shells and patterns.

## 2. Required reading (do this first)

- [`../_shared/agent-operating-rules.md`](../_shared/agent-operating-rules.md) and
  [`../_shared/frontend-conventions-checklist.md`](../_shared/frontend-conventions-checklist.md).
- [`client/CLAUDE.md`](../../../client/CLAUDE.md) in full — the engineering contract (RSC boundary,
  layouts, i18n, theme, cookies, fetch services, anti-patterns). Note the doc/code drift the audit found
  (e.g. a `ColorSchemeScript` is referenced but doesn't exist) — trust the code, and fix the doc if you
  touch that area.
- **Invoke the `frontend-designer` skill** — it is the design/brand contract (palette, tokens,
  typography, the `App*` library, layout shells, the hard UI rules). All visual work goes through it.
- [`product/wireframes/index.html`](../../../product/wireframes/index.html) — the visual baseline:
  mobile-first RTL app, deep-green brand, the **5-tab bottom nav** for the customer app
  (خانه/Home · رزروها/Bookings · بیماران/Patients · کیف‌پول/Wallet · پروفایل/Profile), and the nurse-only
  screens. This phase builds the *shells* those screens will live in.
- [`../../contracts/README.md`](../../contracts/README.md) +
  [`conventions/api-conventions.md`](../../contracts/conventions/api-conventions.md) +
  [`money-and-types.md`](../../contracts/conventions/money-and-types.md) — how you'll type and format
  server data (envelope, IRR-as-string + Toman display, enums-as-codes, UTC + Shamsi display).
- The existing `src/services/auth/*` — the exact pattern (`types.ts`/`keys.ts`/`apis/clientApi.ts`/
  `hooks/use*.ts`/`index.ts`) every new domain service copies.

## 3. Scope — build this

### 3.1 Clean up the demo scaffolding
Remove the `toastDemo` namespace, the placeholder home page content, the two dead icons; fix the
`AppLoading` barrel export and the `BottomBar` `usePathname` bug. Keep everything else. `npm run check`
stays green throughout.

### 3.2 The three actor app shells + routing
Balinyaar has three audiences with different chrome. Establish them now (empty/placeholder content is
fine — they fill up in later phases):
- **Customer (family) app** — mobile-first shell with the **bottom tab nav** (Home/Bookings/Patients/
  Wallet/Profile) per the wireframe; this is the primary experience.
- **Nurse app** — its own shell (the wireframe's "نمای پرستار" screens: verification, dashboard, EVV).
- **Admin/backoffice** — a desktop-oriented shell (sidebar nav) for the ops console (f15).

Decide the routing that expresses these cleanly within the existing `[locale]` + route-group structure
(e.g. role-scoped route groups/segments under `(private-routes)`), **without** adding any layout above
`[locale]` and **without** breaking the server/client boundary. Drive nav by role from `AuthContext`
(roles arrive in f1-b2 — design the shell to read a role and render the right chrome; default gracefully
until roles exist). Build a **shared bottom-nav** and **shared sidebar-nav** component at the right level
in `src/layout/` / `src/components/`. Update the **Project Structure** tree in `client/CLAUDE.md` for any
new route group/folder.

### 3.3 The `services/{domain}` + Query caching pattern (the reference implementation)
Codify the data pattern every later phase copies, using the `auth` service as the template and the
checklist's caching rules:
- A `keys.ts` query-key factory per domain; deliberate `staleTime`/`gcTime`; **mutations invalidate or
  `setQueryData`** so data already in cache is never needlessly refetched.
- `apis/clientApi.ts` (+ `serverApi.ts` only when an RSC needs it) wrapping `clientFetch`/`serverFetch`;
  **one hook per file**.
- A documented way to derive `types.ts` from the published contract (`dev/contracts/`) — and, when a
  backend phase isn't ready, a **mock `clientApi`** behind the same seam plus a row in your report (so
  it's swapped cleanly once the real endpoint lands). Provide a tiny example domain (or thoroughly
  document the `auth` one) so f1 starts by copying, not inventing.
- A small **money/format util** (`formatIrrToToman`, integer-safe parse of IRR strings, Shamsi date
  display) in `src/utils/` per the money-and-types contract — used wherever prices/dates render.

### 3.4 Shared composite components (built once, reused everywhere)
Build the cross-cutting composite components the wireframe implies, at the shared level (`src/components/…`),
each with a co-located `*.test.tsx`, each composed from MUI/`App*` primitives (never re-implementing a
root primitive): an **OTP code input**, a **phone-number field** (Iranian format, RTL-safe), a **stepper/
progress header** (used by onboarding + verification), a **status chip** (verified/pending/…); a
**nurse/result card** and a **price-breakdown** can be stubbed here or deferred to their phases — your
call, but if you build them, build them shared. Keep page-only composition in pages.

### 3.5 i18n namespaces baseline
Establish the namespace conventions for the feature areas to come (e.g. `auth`, `onboarding`,
`verification`, `search`, `booking`, `payment`, `bnpl`, `reviews`, `notifications`, `admin`, `common`,
`nav`) — seed `common`/`nav` with the shell strings you add, in **both** `en.json` and `fa.json`, in
sync. RTL-first.

## 4. Mocks & seams in this phase

No backend dependency. Where you demonstrate the data pattern without a live endpoint, use a **mock
`clientApi`** behind the `services/{domain}` seam and note it in your report — this is the template f1+
follow until their backend phase is merged.

## 5. Critical rules you must not get wrong

- **Never add a layout above `[locale]`** and never break the RSC/client boundary (the audit shows the
  current setup is load-bearing — see `client/CLAUDE.md`).
- **Design RTL-first**, `fa` default; every string in both locale files.
- **Colours from tokens**, MUI v9 API only, pre-built themes only.
- **Caching is a feature:** set `queryKey`/`staleTime` deliberately and invalidate on mutation — the
  whole point of this phase is that later phases don't over-fetch or over-render.
- **MUI primitives stay MUI;** shareable composites live shared, not in a page.
- Keep `npm run check` green and translations in sync at every step.

## 6. Definition of Done

The shared [definition-of-done.md](../_shared/definition-of-done.md), plus:
- [ ] Demo scaffolding removed; the two barrel/`BottomBar` bugs fixed; `npm run check` green;
      `npm run test:ci` green for the shared components you add.
- [ ] The three actor shells exist and render with role-aware nav (degrading gracefully before roles
      exist); no layout added above `[locale]`.
- [ ] The `services/{domain}` + Query caching pattern is implemented and documented as the reference;
      the money/format util exists.
- [ ] The shared composite components added each have a co-located test.
- [ ] `client/CLAUDE.md` *Project Structure* updated for new route groups/folders; any doc drift you
      touched is corrected.

## 7. How to test (what a human can verify after this phase)

- `npm run dev` → the app boots; visiting the customer area shows the mobile shell with the 5-tab bottom
  nav; the nurse and admin areas show their shells; switching locale flips `dir`/strings correctly; dark
  mode still works.
- `npm run check` and `npm run test:ci` pass; the new shared components render and their interactions
  fire callbacks in tests.
- The reference `services/{domain}` (or the documented `auth` one) shows a query caching + a mutation
  invalidating it in React Query Devtools.

## 8. Hand off & document (close the phase)

- **Docs:** update `client/CLAUDE.md` *Project Structure* (route groups, new shared components, the
  services pattern note); fix any drift you touched.
- **Contracts:** none produced (frontend consumes). If the b0 swagger snapshot exists, wire the
  types-from-contract step against it; otherwise document the intended step. File any envelope/format
  question in `shared-working-context/frontend/requests/for-backend.md`.
- **Handoff & report:** append to `shared-working-context/frontend/STATUS.md`; write
  `reports/frontend-phase-0-report.md` (shells built, the reference data pattern, which composites are
  shared, what's mocked client-side and how f1 swaps it).
- **Memory:** save a `project` memory note for the actor-shell/routing decision and the data pattern,
  with a `MEMORY.md` pointer.
