Files
baya-monorepo/dev/phases/frontend/frontend-phase-0.md
T
2026-06-28 21:59:59 +03:30

167 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 f1f15 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.