10 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 02-authentication-multi-tenancy | 02 | auth, ui |
|
|
|
|
|
|
|
|
|
8min | 2026-06-18 |
Phase 2 Plan 02: Frontend Auth & User/Tenant CRUD Summary
Split-screen login with JWT middleware route protection, auth-wired portal chrome, and admin CRUD pages for users (ADMIN+) and tenants (SUPER_ADMIN)
Performance
- Duration: 8 min
- Started: 2026-06-18T11:30:35Z
- Completed: 2026-06-18T11:39:05Z
- Tasks: 3
- Files modified: 26
Accomplishments
- Split-screen login page with Tessera branding (yellow #ffed00 left panel) and form (right panel), including remember-me checkbox for session duration control
- Next.js middleware validates JWT on every route, redirects unauthenticated users to /login, and handles mustChangePassword redirect
- Header displays logged-in user initial with dropdown (display name, role badge, logout); sidebar footer shows user name and role from Zustand auth store
- User CRUD API with ADMIN/SUPER_ADMIN access: ADMIN scoped to own tenant, cannot escalate to SUPER_ADMIN role
- Tenant CRUD API with SUPER_ADMIN-only access: includes user count, blocks deletion of tenants with active users
- Admin users page with table, create/edit/delete modals; admin tenants page with table, create/edit/deactivate
- Sidebar "Verwaltung" section visible to ADMIN+, with "Mandanten" link only for SUPER_ADMIN
- Complete DE/EN i18n coverage for all new auth, admin, and header strings
Task Commits
Each task was committed atomically:
- Task 1: Auth infrastructure -
cdf4d60(feat: route groups, middleware, session, auth-actions, auth store) - Task 2: Login page UI and header/sidebar wiring -
e7b2a70(feat: split-screen login, user dropdown, i18n) - Task 3: User/Tenant CRUD API + admin pages -
bfb04ea(feat: controllers, DTOs, admin UI, sidebar admin nav)
Files Created/Modified
Created
apps/web/src/app/(auth)/layout.tsx- Standalone auth layout (no sidebar/header)apps/web/src/app/(auth)/login/page.tsx- Split-screen login page with formapps/web/src/app/(portal)/layout.tsx- Portal layout wrapping with AppShellapps/web/src/app/(portal)/page.tsx- Dashboard page (moved from root)apps/web/src/middleware.ts- JWT-based route protection middlewareapps/web/src/lib/session.ts- Edge-compatible JWT verification with joseapps/web/src/lib/auth-actions.ts- Server actions: login, logout, fetchCurrentUserapps/web/src/lib/stores/auth-store.ts- Zustand store for client-side user stateapps/api/src/user/user.controller.ts- User CRUD endpoints with role/tenant guardsapps/api/src/user/dto/create-user.dto.ts- CreateUserDto with class-validatorapps/api/src/user/dto/update-user.dto.ts- UpdateUserDto extending CreateUserDtoapps/api/src/tenant/tenant.controller.ts- Tenant CRUD endpoints (SUPER_ADMIN only)apps/api/src/tenant/dto/create-tenant.dto.ts- CreateTenantDto with slug validationapps/web/src/app/(portal)/admin/users/page.tsx- User management admin pageapps/web/src/app/(portal)/admin/tenants/page.tsx- Tenant management admin page
Modified
apps/web/src/components/layout/header.tsx- Auth-wired user avatar dropdown with logoutapps/web/src/components/layout/sidebar-footer.tsx- Auth-wired user info displayapps/web/src/components/layout/sidebar.tsx- Added Verwaltung admin sectionapps/web/src/messages/de.json- Added auth, header.role, admin i18n keysapps/web/src/messages/en.json- Added auth, header.role, admin i18n keysapps/api/src/user/user.module.ts- Added UserControllerapps/api/src/tenant/tenant.module.ts- Added TenantControllerapps/web/package.json- Added jose, zodapps/api/package.json- Added @nestjs/mapped-types
Decisions Made
- Route groups over conditional rendering: Used Next.js route groups
(auth)and(portal)to separate layouts cleanly. The(auth)group has a minimal layout (no sidebar/header per D-04), while(portal)wraps everything in AppShell. - Server Action cookie forwarding: In development (separate ports 3000/3001), the login server action manually reads Set-Cookie from the API response and sets it via Next.js cookies() API to bridge the cross-origin gap.
- Remember-me via cookie duration: The remember-me checkbox controls whether the session cookie has a 30-day maxAge (checked) or is a session cookie (unchecked, expires on browser close). Both use the same JWT.
- Controller-level tenant isolation: ADMIN user requests filter by tenantId at the controller level as defense-in-depth alongside RLS, ensuring ADMIN users never see cross-tenant data even if RLS is misconfigured.
- Installed @nestjs/mapped-types: Required for PartialType DTO pattern (UpdateUserDto extends CreateUserDto with all fields optional).
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Added definite assignment assertions to DTO properties
- Found during: Task 3 (User/Tenant CRUD)
- Issue: TypeScript strict mode required definite assignment for DTO class properties, causing type-check failures
- Fix: Added
!definite assignment assertions to required DTO properties (standard NestJS DTO pattern with class-validator) - Files modified: create-user.dto.ts, create-tenant.dto.ts
- Verification:
pnpm turbo type-checkpasses - Committed in:
bfb04ea(Task 3 commit)
2. [Rule 3 - Blocking] Installed @nestjs/mapped-types
- Found during: Task 3 (User/Tenant CRUD)
- Issue: PartialType import from @nestjs/mapped-types was not available; package not listed in plan dependencies
- Fix: Ran
pnpm add @nestjs/mapped-typesin apps/api - Files modified: apps/api/package.json, pnpm-lock.yaml
- Verification: UpdateUserDto compiles correctly, type-check passes
- Committed in:
bfb04ea(Task 3 commit)
Total deviations: 2 auto-fixed (1 bug, 1 blocking) Impact on plan: Both auto-fixes necessary for compilation. No scope creep.
Issues Encountered
- Stale .next cache: After moving
page.tsxfrom root to(portal)/route group, the.next/typesdirectory still referenced the old location. Fixed by clearing.nextcache before type-check.
User Setup Required
None - no external service configuration required. JWT_SECRET env var must be set for production (development uses a fallback).
Next Phase Readiness
- Login flow is fully wired: user can authenticate via split-screen login page and reach the portal
- Auth state flows through the entire portal: header dropdown, sidebar footer, admin page access checks
- User and tenant CRUD is complete for admin workflows
- Ready for LDAP sync (Phase 2, Plan 03 if planned) or marketplace features (Phase 3)
- Password reset flow (D-03) requires SMTP setup -- deferred to separate plan
Self-Check: PASSED
All 16 created/expected files verified on disk. All 3 task commits (cdf4d60, e7b2a70, bfb04ea) verified in git log. Type-check passes for all packages.
Phase: 02-authentication-multi-tenancy Completed: 2026-06-18