refinement phase 2

This commit is contained in:
hamid
2026-07-13 01:14:35 +03:30
parent 0b45ec51f4
commit 1ce36f9414
22 changed files with 519 additions and 27 deletions
@@ -1,12 +1,20 @@
'use client';
import type { ReactNode } from 'react';
import { CustomerLayout } from '@/layout';
import { RoleGuard } from '@/components/auth';
import { APP_ROLES } from '@/constants';
/*
* Customer (family) route group — the primary mobile-first experience with the
* 5-tab bottom nav. A route group `(customer)` adds chrome without adding a URL
* segment, so these screens live at the app root (/, /bookings, /patients, …).
* RoleGuard gates it on a resolved customer role: a pure nurse lands on /nurse,
* a role-less user on /select-role — never the family app as a loading stand-in.
*/
export default function CustomerRouteLayout({ children }: { children: ReactNode }) {
return <CustomerLayout>{children}</CustomerLayout>;
return (
<RoleGuard expected={APP_ROLES.CUSTOMER}>
<CustomerLayout>{children}</CustomerLayout>
</RoleGuard>
);
}
@@ -1,11 +1,18 @@
'use client';
import type { ReactNode } from 'react';
import { AdminLayout } from '@/layout';
import { RoleGuard } from '@/components/auth';
import { APP_ROLES } from '@/constants';
/*
* Admin / backoffice route group (/admin/…) — desktop-oriented ops console (f15)
* with a persistent sidebar.
* with a persistent sidebar. RoleGuard gates the shell on the (collapsed) admin actor
* role; the per-console fine-grained gating stays with useAdminCapabilities inside.
*/
export default function AdminRouteLayout({ children }: { children: ReactNode }) {
return <AdminLayout>{children}</AdminLayout>;
return (
<RoleGuard expected={APP_ROLES.ADMIN}>
<AdminLayout>{children}</AdminLayout>
</RoleGuard>
);
}
@@ -1,11 +1,18 @@
'use client';
import type { ReactNode } from 'react';
import { NurseLayout } from '@/layout';
import { RoleGuard } from '@/components/auth';
import { APP_ROLES } from '@/constants';
/*
* Nurse route group (/nurse/…) — its own shell (dashboard, verification, EVV visits).
* A real path segment keeps nurse screens namespaced under /nurse.
* A real path segment keeps nurse screens namespaced under /nurse. RoleGuard redirects
* a caller without the nurse role home (with a toast); a nurse never flashes the wrong app.
*/
export default function NurseRouteLayout({ children }: { children: ReactNode }) {
return <NurseLayout>{children}</NurseLayout>;
return (
<RoleGuard expected={APP_ROLES.NURSE}>
<NurseLayout>{children}</NurseLayout>
</RoleGuard>
);
}
@@ -1,12 +1,19 @@
'use client';
import type { ReactNode } from 'react';
import { PartnerLayout } from '@/layout';
import { RoleGuard } from '@/components/auth';
/*
* Partner-center portal route group (/partner/…) — a separate authz scope from /admin (f15). A center
* admin sees only their own center; tenancy is server-enforced and each portal page resolves the caller's
* own center via `useMyPartnerCenter` (a 403/404 renders the access-denied state).
* own center via `useMyPartnerCenter` (a 403/404 renders the access-denied state). The RoleGuard here takes
* no `expected` role — partner scope isn't an `AppRole`, so the guard only hardens `/me` hydration (neutral
* loading/error instead of the raw shell); the center-resolution gate stays with `useMyPartnerCenter`.
*/
export default function PartnerRouteLayout({ children }: { children: ReactNode }) {
return <PartnerLayout>{children}</PartnerLayout>;
return (
<RoleGuard>
<PartnerLayout>{children}</PartnerLayout>
</RoleGuard>
);
}