Adds profile and settings pages
This commit is contained in:
+112
@@ -0,0 +1,112 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user