- 04-02-SUMMARY.md: Auth.js JWT + role nav + tenant switcher + impersonation banner + user pages - STATE.md: advanced to plan 3, metrics recorded, base-ui decisions added - ROADMAP.md: phase 4 updated to 2/3 plans complete - REQUIREMENTS.md: RBAC-05 marked complete
7.4 KiB
7.4 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 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 04-rbac | 02 | auth |
|
|
|
|
|
|
|
|
|
5min | 2026-03-24 |
Phase 4 Plan 02: Portal RBAC Integration Summary
Role-based portal with Auth.js JWT carrying role+tenants, operator path restrictions, tenant switcher, impersonation banner, invite acceptance page, and user management pages
Performance
- Duration: ~5 min
- Started: 2026-03-24T23:02:53Z
- Completed: 2026-03-24T23:07:17Z
- Tasks: 3
- Files modified: 9 (4 modified, 5 created from scratch + 3 new pages)
Accomplishments
- JWT now carries role + tenant_ids + active_tenant_id; proxy enforces role-based redirects silently
- Tenant switcher updates active_tenant_id in JWT without page reload, invalidates TanStack Query cache
- Three new pages: invite acceptance (public), per-tenant users, platform admin global users
Task Commits
- Tasks 1+2: Auth.js JWT + nav + tenant switcher + impersonation banner -
fcb1166(feat) - Task 3: Invite acceptance page + user management pages -
744cf79(feat)
Files Created/Modified
packages/portal/lib/auth-types.ts- Module augmentation: role, tenant_ids, active_tenant_id in JWT/Session/User typespackages/portal/lib/auth.ts- JWT callbacks carry role+tenants, trigger=update for tenant switch and impersonation clearpackages/portal/proxy.ts- /invite public, customer_operator restricted from billing/users/admin, role-based landing pagepackages/portal/components/nav.tsx- Role-filtered nav with Users and Platform admin itemspackages/portal/components/tenant-switcher.tsx- Multi-tenant dropdown, Auth.js update() + queryClient invalidationpackages/portal/components/impersonation-banner.tsx- Fixed amber banner with exit buttonpackages/portal/app/(dashboard)/layout.tsx- Integrates ImpersonationBanner and TenantSwitcherpackages/portal/app/invite/[token]/page.tsx- Password form, POST /api/portal/invitations/accept, redirect to /loginpackages/portal/app/(dashboard)/users/page.tsx- Tenant user list, invite dialog, resend pending invitationspackages/portal/app/(dashboard)/admin/users/page.tsx- Cross-tenant user table, tenant+role filters, invite with tenant selector
Decisions Made
base-ui DialogTriggerusesrenderprop notasChild— the shadcn components are base-ui based, not Radixbase-ui Select onValueChangetyped as(string | null)— filter state setters use?? ""to coerce nullzod v4z.enum()does not acceptrequired_erroroption — removed from both user pages- Next.js 15
paramsis a Promise in page components — unwrap withuse(params)per decision from Phase 3
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Fixed base-ui component API incompatibilities
- Found during: Task 3 (TypeScript compilation)
- Issue: Code written using Radix/shadcn API conventions (
asChild,onValueChange: (string) => void,required_errorin zod enum). The portal uses base-ui primitives which have different APIs. - Fix: Replaced
DialogTrigger asChildwithDialogTrigger render={<Button>}. WrappedSelectwithControllerfrom react-hook-form. Changed filteronValueChangehandlers to use?? "". Removedrequired_errorfromz.enum()calls. - Files modified:
app/(dashboard)/users/page.tsx,app/(dashboard)/admin/users/page.tsx - Verification:
npx tsc --noEmitpasses with zero errors - Committed in:
744cf79(Task 3 commit)
Total deviations: 1 auto-fixed (Rule 1 - Bug) Impact on plan: Auto-fix necessary for TypeScript compilation. No scope creep — same functionality, correct component APIs.
Issues Encountered
- Tasks 1 and 2 files (
auth.ts,auth-types.ts,proxy.ts,nav.tsx,tenant-switcher.tsx,impersonation-banner.tsx,layout.tsx) were already fully implemented from Plan 01 execution. Verified TypeScript clean and committed the staged changes.
User Setup Required
None - no external service configuration required.
Next Phase Readiness
- Portal RBAC is fully wired: JWT contains role+tenants, proxy enforces access, nav filters by role
- User management pages exist and are wired to expected API endpoints
- Plan 03 needs to implement the backend API endpoints:
GET /api/portal/tenants/{id}/users,GET /api/portal/admin/users,POST /api/portal/invitations/{id}/resend - Invite acceptance page wired to
POST /api/portal/invitations/accept(implemented in Plan 01)
Phase: 04-rbac Completed: 2026-03-24
Self-Check: PASSED
- All 9 portal files confirmed present on disk
- Commit fcb1166 (Tasks 1+2) confirmed in git log
- Commit 744cf79 (Task 3) confirmed in git log
- TypeScript compiles clean (zero errors)