119 lines
6.1 KiB
Markdown
119 lines
6.1 KiB
Markdown
|
|
---
|
||
|
|
phase: 03-agent-portal-shell
|
||
|
|
plan: 01
|
||
|
|
subsystem: database
|
||
|
|
tags: [drizzle, postgres, pgEnum, next-auth, middleware, routing]
|
||
|
|
|
||
|
|
# Dependency graph
|
||
|
|
requires:
|
||
|
|
- phase: 01-foundation
|
||
|
|
provides: Drizzle schema.ts with users table, auth.config.ts authorized callback, middleware.ts with /agent matcher
|
||
|
|
provides:
|
||
|
|
- clients and documents tables in PostgreSQL with document_status enum
|
||
|
|
- Drizzle migration 0001_watery_blindfold.sql
|
||
|
|
- /portal/:path* protected via middleware matcher and auth.config.ts authorized callback
|
||
|
|
- Post-login redirect lands on /portal/dashboard
|
||
|
|
- /agent/dashboard silently forwards to /portal/dashboard
|
||
|
|
affects: [03-02, 03-03, 03-04, all Phase 3 plans — clients/documents tables and /portal routing are foundations]
|
||
|
|
|
||
|
|
# Tech tracking
|
||
|
|
tech-stack:
|
||
|
|
added: [pgEnum from drizzle-orm/pg-core]
|
||
|
|
patterns: [pgEnum defined before referencing table, documentStatusEnum as named export, portal route protection mirrors agent route pattern in authorized callback]
|
||
|
|
|
||
|
|
key-files:
|
||
|
|
created:
|
||
|
|
- teressa-copeland-homes/drizzle/0001_watery_blindfold.sql
|
||
|
|
- teressa-copeland-homes/drizzle/meta/0001_snapshot.json
|
||
|
|
modified:
|
||
|
|
- teressa-copeland-homes/src/lib/db/schema.ts
|
||
|
|
- teressa-copeland-homes/middleware.ts
|
||
|
|
- teressa-copeland-homes/src/lib/auth.config.ts
|
||
|
|
- teressa-copeland-homes/src/app/agent/(protected)/dashboard/page.tsx
|
||
|
|
|
||
|
|
key-decisions:
|
||
|
|
- "documentStatusEnum exported before documents table — pgEnum must be declared before the table that references it or drizzle-kit may omit the CREATE TYPE statement"
|
||
|
|
- "portal route protection mirrors existing /agent pattern in authorized callback — isPortalRoute check added alongside isAgentRoute, both redirect unauthenticated to /agent/login"
|
||
|
|
- "Post-login redirect changed from /agent/dashboard to /portal/dashboard — agent portal lives at /portal prefix going forward"
|
||
|
|
- "DATABASE_URL not loaded from .env.local by drizzle-kit (uses dotenv/config which reads .env) — migration run with explicit env var; .env.local is sufficient for Next.js dev server"
|
||
|
|
|
||
|
|
patterns-established:
|
||
|
|
- "pgEnum: export enum constant before the table that uses it in schema.ts"
|
||
|
|
- "Route protection: add new route prefix to both middleware.ts matcher array AND auth.config.ts authorized callback isPortalRoute check"
|
||
|
|
|
||
|
|
requirements-completed: [CLIENT-01, CLIENT-02, CLIENT-03, DASH-01, DASH-02]
|
||
|
|
|
||
|
|
# Metrics
|
||
|
|
duration: 3min
|
||
|
|
completed: 2026-03-19
|
||
|
|
---
|
||
|
|
|
||
|
|
# Phase 3 Plan 01: Agent Portal Shell — Data & Routing Foundation Summary
|
||
|
|
|
||
|
|
**Drizzle schema extended with clients + documents tables (document_status pgEnum), migration applied to local PostgreSQL, and /portal/* routes protected via middleware + auth.config.ts with post-login redirect updated to /portal/dashboard**
|
||
|
|
|
||
|
|
## Performance
|
||
|
|
|
||
|
|
- **Duration:** 3 min
|
||
|
|
- **Started:** 2026-03-19T22:16:34Z
|
||
|
|
- **Completed:** 2026-03-19T22:19:00Z
|
||
|
|
- **Tasks:** 2
|
||
|
|
- **Files modified:** 6
|
||
|
|
|
||
|
|
## Accomplishments
|
||
|
|
|
||
|
|
- Added `clients` and `documents` tables to Drizzle schema with `documentStatusEnum` (Draft, Sent, Viewed, Signed), generated and applied migration successfully
|
||
|
|
- Extended middleware.ts matcher and auth.config.ts authorized callback to protect all `/portal/*` routes — unauthenticated requests redirect to `/agent/login`
|
||
|
|
- Updated post-login redirect from `/agent/dashboard` to `/portal/dashboard`, and replaced the old agent dashboard stub with a forward to `/portal/dashboard`
|
||
|
|
|
||
|
|
## Task Commits
|
||
|
|
|
||
|
|
Each task was committed atomically:
|
||
|
|
|
||
|
|
1. **Task 1: Extend Drizzle schema with clients and documents tables** - `f8f8b8f` (feat)
|
||
|
|
2. **Task 2: Update middleware and auth config to protect /portal routes** - `00f9c7c` (feat)
|
||
|
|
|
||
|
|
**Plan metadata:** (pending docs commit)
|
||
|
|
|
||
|
|
## Files Created/Modified
|
||
|
|
|
||
|
|
- `teressa-copeland-homes/src/lib/db/schema.ts` - Added pgEnum import, documentStatusEnum, clients table, documents table with FK to clients
|
||
|
|
- `teressa-copeland-homes/drizzle/0001_watery_blindfold.sql` - Migration: CREATE TYPE document_status AS ENUM, CREATE TABLE clients, CREATE TABLE documents with FK constraint
|
||
|
|
- `teressa-copeland-homes/drizzle/meta/0001_snapshot.json` - Drizzle schema snapshot for migration tracking
|
||
|
|
- `teressa-copeland-homes/middleware.ts` - Added "/portal/:path*" to matcher array alongside "/agent/:path*"
|
||
|
|
- `teressa-copeland-homes/src/lib/auth.config.ts` - Added isPortalRoute check in authorized callback; updated post-login redirect to /portal/dashboard
|
||
|
|
- `teressa-copeland-homes/src/app/agent/(protected)/dashboard/page.tsx` - Replaced session-check stub with redirect("/portal/dashboard")
|
||
|
|
|
||
|
|
## Decisions Made
|
||
|
|
|
||
|
|
- `documentStatusEnum` exported before `documents` table in schema.ts — pgEnum must precede the table that references it or drizzle-kit generate may silently omit the CREATE TYPE statement from the migration.
|
||
|
|
- `DATABASE_URL` not auto-loaded from `.env.local` by drizzle-kit (dotenv/config reads `.env` not `.env.local`) — migration was run with explicit `DATABASE_URL=...` env prefix. The Next.js dev server reads `.env.local` correctly so no change needed there.
|
||
|
|
- Portal route protection mirrors the existing `/agent` pattern exactly: new `isPortalRoute` variable, redirect to `/agent/login` on unauthenticated access.
|
||
|
|
|
||
|
|
## Deviations from Plan
|
||
|
|
|
||
|
|
None - plan executed exactly as written.
|
||
|
|
|
||
|
|
## Issues Encountered
|
||
|
|
|
||
|
|
- drizzle-kit `db:migrate` initially failed with "url: undefined" because it uses `dotenv/config` which reads `.env`, not `.env.local`. Resolved by passing `DATABASE_URL` as an explicit env variable prefix to the npm run command. This is a known behavior difference between Next.js (reads .env.local) and drizzle-kit (reads .env).
|
||
|
|
|
||
|
|
## User Setup Required
|
||
|
|
|
||
|
|
None - no external service configuration required. Database is local Docker PostgreSQL already running.
|
||
|
|
|
||
|
|
## Next Phase Readiness
|
||
|
|
|
||
|
|
- `clients` and `documents` tables are live in PostgreSQL; Phase 3 plans 02-04 can reference them immediately
|
||
|
|
- `/portal/*` route protection is active — any new pages added under `/portal/` are automatically protected
|
||
|
|
- Post-login redirect lands on `/portal/dashboard` — ready for the dashboard page to be built in plan 03-02
|
||
|
|
- No blockers for subsequent Phase 3 plans
|
||
|
|
|
||
|
|
---
|
||
|
|
*Phase: 03-agent-portal-shell*
|
||
|
|
*Completed: 2026-03-19*
|
||
|
|
|
||
|
|
## Self-Check: PASSED
|
||
|
|
|
||
|
|
All files verified present. All commits verified in git log.
|