Files
konstruct/.planning/phases/01-foundation/01-04-SUMMARY.md
Adolfo Delorenzo dcd89cc8fd docs(01-04): complete portal plan — tenant/agent CRUD and Agent Designer
- Create 01-04-SUMMARY.md documenting FastAPI portal API and Next.js portal
- Update STATE.md: advance plan, record metrics, add decisions
- Update ROADMAP.md: phase 1 plan progress (3/4 summaries)
- Update REQUIREMENTS.md: mark PRTA-01, PRTA-02 complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 10:22:22 -06:00

13 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
01-foundation 04 ui
nextjs
next-auth
tanstack-query
react-hook-form
zod
shadcn
fastapi
bcrypt
tailwind
phase provides
01-foundation plan 01 PostgreSQL schema with Tenant, Agent, PortalUser ORM models and RLS infrastructure
FastAPI portal API router at /api/portal (tenant CRUD, agent CRUD, auth verify/register)
Next.js 16 admin portal at localhost:3000 with login, tenant management, and Agent Designer
Auth.js v5 Credentials provider validating against FastAPI /auth/verify endpoint
proxy.ts (Next.js 16 auth proxy) protecting all routes except /login and /api/auth/*
Integration tests for all portal API CRUD operations (38 tests)
02-channel-expansion
03-polish-launch
operator-workflow
added patterns
bcrypt>=4.0.0 (password hashing in shared package)
next-auth@5.0.0-beta.30 (Auth.js v5 with Credentials provider)
@tanstack/react-query@^5 (server state and cache management)
react-hook-form@^7 (form management)
zod@^4 (schema validation)
@hookform/resolvers@^5 (standard-schema resolver for zod v4 compat)
shadcn/ui (button, card, input, textarea, select, badge, table, dialog, separator, label)
lucide-react (icons)
FastAPI APIRouter with prefix /api/portal for portal-specific endpoints
Portal API sets RLS current_tenant_id context for agent endpoints (admin bypasses but still scopes correctly)
Auth.js v5 JWT strategy — no DB session table, stateless tokens
Next.js 16 route groups: (auth) for login, (dashboard) for protected routes with shared layout
TanStack Query hooks in lib/queries.ts with standardized query key hierarchy
standardSchemaResolver from @hookform/resolvers/standard-schema for zod v4 + hookform v5 compat
proxy.ts instead of middleware.ts — Next.js 16 renamed middleware to proxy
created modified
packages/shared/shared/api/__init__.py — portal_router export
packages/shared/shared/api/portal.py — FastAPI portal router with all CRUD endpoints
tests/integration/test_portal_tenants.py — 23 tenant CRUD integration tests
tests/integration/test_portal_agents.py — 15 agent CRUD + Agent Designer field tests
packages/portal/proxy.ts — auth proxy protecting dashboard routes
packages/portal/lib/auth.ts — Auth.js v5 config with Credentials provider
packages/portal/lib/api.ts — typed fetch wrapper + API type definitions
packages/portal/lib/queries.ts — TanStack Query hooks for tenants and agents
packages/portal/components/agent-designer.tsx — Agent Designer form (Identity/Personality/Config/Capabilities/Escalation/Status)
packages/portal/components/tenant-form.tsx — reusable tenant create/edit form
packages/portal/components/nav.tsx — sidebar navigation (Dashboard/Tenants/Employees)
packages/portal/app/(dashboard)/layout.tsx — shared dashboard layout with QueryClientProvider
packages/portal/app/(dashboard)/dashboard/page.tsx — dashboard landing with tenant count
packages/portal/app/(dashboard)/tenants/page.tsx — tenant list with table UI
packages/portal/app/(dashboard)/tenants/new/page.tsx — tenant creation
packages/portal/app/(dashboard)/tenants/[id]/page.tsx — tenant detail/edit/delete
packages/portal/app/(dashboard)/agents/page.tsx — AI employees card grid
packages/portal/app/(dashboard)/agents/new/page.tsx — Agent Designer create
packages/portal/app/(dashboard)/agents/[id]/page.tsx — Agent Designer edit
packages/portal/app/(auth)/login/page.tsx — email/password login form
packages/portal/app/api/auth/[...nextauth]/route.ts — Auth.js route handler
packages/shared/pyproject.toml — added bcrypt>=4.0.0 dependency
docker-compose.yml — added portal service on port 3000
packages/portal/app/layout.tsx — updated metadata title to 'Konstruct Portal'
packages/portal/app/page.tsx — redirect to /dashboard or /login based on auth state
proxy.ts used instead of middleware.ts — Next.js 16 renamed middleware to proxy (deprecated warning)
standardSchemaResolver from @hookform/resolvers/standard-schema used instead of zodResolver — @hookform/resolvers v5 removed dedicated zod subpackage in favor of Standard Schema protocol; zod v4 implements Standard Schema
Route group (dashboard) used to share QueryClientProvider layout across /dashboard, /tenants, /agents routes without nesting them under a path prefix
Portal agent endpoints set RLS current_tenant_id context before DB operations — platform admin API still operates within tenant scope per RLS policy
Auth.js v5 JWT session strategy — no portal_sessions table needed for Phase 1; stateless tokens sufficient until enterprise SSO requirements
Agent Designer uses employee-centric labels: Employee Name, Job Title, Job Description (persona), Statement of Work (system_prompt)
Pattern 1: FastAPI portal router sets RLS tenant context via current_tenant_id ContextVar for all agent CRUD operations
Pattern 2: Integration tests use make_app(session) factory to override get_session dependency with test DB session
Pattern 3: Next.js 16 uses proxy.ts for edge-layer auth protection; Auth.js v5 auth() called directly in proxy
Pattern 4: TanStack Query key hierarchy [resource, ...params] enables targeted cache invalidation on mutations
Pattern 5: Zod v4 + @hookform/resolvers v5 via standardSchemaResolver (not zodResolver)
PRTA-01
PRTA-02
19min 2026-03-23

Phase 1 Plan 4: Portal — Tenant CRUD and Agent Designer Summary

FastAPI portal API with bcrypt auth + Next.js 16 admin portal featuring Auth.js v5 login, tenant management, and a full-featured Agent Designer for defining AI employees

Performance

  • Duration: 19 min
  • Started: 2026-03-23T16:01:33Z
  • Completed: 2026-03-23T16:20:09Z
  • Tasks: 2
  • Files modified: 25+ (new portal package + shared API)

Accomplishments

  • FastAPI portal router at /api/portal with full tenant CRUD, agent CRUD, and bcrypt auth endpoints
  • Agent endpoints correctly set PostgreSQL RLS current_tenant_id context for policy compliance
  • 38 integration tests prove all CRUD operations, validation, uniqueness constraints, and tenant isolation
  • Next.js 16 portal builds cleanly with Auth.js v5 Credentials provider, proxy.ts auth guard
  • Agent Designer with 6 grouped sections (Identity, Personality, Configuration, Capabilities, Escalation, Status) using employee-centric language throughout
  • Tenant management: list with slug badges, create with auto-slug generation, edit, delete with cascade confirmation

Task Commits

  1. Task 1: FastAPI portal API endpoints - 7b348b9 (feat)
  2. Task 2: Next.js portal with Auth.js v5 and Agent Designer - cec7180 (feat)

Files Created/Modified

  • /home/adelorenzo/repos/konstruct/packages/shared/shared/api/portal.py — FastAPI portal router with all endpoints
  • /home/adelorenzo/repos/konstruct/packages/shared/shared/api/__init__.py — exports portal_router
  • /home/adelorenzo/repos/konstruct/tests/integration/test_portal_tenants.py — 23 tenant CRUD tests
  • /home/adelorenzo/repos/konstruct/tests/integration/test_portal_agents.py — 15 agent + Agent Designer tests
  • /home/adelorenzo/repos/konstruct/packages/portal/proxy.ts — Next.js 16 auth proxy
  • /home/adelorenzo/repos/konstruct/packages/portal/lib/auth.ts — Auth.js v5 config
  • /home/adelorenzo/repos/konstruct/packages/portal/lib/api.ts — typed fetch client
  • /home/adelorenzo/repos/konstruct/packages/portal/lib/queries.ts — TanStack Query hooks
  • /home/adelorenzo/repos/konstruct/packages/portal/components/agent-designer.tsx — Agent Designer form
  • /home/adelorenzo/repos/konstruct/packages/portal/components/tenant-form.tsx — tenant form
  • /home/adelorenzo/repos/konstruct/packages/portal/components/nav.tsx — sidebar nav

Decisions Made

  • proxy.ts over middleware.ts: Next.js 16 renamed middleware.ts to proxy.ts. The old name generates a deprecation warning. Used the new convention throughout.
  • standardSchemaResolver over zodResolver: @hookform/resolvers@5 no longer ships a dedicated /zod subpackage. It uses the Standard Schema protocol instead, and zod v4 implements Standard Schema. Using standardSchemaResolver from @hookform/resolvers/standard-schema is the correct integration pattern.
  • Route group (dashboard): Moving tenant and agent routes into an (dashboard) route group shares the QueryClientProvider layout without adding /dashboard to the URL path. Clean separation of public ((auth)) and protected ((dashboard)) routes.
  • Auth.js v5 JWT strategy: No portal_sessions table required for Phase 1. JWT tokens stored in httpOnly cookies via Auth.js session strategy.

Deviations from Plan

Auto-fixed Issues

1. [Rule 1 - Bug] Agent portal endpoints set RLS tenant context

  • Found during: Task 1 (integration test execution)
  • Issue: POST /tenants/{tenant_id}/agents raised InsufficientPrivilegeError: new row violates row-level security policy for table "agents" — the portal API connected as konstruct_app role but didn't set app.current_tenant session variable before inserting
  • Fix: Added current_tenant_id.set(tenant_id) context manager around all agent DB operations in portal.py endpoints
  • Files modified: packages/shared/shared/api/portal.py
  • Verification: All 38 integration tests pass including agent create/read/update/delete
  • Committed in: 7b348b9 (Task 1 commit)

2. [Rule 3 - Blocking] Next.js 16 renamed middleware.ts to proxy.ts

  • Found during: Task 2 (reading Next.js 16 docs per CLAUDE.md/AGENTS.md instruction)
  • Issue: Plan specified creating middleware.ts; Next.js 16 deprecates this in favor of proxy.ts with a proxy() export
  • Fix: Created proxy.ts with export async function proxy() and export const config matcher
  • Files modified: packages/portal/proxy.ts (created instead of middleware.ts)
  • Verification: Build output shows ƒ Proxy (Middleware) — proxy is active
  • Committed in: cec7180 (Task 2 commit)

3. [Rule 3 - Blocking] zodResolver replaced with standardSchemaResolver

  • Found during: Task 2 (TypeScript build error)
  • Issue: @hookform/resolvers@5 removed the /zod subpackage — TypeScript error Type 'Resolver<...string | undefined...>' is not assignable to type 'Resolver<...string...>' because the new standard-schema protocol handles zod v4 output type inference differently
  • Fix: Changed all imports from zodResolver (@hookform/resolvers/zod) to standardSchemaResolver (@hookform/resolvers/standard-schema) in login page, agent-designer, and tenant-form
  • Files modified: app/(auth)/login/page.tsx, components/agent-designer.tsx, components/tenant-form.tsx
  • Verification: npm run build exits 0 with no TypeScript errors
  • Committed in: cec7180 (Task 2 commit)

4. [Rule 3 - Blocking] Route group reorganization for QueryClientProvider scope

  • Found during: Task 2 (Next.js prerender error)
  • Issue: Error: No QueryClient set, use QueryClientProvider to set one/agents and /tenants routes were outside the dashboard/layout.tsx so they didn't get the QueryClientProvider wrapper
  • Fix: Created (dashboard) route group with shared layout.tsx, moved /dashboard, /tenants, and /agents routes under it. URLs remain the same (/tenants, /agents, /dashboard) since route groups don't add path segments.
  • Files modified: entire app route structure reorganized into (auth) and (dashboard) groups
  • Verification: npm run build completes successfully with all 10 routes rendered
  • Committed in: cec7180 (Task 2 commit)

Total deviations: 4 auto-fixed (1 bug, 3 blocking) Impact on plan: All auto-fixes necessary for correctness and functionality. No scope creep. Deviations 2-4 are Next.js 16 + ecosystem version adaptations.

Issues Encountered

  • create-next-app initialized a nested .git repo inside packages/portal/ — removed with rm -rf packages/portal/.git before committing to prevent git submodule confusion.

User Setup Required

None — portal uses email/password auth against local DB, no external OAuth providers needed in Phase 1.

Next Phase Readiness

  • Portal API endpoints ready to receive connections from the gateway service (Plan 01-02, 01-03)
  • Auth.js session ready; will need AUTH_SECRET env var set in production
  • Agent Designer stores all fields needed for agent orchestration (Phase 2)
  • Portal service added to docker-compose.yml — requires npm run build output or container build before running

Self-Check: PASSED

All created files verified on disk. Both task commits (7b348b9, cec7180) confirmed in git log.


Phase: 01-foundation Completed: 2026-03-23