fix(04-rbac): revise plans based on checker feedback

This commit is contained in:
2026-03-24 13:46:03 -06:00
parent bf4adf0b21
commit 2aecc5c787
3 changed files with 60 additions and 27 deletions

View File

@@ -11,7 +11,7 @@ files_modified:
- packages/portal/components/nav.tsx
- packages/portal/components/tenant-switcher.tsx
- packages/portal/components/impersonation-banner.tsx
- packages/portal/app/(dashboard)/invite/[token]/page.tsx
- packages/portal/app/invite/[token]/page.tsx
- packages/portal/app/(dashboard)/users/page.tsx
- packages/portal/app/(dashboard)/admin/users/page.tsx
- packages/portal/app/(dashboard)/layout.tsx
@@ -52,8 +52,8 @@ must_haves:
- path: "packages/portal/components/impersonation-banner.tsx"
provides: "Impersonation indicator banner"
min_lines: 15
- path: "packages/portal/app/(dashboard)/invite/[token]/page.tsx"
provides: "Invite acceptance page with password form"
- path: "packages/portal/app/invite/[token]/page.tsx"
provides: "Invite acceptance page with password form (outside dashboard layout — no auth required)"
min_lines: 40
- path: "packages/portal/app/(dashboard)/users/page.tsx"
provides: "Per-tenant user management page"
@@ -253,13 +253,13 @@ const navItems = [ /* dashboard, tenants, agents, usage, billing, api-keys */ ];
<task type="auto">
<name>Task 3: Invite acceptance page + user management pages</name>
<files>
packages/portal/app/(dashboard)/invite/[token]/page.tsx,
packages/portal/app/invite/[token]/page.tsx,
packages/portal/app/(dashboard)/users/page.tsx,
packages/portal/app/(dashboard)/admin/users/page.tsx
</files>
<action>
Create `packages/portal/app/(dashboard)/invite/[token]/page.tsx`:
- NOTE: This page must be accessible WITHOUT authentication. If the (dashboard) layout requires auth, create this at `packages/portal/app/invite/[token]/page.tsx` instead (outside the dashboard layout group). Check existing route structure.
Create `packages/portal/app/invite/[token]/page.tsx`:
- IMPORTANT: This page is created OUTSIDE the (dashboard) route group because the (dashboard) layout enforces authentication. Invite acceptance must be accessible to unauthenticated users who are creating their account.
- Reads `token` from URL params
- On load, validates token client-side by calling a GET endpoint or just displays the form (server validates on submit)
- Form fields: Password (min 8 chars), Confirm Password
@@ -289,7 +289,7 @@ const navItems = [ /* dashboard, tenants, agents, usage, billing, api-keys */ ];
<verify>
<automated>cd /home/adelorenzo/repos/konstruct/packages/portal && npx tsc --noEmit 2>&1 | head -30</automated>
</verify>
<done>Invite acceptance page renders password form and submits to accept endpoint. Per-tenant users page lists users with invite/resend capability. Platform admin users page shows cross-tenant user list with filters. All pages compile without TypeScript errors.</done>
<done>Invite acceptance page renders password form and submits to accept endpoint. Page is outside (dashboard) group so unauthenticated users can access it. Per-tenant users page lists users with invite/resend capability. Platform admin users page shows cross-tenant user list with filters. All pages compile without TypeScript errors.</done>
</task>
</tasks>
@@ -299,6 +299,7 @@ const navItems = [ /* dashboard, tenants, agents, usage, billing, api-keys */ ];
- `cd packages/portal && npx next build` — build succeeds
- Login as platform_admin: JWT contains role="platform_admin", sees all nav items
- Login as customer_operator: does not see Billing/API Keys/Users in nav, /billing redirects to /agents
- Visit /invite/{token} while logged out: page renders without auth redirect
</verification>
<success_criteria>
@@ -307,7 +308,7 @@ const navItems = [ /* dashboard, tenants, agents, usage, billing, api-keys */ ];
- Nav hides restricted items based on role
- Tenant switcher works for multi-tenant users (no page reload)
- Impersonation banner renders when impersonating
- Invite acceptance page accepts token and creates account
- Invite acceptance page at /invite/[token] (outside dashboard layout) accepts token and creates account without requiring auth
- User management pages exist for tenant admin and platform admin
- Portal builds and TypeScript compiles clean
</success_criteria>