cleanup phases 6

This commit is contained in:
hamid
2026-08-02 18:48:32 +03:30
parent e2db97392a
commit 51e86a1e5f
239 changed files with 118 additions and 70 deletions
@@ -0,0 +1,97 @@
# Frontend Phase 0 — Foundations: app shells, design system & data/contract patterns — Report (2026-07-02)
## What was built
**Cleanup (3.1)**
- Removed the `toastDemo` i18n namespace (both locales) and the placeholder home page.
- Deleted the two dead icons (`AppIcon/icons/CurrencyIcon.tsx`, `YellowPlanIcon.tsx`).
- Fixed `BottomBar` to read the route via `usePathname()` (was the global `location`) and made it
locale-aware (highlights the active tab, pushes locale-prefixed routes).
- Audit note "AppLoading missing from the `@/components` barrel" — verified it is already exported
(`components/common/index.tsx`); no change needed.
**Actor shells + routing (3.2)** — three role-scoped experiences under `(private-routes)`, no layout
added above `[locale]`:
- **Customer (family)** — `(customer)` route group (no URL segment) at `/`, `/bookings`, `/patients`,
`/wallet`, `/profile`; `CustomerLayout` = slim TopBar + the 5-tab `BottomBar` from the wireframe.
- **Nurse** — `/nurse`, `/nurse/verification`, `/nurse/visits`; `NurseLayout` on the shared
`TopBarAndSideBarLayout` engine.
- **Admin** — `/admin`, `/admin/users`, `/admin/notifications`; `AdminLayout`, persistent desktop sidebar.
- Role model: `constants/roles.ts` (`AppRole`), optional `User.roles`, and `useActorRole()` (defaults to
`customer` until the server seeds roles in f1-b2). Nav is built per shell from `useTranslations('nav')`.
**Data pattern + utils (3.3)**
- Reference domain `services/patients/` mirroring `auth`: `types.ts` (+ the `PatientsApi` seam interface),
`keys.ts` (hierarchical factory), `constants.ts` (mock toggle + staleTime), `apis/` (`clientApi` real,
`mockApi` in-memory, `index` selects by config), `hooks/` (`usePatients` with `staleTime`,
`useAddPatient` invalidates the list), barrel exporting hooks only.
- Shared wire types `lib/api/types.ts`: `ApiEnvelope<T>` + `unwrap()`, `Paginated<T>`, `PageParams`.
- Money/date utils in `@/utils`: `parseIrr`/`rialToToman`/`formatIrr`/`formatIrrToToman` (integer-safe
BigInt) and `formatShamsiDate`/`formatShamsiDateTime` (Intl Persian calendar — no date lib). Plus
`toEnglishDigits`/`digitsOnly` in `utils/text.ts`.
**Shared composites (3.4)** — each in `src/components/<Name>/` with a co-located `.test.tsx`, composed
from MUI/`App*` primitives, i18n-agnostic (labels passed by caller):
- `OtpInput` (auto-advance, backspace-to-previous, paste distribution, digit-normalizing, LTR-in-RTL),
- `PhoneNumberField` (Iranian mobile, normalizes Persian/Arabic digits, caps at 11, `isIranianMobile`),
- `StepperHeader` (MUI Stepper, RTL-aware), `StatusChip` (verified/pending/rejected/… off `--bal-*` tokens),
- `PlaceholderScreen` (empty-state used by every not-yet-built screen).
- Nurse/result card and price-breakdown were **deferred** to their feature phases (per the phase's "your call").
**i18n (3.5)** — seeded `nav`, `common`, `shell`, `patients` in both `en.json`/`fa.json` (in sync,
RTL-first). Documented the future namespace conventions in `client/CLAUDE.md`.
## What is now testable (and exactly how)
1. `cd client && npm run dev` → open `http://localhost:3000` (redirects to `/fa`).
- Customer shell: mobile 5-tab bottom nav (خانه/رزروها/بیماران/کیف‌پول/پروفایل); tapping switches routes
and highlights the active tab.
- Nurse shell: `/fa/nurse` — TopBar + sidebar (داشبورد/احراز هویت/ویزیت‌ها).
- Admin shell: `/fa/admin` — persistent sidebar on desktop (نمای کلی/کاربران/اعلان‌ها).
- Switch locale to `/en``dir` flips to LTR and all strings translate; dark-mode toggle still works.
2. **Reference data pattern:** `/fa/patients` shows the mocked list (~400 ms latency), an add form
(name + gender). Submitting adds the patient and the list updates **without a refetch** — open React
Query Devtools to watch `['patients','list',…]` cache + the invalidation on mutation success.
3. `npm run check` (type + lint) and `npm run test:ci` (72 tests, 12 suites) both pass. `npm run build`
passes when `NEXT_PUBLIC_API_URL` is set (see Follow-ups).
## What is mocked / waiting on a real service
- **Patients domain — client-side mock.** `services/patients/apis/mockApi.ts` (`patientsMockApi`)
implements the `PatientsApi` interface (`services/patients/types.ts`) in memory. Selected by
`USE_PATIENTS_MOCK = true` in `services/patients/constants.ts`. The real `clientApi.ts` is written
against `/patients` (GET list + POST create) and already unwraps the `ApiEnvelope`. **To make real:**
publish the `patients` contract + endpoints, set `USE_PATIENTS_MOCK = false` — no hook/component change.
(This is a frontend client-side mock, not a backend DI seam, so it is recorded here rather than in the
backend-owned `mocks-registry.md`.)
- This is the template f1+ copy for any domain whose backend phase hasn't merged.
## Contracts
- **Produced:** none (frontend consumes).
- **Consumed:** `dev/contracts/conventions/{api-conventions,money-and-types}.md` and the b0
`openapi/swagger.v1.json` (only `ping` endpoints exist yet). Types-from-contract step is wired for the
`patients` reference (shapes mirror the intended wire; `ApiEnvelope`/`Paginated` in `lib/api/types.ts`).
- **Request filed:** `frontend/requests/for-backend.md` REQ-001 (confirm envelope unwrapping, wire casing,
pagination payload shape).
## Docs updated
- `client/CLAUDE.md`: *Project Structure* tree (new route groups, actor layouts, shared composites,
`services/patients`, `lib/api/types.ts`, `constants/roles.ts`, money/date utils); i18n namespaces +
future-namespace conventions; a new *services/{domain} reference pattern* subsection (caching, mock
seam, envelope, money/dates). Corrected the `ColorSchemeScript` doc drift in the two structure lines
that named it (it is neither exported from `@/theme` nor rendered).
## Follow-ups for later phases
- **Envelope unwrapping (REQ-001):** `clientFetch`/`serverFetch` currently return the raw body, so domain
`clientApi`s call `unwrap()`. If the team prefers central unwrapping, that touches the auth plumbing —
coordinate before changing. Wire casing observed is **camelCase**, not the snake_case api-conventions
implies; confirm and update the convention doc.
- **Role guards:** shells read `useActorRole()` but do not yet *guard* cross-actor access (any authed user
can open `/nurse`, `/admin`). Add real guards once roles land in **f1-b2**.
- **Login is username/password** today; phone-OTP arrives in **f1-b2** (use `OtpInput`/`PhoneNumberField`).
- **`npm run build` needs `NEXT_PUBLIC_API_URL`:** `@/config` uses `envRequired`, which throws at import.
Dev works via the committed `.env.development`; a production build must supply the var (as it always would
once any page imports the fetch layer). Not a code defect — an env expectation to note in CI.