# 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 ``, 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` (`Balin yaar` 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.