17a82832ab
Replace the username/password stub with Balinyaar's real credential (phone-OTP) and add the role router every authenticated screen sits behind. - services/auth rewritten for OTP over the b2 contract: types/keys/constants, clientApi+mockApi behind a config'd seam, hooks (useRequestOtp/useVerifyOtp/ useMe/useRefresh/useLogout/useSelectRole/useSessionRoleSync). Stub removed. - A1/A2 customer login + B1/B2 nurse switch as one OTP flow at /login (PhoneStep/OtpStep: auto-verify, resend countdown, wrong/expired/lockout states). - Role router: pure resolveRoleDestination + RoleRouter -> family / nurse / admin / select-role, with a splash while /me loads (no wrong-shell flash). - SelectRole first-use screen at /select-role. - Widened AuthState (roles via SessionUser), hydrated from /me by useSessionRoleSync. - Fetch-layer silent token refresh (single-flight + one retry) + shared persistAuthTokens/clearAuthTokens; useRefresh as the on-demand path. - auth i18n namespace in both locales; tests for routing branches, countdown, OtpStep state machine, RoleRouter branches; fixed jest @/ -> src alias. - Docs: client/CLAUDE.md, frontend STATUS/report, for-backend REQ-002..004. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
48 lines
3.4 KiB
Markdown
48 lines
3.4 KiB
Markdown
# Frontend status log (append-only)
|
|
|
|
One block per completed frontend phase. Newest at the top. Frontend lane writes here; backend reads
|
|
for awareness.
|
|
|
|
<!-- TEMPLATE — copy for each phase
|
|
## frontend-phase-N-bM — <Title> — <YYYY-MM-DD>
|
|
- **Shipped:** <screens/flows/services/hooks/components in one or two lines>
|
|
- **Consumes:** dev/contracts/domains/<domain>.md (backend phase bM)
|
|
- **Mocked client-side:** <which services are mocked pending which backend phase>
|
|
- **Gate:** npm run check green / tests green
|
|
- **Requests filed:** frontend/requests/for-backend.md (yes/no)
|
|
-->
|
|
|
|
## frontend-phase-1-b2 — Auth: phone-OTP login & role routing — 2026-07-02
|
|
- **Shipped:** `services/auth` rewritten for phone-OTP (types/keys/apis[client+mock+seam]/hooks:
|
|
`useRequestOtp`/`useVerifyOtp`/`useMe`/`useRefresh`/`useLogout`/`useSelectRole`/`useSessionRoleSync`) —
|
|
the username/password stub is gone; A1/A2 customer login + B1/B2 nurse switch (one OTP flow parameterised
|
|
by intended role) at `/login`; the **role router** (`RoleRouter` + pure `resolveRoleDestination`) →
|
|
customer→family, nurse→nurse app, no-role→`/select-role`, admin→admin console (splash while `/me` loads,
|
|
no wrong-shell flash); `SelectRole` screen at `/select-role`; **silent token refresh** in the fetch layer
|
|
(single-flight `attemptTokenRefresh`, one retry on 401); widened `AuthState` (roles via `SessionUser`,
|
|
hydrated from `/me` by `useSessionRoleSync` in the private layout); `auth` i18n namespace + `common.brand*`
|
|
in both locales.
|
|
- **Consumes:** dev/contracts/domains/identity-auth.md + openapi/swagger.v1.json (backend-phase-2). Wire is
|
|
**camelCase**; routes `api/v1/auth/{request_otp,verify_otp,refresh,logout}`, `api/v1/me`, `api/v1/me/select_role`.
|
|
- **Mocked client-side:** `services/auth` via `authMockApi` behind `USE_AUTH_MOCK` (**default false** — b2 is
|
|
live; flip true for offline dev, dev code `123456`). See mocks-registry.
|
|
- **Gate:** npm run check green · npm run test:ci green (95 tests, +23) · npm run build green with
|
|
NEXT_PUBLIC_API_URL set. Fixed the jest `@/`→`src` alias (was `<rootDir>/$1`).
|
|
- **Requests filed:** frontend/requests/for-backend.md — yes (REQ-002 OTP length/expiry, REQ-003 verify
|
|
error codes + lockout retry-after, REQ-004 multi-role `activeRole?`).
|
|
|
|
## frontend-phase-0 — Foundations: app shells, design system & data/contract patterns — 2026-07-02
|
|
- **Shipped:** 3 actor shells (customer bottom-nav / nurse / admin sidebar) + role-aware routing under
|
|
`(private-routes)`; `useActorRole`; the `services/{domain}` reference (`patients`, mocked behind a
|
|
seam) with deliberate Query caching + invalidation; `lib/api/types.ts` (envelope/pagination); money +
|
|
Shamsi-date utils; shared composites `OtpInput`/`PhoneNumberField`/`StepperHeader`/`StatusChip`/
|
|
`PlaceholderScreen` (each tested); i18n `nav`/`common`/`shell`/`patients` in both locales. Removed the
|
|
demo scaffolding; fixed the `BottomBar` pathname bug.
|
|
- **Consumes:** dev/contracts/conventions/* + openapi/swagger.v1.json (b0 = ping only). No feature
|
|
contract consumed yet.
|
|
- **Mocked client-side:** `services/patients` via `patientsMockApi` (USE_PATIENTS_MOCK=true) — template
|
|
for f1+. Swap is one line once real endpoints land.
|
|
- **Gate:** npm run check green · npm run test:ci green (72 tests) · npm run build green with
|
|
NEXT_PUBLIC_API_URL set.
|
|
- **Requests filed:** frontend/requests/for-backend.md — yes (REQ-001).
|