# Business Rules — Unit 6: Profile, Settings & CMS Placeholder ## Access Control Rules ```mermaid graph TD Request["Incoming Route Request"] IsAuth{"Authenticated?"} Route{"Which route?"} IsOwner{"Role = Owner?"} AccessDenied["403 AccessDeniedPage"] NotFound["404 NotFoundPage"] Profile["ProfilePage"] Settings["SettingsPage"] Cms["CmsPage"] Login["Redirect to /login"] Request --> IsAuth IsAuth -->|No| Login IsAuth -->|Yes| Route Route -->|/profile| Profile Route -->|/settings| IsOwner Route -->|/cms| IsOwner Route -->|unknown path| NotFound IsOwner -->|Yes| Settings IsOwner -->|Yes| Cms IsOwner -->|No| AccessDenied classDef guard fill:#FF9800,stroke:#e65100,color:#000 classDef page fill:#2196F3,stroke:#0d47a1,color:#000 classDef error fill:#F44336,stroke:#b71c1c,color:#000 classDef start fill:#9C27B0,stroke:#4a148c,color:#000 class IsAuth guard class IsOwner guard class Route guard class Profile page class Settings page class Cms page class AccessDenied error class NotFound error class Login error class Request start ``` Text alternative: All routes require authentication (redirect to /login if not). /settings and /cms additionally require Owner role; non-Owners are shown 403. Unknown paths show 404. --- ## BR-01: Profile Access - **Rule**: Any authenticated user can access `/profile` - **Implementation**: ProfilePage is a child of `_authenticated.tsx` (inherits ProtectedRoute); no additional RoleGuard - **Data**: Profile data is read from AuthContext (no extra API call for display) ## BR-02: Profile — Name and Email are Editable - **Rule**: The logged-in user may update their own `name` and `email` - **Validation** (frontend, mirrors backend): - `name`: required, non-empty - `email`: required, valid email format - **Endpoint**: `PUT /api/v1/Users/me` - **After save**: Call `POST /api/v1/Auth/refresh` to synchronize AuthContext with updated values ## BR-03: Profile — Role is Read-Only - **Rule**: A user cannot change their own role from the profile page - **Display**: Role shown as a static badge; no edit controls rendered ## BR-04: Change Password - **Rule**: The logged-in user may change their own password via a dialog on ProfilePage - **Validation** (frontend, mirrors backend password policy): - `currentPassword`: required, non-empty - `newPassword`: required, min 8 chars, at least 1 uppercase, 1 lowercase, 1 digit, 1 special character - `confirmPassword` (UI-only field): must match `newPassword` - **Endpoint**: `POST /api/v1/Auth/change-password` - **On success**: Close dialog, show success toast; no AuthContext update needed (password change does not affect access token) ## BR-05: Settings — Owner Only - **Rule**: Only users with role `Owner` may access `/settings` - **Implementation**: `RoleGuard` with `allowedRoles={["Owner"]}` wraps SettingsPage - **On violation**: Redirect to `/403` ## BR-06: Settings — Availability Management - **Rule**: Owner may change the system availability status from SettingsPage - **Allowed modes**: `Available`, `Maintenance`, `Unavailable` - **Endpoint**: `POST /api/v1/Availability/admin/status` (OwnerOnly — already enforced by backend) - **Message field**: Optional free-text reason displayed to end-users - **On save**: Invalidate `useAvailabilityStatus` query cache to reflect new status immediately ## BR-07: CMS Page — Owner Only - **Rule**: Only users with role `Owner` may access `/cms` - **Implementation**: `RoleGuard` with `allowedRoles={["Owner"]}` wraps CmsPage - **On violation**: Redirect to `/403` - **Content**: Placeholder only — no functional CMS features in this unit ## BR-08: 403 Access Denied Page - **Rule**: Rendered when `RoleGuard` rejects a route request - **Content**: Heading "Access Denied" + explanatory message + "Back to Dashboard" button (navigates to `/`) - **No authentication required**: 403 is a public route (unauthenticated users hitting protected routes are redirected to `/login` by ProtectedRoute first) ## BR-09: 404 Not Found Page - **Rule**: Rendered when TanStack Router cannot match any registered route - **Content**: Heading "Page Not Found" + brief message + "Back to Dashboard" button (navigates to `/`) - **Implementation**: TanStack Router catch-all route (`$404.tsx`) ## BR-10: Backend — New Endpoints Required The following new backend endpoints must be added as part of Unit 6: | Endpoint | Method | Policy | Purpose | |----------|--------|--------|---------| | `/api/v1/Users/me` | PUT | Authenticated | Update own name and email | | `/api/v1/Auth/change-password` | POST | Authenticated | Change own password | Both endpoints operate on the currently authenticated user (identified via JWT claims).