Files
slp-modular-cms/aidlc-docs/features/cms-frontend/construction/unit-2/functional-design/business-rules.md
T
2026-06-21 00:15:28 +02:00

6.8 KiB
Raw Blame History

Business Rules — Unit 2: Authentication Pages

Password Validation (Shared Schema)

These rules apply to every password field in the application. The Zod schema lives in src/lib/schemas/auth.ts and is imported by SetupPage, InviteCompletePage, and LoginPage (BR-U2-24).

ID Rule Zod constraint
BR-U2-01 Minimum 8 characters .min(8)
BR-U2-02 At least 1 uppercase letter (AZ) .regex(/[A-Z]/)
BR-U2-03 At least 1 lowercase letter (az) .regex(/[a-z]/)
BR-U2-04 At least 1 digit (09) .regex(/[0-9]/)
BR-U2-05 At least 1 non-alphanumeric character (e.g. !@#$%^&*) .regex(/[^a-zA-Z0-9]/)

These rules mirror the backend IdentityOptions.Password configuration exactly. Any change to backend password rules must also update this schema.


Confirm Password

ID Rule
BR-U2-06 confirmPassword must be identical to password. Validated via Zod .refine() at the schema root level — not as an individual field constraint. Error is attached to the confirmPassword field.

Email Validation

ID Rule
BR-U2-07 email must pass Zod .email() (RFC-compliant format). Validated client-side before submission.

System Initialization Guard (InitGuard)

ID Rule
BR-U2-08 Setup status (GET /Setup/status) is fetched exactly once per browser session. The result is held in React state at the root route level. It is never re-fetched unless the user reloads the page.
BR-U2-09 When initialized: false, all routes redirect to /setup — including /login. The only route that bypasses this redirect is /setup itself.
BR-U2-10 When initialized: true, navigating to /setup redirects to /login. The /setup route is only accessible when the system is uninitialized.

Authentication Guard (ProtectedRoute)

ID Rule
BR-U2-11 Any route inside the authenticated layout requires a valid AuthSession (non-null user in AuthContext).
BR-U2-12 When there is no authenticated session, the router redirects to /login. The originally intended URL is preserved as a redirect search parameter (e.g. /login?redirect=%2Fusers).
BR-U2-13 No protected page content is rendered, even transiently, before the guard check resolves.

Role Guard (RoleGuard)

ID Rule
BR-U2-14 Route / (dashboard) — accessible to: Owner, Admin, User
BR-U2-15 Route /profile — accessible to: Owner, Admin, User
BR-U2-16 Route /users — accessible to: Owner, Admin
BR-U2-17 Route /settings — accessible to: Owner only
BR-U2-18 Route /cms — accessible to: Owner only
BR-U2-19 When a user's role is insufficient for the requested route, the page renders an inline "Access Denied" message within the normal page shell. No redirect to /403 and no separate route is created in Unit 2.
BR-U2-20 The inline "Access Denied" state must be rendered by RoleGuard as a wrapper/HOC, not embedded in individual page components.

SetupPage Rules

ID Rule
BR-U2-21 The SetupPage form collects: name, email, password, confirmPassword, locale.
BR-U2-22 locale defaults to the browser's detected language (navigator.language), falling back to 'en' if the detected language is not supported.
BR-U2-23 Changing locale immediately applies i18n.changeLanguage() so the page re-renders in the selected language as a preview.
BR-U2-24 After a successful POST /Setup response, the user is NOT automatically logged in. A success message is shown and the user is redirected to /login after a short delay (12 seconds) or immediately on a "Go to login" action.
BR-U2-25 The POST /Setup payload contains { name, email, password }. The locale field is not sent to the backend.

InviteCompletePage Rules

ID Rule
BR-U2-26 On page mount, the token from ?token=xxx is extracted from the URL and sent to GET /Invitation/validate?token=xxx.
BR-U2-27 While the validation request is in flight, a loading spinner is shown and the form is not rendered.
BR-U2-28 If the token is valid, the form is shown with the email field pre-filled from the validation response and set to read-only.
BR-U2-29 If the token is invalid or expired, an error state is shown. No form is rendered. The error message explains the reason (expired / already used / not found). A link to /login is provided.
BR-U2-30 If no token query parameter is present in the URL, this is treated as an invalid token (show error state immediately, no validation request).
BR-U2-31 After a successful POST /Invitation/complete response, the user is NOT automatically logged in. A success message is shown and the user is redirected to /login.

Form Error Handling (Application-Wide Standard)

These rules define the error handling pattern that applies to ALL forms in the application (SetupPage, InviteCompletePage, LoginPage).

ID Rule
BR-U2-32 Field validation errors from Zod are shown inline, directly below the field. Inline errors are triggered on blur (when the user leaves a field), not on every keystroke.
BR-U2-33 Once a field has been touched (blurred), validation re-runs on change so the error clears as soon as the user corrects the input.
BR-U2-34 API-level errors (e.g. 400 Bad Request, 409 Conflict) returned after form submission are shown in a dismissible banner above the form.
BR-U2-35 Network errors (no response received) are shown in the dismissible banner with the message: "Unable to connect. Please try again."
BR-U2-36 The banner is dismissed when the user submits the form again or clicks the dismiss button.
BR-U2-37 LoginPage (from Unit 1) must be updated in Unit 2 to align with the inline validation pattern (BR-U2-32/33). The banner pattern is already in place.

i18n Rules

ID Rule
BR-U2-38 All Unit 2 strings (setup, invite complete, error messages, guard messages) are added to the existing translation.json files under setup and inviteComplete namespaces. No separate namespace files are created.
BR-U2-39 The supported locales are en and nl. All keys must be present in both locale files.

MSW Handler Rules

ID Rule
BR-U2-40 POST /Setup is added to the existing src/mocks/setup/handlers.ts file.
BR-U2-41 GET /Invitation/validate and POST /Invitation/complete are added to a new file src/mocks/invitation/handlers.ts.
BR-U2-42 MSW handlers for invitation endpoints are stubs: they return hard-coded success/error scenarios sufficient to test Unit 2 UI states. Full dynamic behaviour is implemented in Unit 5.