Adds auth pages
This commit is contained in:
+188
@@ -0,0 +1,188 @@
|
||||
# Domain Entities — Unit 2: Authentication Pages
|
||||
|
||||
## Overview
|
||||
|
||||
Unit 2 introduces client-side domain models for authentication guards, system initialization, and invitation completion. Several entities (`User`, `AuthSession`, `SetupStatus`) are inherited from Unit 1; this document defines those that are new or extended.
|
||||
|
||||
---
|
||||
|
||||
## Inherited from Unit 1 (reference only)
|
||||
|
||||
| Entity | Source | Description |
|
||||
|---|---|---|
|
||||
| `User` | `src/api/types.ts` | `{ id, name, email, role }` — from `AuthContext` |
|
||||
| `AuthSession` | `src/contexts/auth-context.ts` | In-memory `{ user, accessToken }` |
|
||||
| `SetupStatus` | `src/api/types.ts` | `{ initialized: boolean }` — from `GET /Setup/status` |
|
||||
| `AuthResponse` | `src/api/types.ts` | `{ accessToken, name }` — returned by login/refresh |
|
||||
|
||||
---
|
||||
|
||||
## New Entities
|
||||
|
||||
### UserRole
|
||||
|
||||
The application uses three roles, enforced by both backend and frontend guards.
|
||||
|
||||
```
|
||||
UserRole = 'Owner' | 'Admin' | 'User'
|
||||
```
|
||||
|
||||
| Role | Description |
|
||||
|---|---|
|
||||
| `Owner` | Full access to all routes, including `/settings` and `/cms` |
|
||||
| `Admin` | Access to `/users`; no access to `/settings` or `/cms` |
|
||||
| `User` | Access to `/dashboard` and `/profile` only |
|
||||
|
||||
---
|
||||
|
||||
### SetupFormData
|
||||
|
||||
Collected by the `SetupPage` form. Submitted to `POST /Setup`.
|
||||
|
||||
| Field | Type | Constraint |
|
||||
|---|---|---|
|
||||
| `name` | `string` | Required; min 1 character |
|
||||
| `email` | `string` | Required; valid email format |
|
||||
| `password` | `string` | Required; see BR-U2-01–05 |
|
||||
| `confirmPassword` | `string` | Required; must match `password` (BR-U2-06) |
|
||||
| `locale` | `'en' \| 'nl'` | Required; user's preferred UI language |
|
||||
|
||||
**Notes**:
|
||||
- `locale` defaults to the browser's detected language if supported, otherwise `'en'`
|
||||
- The `locale` preference is applied immediately when changed (live preview), using `i18n.changeLanguage()`
|
||||
- The backend `POST /Setup` payload includes `name`, `email`, `password` — `locale` is applied client-side only (stored in localStorage via i18n or browser preference)
|
||||
|
||||
---
|
||||
|
||||
### InvitationToken
|
||||
|
||||
Represents the token extracted from the URL query string on the `InviteCompletePage`.
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `token` | `string` | Raw JWT or opaque token from `?token=xxx` in the URL |
|
||||
|
||||
---
|
||||
|
||||
### InvitationValidation
|
||||
|
||||
Returned by `GET /Invitation/validate?token=xxx` (stub in Unit 2; full implementation in Unit 5).
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `email` | `string` | The email address the invitation was sent to |
|
||||
| `name` | `string \| null` | Pre-filled name (optional, may be null) |
|
||||
| `isValid` | `boolean` | Whether the token is still valid and not yet used |
|
||||
| `errorCode` | `'EXPIRED' \| 'USED' \| 'NOT_FOUND' \| null` | Error reason when `isValid = false` |
|
||||
|
||||
---
|
||||
|
||||
### InviteCompleteFormData
|
||||
|
||||
Collected by the `InviteCompletePage` form. Submitted to `POST /Invitation/complete`.
|
||||
|
||||
| Field | Type | Constraint |
|
||||
|---|---|---|
|
||||
| `email` | `string` | Read-only; populated from `InvitationValidation.email` |
|
||||
| `name` | `string` | Required; min 1 character |
|
||||
| `password` | `string` | Required; see BR-U2-01–05 |
|
||||
| `confirmPassword` | `string` | Required; must match `password` (BR-U2-06) |
|
||||
|
||||
---
|
||||
|
||||
### FormBannerError
|
||||
|
||||
Represents an API-level or network-level error surfaced as a dismissible banner above a form (BR-U2-21/22).
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `message` | `string` | User-facing error message |
|
||||
| `type` | `'api' \| 'network'` | Source of the error |
|
||||
|
||||
---
|
||||
|
||||
### TokenValidationState
|
||||
|
||||
Represents the loading/success/error lifecycle of the invitation token validation on page mount.
|
||||
|
||||
| State | Description |
|
||||
|---|---|
|
||||
| `loading` | Token validation in progress (spinner shown) |
|
||||
| `valid` | Token is valid; invitation form is shown |
|
||||
| `invalid` | Token is expired, used, or not found; error message shown |
|
||||
|
||||
---
|
||||
|
||||
## Entity Relationship Diagram
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class User {
|
||||
+string id
|
||||
+string name
|
||||
+string email
|
||||
+UserRole role
|
||||
}
|
||||
|
||||
class UserRole {
|
||||
<<enumeration>>
|
||||
Owner
|
||||
Admin
|
||||
User
|
||||
}
|
||||
|
||||
class AuthSession {
|
||||
+User user
|
||||
+string accessToken
|
||||
}
|
||||
|
||||
class SetupStatus {
|
||||
+boolean initialized
|
||||
}
|
||||
|
||||
class SetupFormData {
|
||||
+string name
|
||||
+string email
|
||||
+string password
|
||||
+string confirmPassword
|
||||
+string locale
|
||||
}
|
||||
|
||||
class InvitationToken {
|
||||
+string token
|
||||
}
|
||||
|
||||
class InvitationValidation {
|
||||
+string email
|
||||
+string name
|
||||
+boolean isValid
|
||||
+string errorCode
|
||||
}
|
||||
|
||||
class InviteCompleteFormData {
|
||||
+string email
|
||||
+string name
|
||||
+string password
|
||||
+string confirmPassword
|
||||
}
|
||||
|
||||
class FormBannerError {
|
||||
+string message
|
||||
+string type
|
||||
}
|
||||
|
||||
class TokenValidationState {
|
||||
<<enumeration>>
|
||||
loading
|
||||
valid
|
||||
invalid
|
||||
}
|
||||
|
||||
User --> UserRole : has
|
||||
AuthSession --> User : contains
|
||||
InvitationToken --> InvitationValidation : resolves to
|
||||
InviteCompleteFormData --> InvitationValidation : pre-filled from
|
||||
TokenValidationState --> InviteCompleteFormData : gates display of
|
||||
```
|
||||
|
||||
Text alternative: `User` has a `UserRole` (Owner/Admin/User); `AuthSession` holds a `User` and `accessToken`; `InvitationToken` resolves to `InvitationValidation` which pre-fills `InviteCompleteFormData`; `TokenValidationState` controls whether the form or error state is shown.
|
||||
Reference in New Issue
Block a user