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>
This commit is contained in:
@@ -40,8 +40,8 @@ Requirements for beta-ready release. Each maps to roadmap phases.
|
||||
|
||||
### Admin Portal
|
||||
|
||||
- [ ] **PRTA-01**: Operator can create, view, update, and delete tenants
|
||||
- [ ] **PRTA-02**: Operator can design agents via a dedicated Agent Designer module — defining job description, statement of work, persona, system prompt, tool assignments, and escalation rules
|
||||
- [x] **PRTA-01**: Operator can create, view, update, and delete tenants
|
||||
- [x] **PRTA-02**: Operator can design agents via a dedicated Agent Designer module — defining job description, statement of work, persona, system prompt, tool assignments, and escalation rules
|
||||
- [ ] **PRTA-03**: Operator can connect messaging channels (Slack, WhatsApp) via guided wizard
|
||||
- [ ] **PRTA-04**: New tenants are guided through structured onboarding (connect channel, configure agent, test message)
|
||||
- [ ] **PRTA-05**: Operator can manage subscription plans and billing via Stripe integration
|
||||
@@ -114,8 +114,8 @@ Which phases cover which requirements. Updated during roadmap creation.
|
||||
| TNNT-02 | Phase 1 | Complete |
|
||||
| TNNT-03 | Phase 1 | Complete |
|
||||
| TNNT-04 | Phase 1 | Complete |
|
||||
| PRTA-01 | Phase 1 | Pending |
|
||||
| PRTA-02 | Phase 1 | Pending |
|
||||
| PRTA-01 | Phase 1 | Complete |
|
||||
| PRTA-02 | Phase 1 | Complete |
|
||||
| PRTA-03 | Phase 3 | Pending |
|
||||
| PRTA-04 | Phase 3 | Pending |
|
||||
| PRTA-05 | Phase 3 | Pending |
|
||||
|
||||
@@ -77,7 +77,7 @@ Phases execute in numeric order: 1 → 2 → 3
|
||||
|
||||
| Phase | Plans Complete | Status | Completed |
|
||||
|-------|----------------|--------|-----------|
|
||||
| 1. Foundation | 2/4 | In Progress| |
|
||||
| 1. Foundation | 3/4 | In Progress| |
|
||||
| 2. Agent Features | 0/4 | Not started | - |
|
||||
| 3. Operator Experience | 0/2 | Not started | - |
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@ gsd_state_version: 1.0
|
||||
milestone: v1.0
|
||||
milestone_name: milestone
|
||||
status: planning
|
||||
stopped_at: Completed 01-foundation 01-02-PLAN.md
|
||||
last_updated: "2026-03-23T16:08:44.982Z"
|
||||
stopped_at: Completed 01-foundation 01-04-PLAN.md
|
||||
last_updated: "2026-03-23T16:22:05.663Z"
|
||||
last_activity: 2026-03-23 — Roadmap created, ready for Phase 1 planning
|
||||
progress:
|
||||
total_phases: 3
|
||||
completed_phases: 0
|
||||
total_plans: 4
|
||||
completed_plans: 2
|
||||
completed_plans: 3
|
||||
percent: 0
|
||||
---
|
||||
|
||||
@@ -52,6 +52,7 @@ Progress: [░░░░░░░░░░] 0%
|
||||
*Updated after each plan completion*
|
||||
| Phase 01-foundation P01 | 12 | 2 tasks | 32 files |
|
||||
| Phase 01-foundation P02 | 6 | 2 tasks | 15 files |
|
||||
| Phase 01-foundation P04 | 19 | 2 tasks | 25 files |
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
@@ -70,6 +71,9 @@ Recent decisions affecting current work:
|
||||
- [Phase 01-foundation]: Celery tasks are always sync def with asyncio.run() — hard architectural constraint, never async def
|
||||
- [Phase 01-foundation]: AI transparency clause is unconditional in system prompt — agents must disclose AI identity when directly asked
|
||||
- [Phase 01-foundation]: llm-pool port 8004 (consistent with shared/config.py llm_pool_url default, not plan-stated 8002)
|
||||
- [Phase 01-foundation]: proxy.ts used instead of middleware.ts — Next.js 16 renamed middleware to proxy
|
||||
- [Phase 01-foundation]: standardSchemaResolver used over zodResolver — hookform/resolvers v5 dropped zod subpackage, uses Standard Schema protocol; zod v4 implements Standard Schema
|
||||
- [Phase 01-foundation]: Auth.js v5 JWT session strategy chosen — no portal_sessions DB table needed for Phase 1, stateless tokens sufficient
|
||||
|
||||
### Pending Todos
|
||||
|
||||
@@ -81,6 +85,6 @@ None yet.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-03-23T16:08:44.980Z
|
||||
Stopped at: Completed 01-foundation 01-02-PLAN.md
|
||||
Last session: 2026-03-23T16:22:05.661Z
|
||||
Stopped at: Completed 01-foundation 01-04-PLAN.md
|
||||
Resume file: None
|
||||
|
||||
199
.planning/phases/01-foundation/01-04-SUMMARY.md
Normal file
199
.planning/phases/01-foundation/01-04-SUMMARY.md
Normal file
@@ -0,0 +1,199 @@
|
||||
---
|
||||
phase: 01-foundation
|
||||
plan: 04
|
||||
subsystem: ui
|
||||
tags: [nextjs, next-auth, tanstack-query, react-hook-form, zod, shadcn, fastapi, bcrypt, tailwind]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 01-foundation plan 01
|
||||
provides: "PostgreSQL schema with Tenant, Agent, PortalUser ORM models and RLS infrastructure"
|
||||
provides:
|
||||
- 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)
|
||||
affects: [02-channel-expansion, 03-polish-launch, operator-workflow]
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added:
|
||||
- "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)"
|
||||
patterns:
|
||||
- "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"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- "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"
|
||||
modified:
|
||||
- "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"
|
||||
|
||||
key-decisions:
|
||||
- "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)"
|
||||
|
||||
patterns-established:
|
||||
- "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)"
|
||||
|
||||
requirements-completed: [PRTA-01, PRTA-02]
|
||||
|
||||
# Metrics
|
||||
duration: 19min
|
||||
completed: 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*
|
||||
Reference in New Issue
Block a user