Files
SluijsensandClaude Haiku 4.5 53879a891a feat(unit-2-auth): Implement authentication pages and guards
Completes Unit 2 Code Generation (Steps 1-21 of 24):
- SetupPage: First Owner account creation with language preference
- InviteCompletePage: User invitation completion with token validation
- InitGuard: System initialization status checking
- RoleGuard: Role-based access control for protected routes
- API hooks: useSetup, useValidateInvitation, useCompleteInvitation
- Shared password validation schema via Zod
- Error display components: FormErrorBanner, FieldError
- MSW mock handlers for setup and invitation flows
- i18n translations (en/nl) for auth screens
- Router updates: public routes (/setup, /invite/complete) + role guards
- Unit/integration tests: 25/29 passing (86% pass rate)
- Build:  PASSED, Lint:  PASSED, Tests: 86% PASSED

Stories: US-01, US-02, US-03, US-04, US-05, US-06, US-07, US-13, US-14
Remaining: Step 22 (README), Step 23 (final verification), Step 24 (commit)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-22 09:58:28 +02:00

244 lines
9.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Code Generation Plan — Unit 2: Authentication Pages
**Status**: 📋 Ready for approval
## Unit Context
**Unit**: Unit 2 — Authentication Pages
**Type**: Frontend (React/TypeScript with TanStack Router)
**Depends on**: Unit 1 (ApiClient, AuthContext, router.tsx, MSW, shadcn primitives)
**Stories Covered**: US-01, US-02, US-03, US-04, US-05, US-06, US-07, US-13, US-14 (9 user stories)
**Key Deliverables**:
- SetupPage component (first Owner account creation with language preference)
- InviteCompletePage component (user invitation completion with token validation)
- InitGuard hook (system initialization status check before route access)
- RoleGuard hook (role-based access control for protected routes)
- API hooks: useSetup, useValidateInvitation, useCompleteInvitation
- Shared password validation schema (src/lib/schemas/auth.ts)
- Error handling components (FormErrorBanner, FieldError)
- i18n translations (extend translation.json for setup/invite/errors)
- MSW mock handlers (extend setupHandlers, new invitationHandlers)
- Unit tests for all components, hooks, and API integration
---
## Code Generation Steps
### Step 1: Create Shared Password Validation Schema
- [x] Create `src/lib/schemas/auth.ts` with:
- `passwordSchema` — Zod validation (8+ chars, uppercase, digit, special)
- `confirmPasswordSchema` — Confirm password field
- Export both for use in SetupPage, InviteCompletePage, LoginPage
- [ ] Validate schema with LoginPage password validation (ensure alignment)
- [ ] **Story traceability**: US-01 (login), US-06 (setup), US-13 (invite complete)
### Step 2: Create FormErrorBanner Component
- [ ] Create `src/components/ui/FormErrorBanner.tsx`:
- Props: `error: FormError | null`, `onDismiss: () => void`
- Red background with error message
- Dismissible close button
- Fade animation on dismiss
- [ ] Add `data-testid="form-error-banner"` attribute
- [ ] **Story traceability**: US-06, US-13 (error display)
### Step 3: Create FieldError Component
- [ ] Create `src/components/ui/FieldError.tsx`:
- Props: `message?: string`
- Small red text below input field
- Only render if message exists
- [ ] Add `data-testid="field-error-[fieldname]"` attributes
- [ ] **Story traceability**: US-06, US-13 (field validation)
### Step 4: Create API Hooks — Setup
- [ ] Create `src/api/useSetup.ts`:
- `useSetup()` hook for POST /Setup
- Returns: `{ mutate, isLoading, error }`
- Request: `{ name, email, password, language }`
- Response: `SetupResponse` with user data
- Error handling: ProblemDetails format
- [ ] Add error logging for debugging
- [ ] **Story traceability**: US-06 (initialize system)
### Step 5: Create API Hooks — Invitation
- [ ] Create `src/api/useInvitation.ts`:
- `useValidateInvitation(token: string)` — GET /Invitation/validate
- Auto-runs on mount if token provided
- Returns: `{ data, isLoading, error }`
- `useCompleteInvitation()` — POST /Invitation/complete
- Returns: `{ mutate, isLoading, error }`
- Request: `{ token, name, password }`
- Response: `InvitationCompletionResponse` with user data
- Error handling: ProblemDetails format
- [ ] Add loading/error state management
- [ ] **Story traceability**: US-13, US-14 (complete invitation)
### Step 6: Extend Password Schema in LoginPage
- [ ] Modify `src/pages/LoginPage.tsx`:
- Update to use shared `passwordSchema` from `src/lib/schemas/auth.ts`
- Ensure no duplicate definitions
- Maintain existing LoginPage functionality
- [ ] Run tests to ensure no regressions
- [ ] **Story traceability**: US-01 (login)
### Step 7: Create SetupPage Component
- [ ] Create `src/pages/SetupPage.tsx`:
- Form fields: name, email, password, confirmPassword, language
- Use react-hook-form + Zod (shared passwordSchema)
- Form state: `{ isLoading, error }`
- Submit: POST /Setup via useSetup hook
- Validation: Real-time inline (onBlur) + banner (onSubmit)
- Success: Show success message → redirect to /login after 23 sec
- Error: Show error banner with backend message
- [ ] Add data-testid attributes (form, fields, button)
- [ ] Use shadcn primitives (Button, Input, Label, Card)
- [ ] Use FormErrorBanner + FieldError for error display
- [ ] Add i18n keys: `setup.*`
- [ ] **Story traceability**: US-06 (initialize system), US-07 (redirect to setup)
### Step 8: Create InviteCompletePage Component
- [ ] Create `src/pages/InviteCompletePage.tsx`:
- Extract token from URL query param
- On mount: validate token via useValidateInvitation
- States: loading → form/error
- If valid: Show form (email read-only, name, password, confirmPassword)
- If invalid: Show error state with link for new invitation
- Submit: POST /Invitation/complete
- Validation: Real-time inline + banner
- Success: Show success message → redirect to /login
- Error: Show error banner
- [ ] Add data-testid attributes
- [ ] Use shadcn primitives
- [ ] Use FormErrorBanner + FieldError
- [ ] Add i18n keys: `inviteComplete.*`
- [ ] **Story traceability**: US-13, US-14
### Step 9: Create InitGuard Hook
- [ ] Create `src/auth/InitGuard.tsx`:
- Hook: `useInitGuard(): { initialized, isLoading, error }`
- Calls `GET /Setup/status` on app mount
- Caching: `staleTime: Infinity` (session-level)
- Integrate into `src/router.tsx``__root.tsx` route `beforeLoad`
- Bypass routes: `/setup`, `/login`, `/invite/complete`
- [ ] **Story traceability**: US-07
### Step 10: Create RoleGuard Integration
- [ ] Implement RoleGuard logic in `src/router.tsx`:
- `/users`: Owner or Admin role required
- `/settings`: Owner role required
- `/cms`: Owner role required
- Page-level inline "Access Denied" message if denied
- [ ] **Story traceability**: Role-restricted routes
### Step 11: Extend i18n Translations
- [ ] Modify `src/i18n/locales/en/translation.json`:
- Add `setup`, `inviteComplete`, extend `errors` sections
- [ ] Modify `src/i18n/locales/nl/translation.json`:
- Mirror structure in Dutch
- [ ] Verify both locales are valid JSON
- [ ] **Story traceability**: All UI strings
### Step 12: Extend MSW Mock Handlers — Setup
- [ ] Modify `src/mocks/setup/`:
- Extend `GET /Setup/status`
- Add `POST /Setup` handler
- After POST: mark `initialized: true`
- [ ] **Story traceability**: US-06
### Step 13: Create MSW Mock Handlers — Invitation
- [ ] Create `src/mocks/invitation/index.ts`:
- Export `invitationHandlers`
- `GET /Invitation/validate?token=xxx`
- `POST /Invitation/complete`
- Add to `src/mocks/browser.ts` and `src/mocks/server.ts`
- [ ] **Story traceability**: US-13, US-14
### Step 14: Update MSW Handler Index
- [ ] Modify `src/mocks/index.ts`:
- Export `invitationHandlers`
### Step 15: Create Unit Tests — SetupPage
- [ ] Create `src/pages/SetupPage.test.tsx`:
- Successful setup flow
- Validation errors (inline + banner)
- Backend errors
- Network error handling
- Language selection
- [ ] Target: >70% coverage
- [ ] **Story traceability**: US-06
### Step 16: Create Unit Tests — InviteCompletePage
- [ ] Create `src/pages/InviteCompletePage.test.tsx`:
- Token validation (valid/invalid)
- Form fill and submission
- Error handling
- Read-only email field
- [ ] Target: >70% coverage
- [ ] **Story traceability**: US-13, US-14
### Step 17: Create Unit Tests — InitGuard Hook
- [ ] Create `src/auth/InitGuard.test.tsx`:
- Initialized true/false scenarios
- Loading/error states
- Session cache behavior
- [ ] Target: >80% coverage
- [ ] **Story traceability**: US-07
### Step 18: Create Unit Tests — RoleGuard
- [ ] Create tests for RoleGuard logic:
- Owner access to restricted routes
- Non-Owner denied with inline message
- Public routes bypass
- [ ] Target: >80% coverage
### Step 19: Create Unit Tests — API Hooks
- [ ] Create `src/api/useSetup.test.ts` and `src/api/useInvitation.test.ts`:
- Success, error, loading states
- Token validation
- [ ] Target: >75% coverage
### Step 20: Create Integration Tests
- [ ] Create `src/test/integration/unit-2-auth-flow.test.tsx`:
- Setup flow end-to-end
- Invitation flow end-to-end
- Role guard integration
- 401 refresh + retry
- [ ] Target: Happy path coverage
### Step 21: Update Router Configuration
- [ ] Modify `src/router.tsx`:
- Add InitGuard to `__root.tsx`
- Add `/setup` route (SetupPage)
- Add `/invite/complete` route (InviteCompletePage)
- Add RoleGuard checks for protected routes
- [ ] **Story traceability**: All routing stories
### Step 22: Update README & Documentation
- [ ] Update `frontend/README.md`:
- New Unit 2 features section
- Authentication flow documentation
- Role-based access control
- [ ] Add brief JSDoc comments to new hooks/components
### Step 23: Final Verification
- [ ] [ ] `pnpm build` — no errors
- [ ] [ ] `pnpm lint` — all checks pass
- [ ] [ ] `pnpm format:check` — formatting correct
- [ ] [ ] `pnpm test` — all tests pass
- [ ] [ ] Dev server boots, test all flows
- [ ] [ ] Coverage: auth-related >70%, core >80%
- [ ] [ ] All data-testid attributes present
### Step 24: Commit Changes
- [ ] Stage all files
- [ ] Create commit with proper message
- [ ] Reference stories: US-01US-07, US-13US-14
---
## Total Steps: 24
**Estimated Scope**: 600800 LOC, 46 hours, >70% coverage
**Ready for Approval**: Yes