docs(13-02): complete ai-prepare route plan — POST handler, guard chain, AI pipeline
- 13-02-SUMMARY.md created with accomplishments, decisions, file list - STATE.md: plan position advanced to 2/4, decisions logged, session updated - ROADMAP.md: phase 13 progress updated to 2 summaries Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -316,4 +316,4 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
|
|||||||
| 11.1. Agent and Client Initials (INSERTED) | 3/3 | Complete | 2026-03-21 | - |
|
| 11.1. Agent and Client Initials (INSERTED) | 3/3 | Complete | 2026-03-21 | - |
|
||||||
| 12. Filled Document Preview | 2/2 | Complete | 2026-03-21 | - |
|
| 12. Filled Document Preview | 2/2 | Complete | 2026-03-21 | - |
|
||||||
| 12.1. Per-Field Text Editing and Quick-Fill (INSERTED) | 2/2 | Complete | 2026-03-21 | - |
|
| 12.1. Per-Field Text Editing and Quick-Fill (INSERTED) | 2/2 | Complete | 2026-03-21 | - |
|
||||||
| 13. AI Field Placement and Pre-fill | 1/4 | In Progress| | - |
|
| 13. AI Field Placement and Pre-fill | 2/4 | In Progress| | - |
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ gsd_state_version: 1.0
|
|||||||
milestone: v1.1
|
milestone: v1.1
|
||||||
milestone_name: Smart Document Preparation
|
milestone_name: Smart Document Preparation
|
||||||
status: unknown
|
status: unknown
|
||||||
last_updated: "2026-03-21T23:02:01.085Z"
|
last_updated: "2026-03-21T23:05:00Z"
|
||||||
progress:
|
progress:
|
||||||
total_phases: 15
|
total_phases: 15
|
||||||
completed_phases: 14
|
completed_phases: 14
|
||||||
total_plans: 48
|
total_plans: 48
|
||||||
completed_plans: 45
|
completed_plans: 46
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -23,9 +23,9 @@ See: .planning/PROJECT.md (updated 2026-03-21)
|
|||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 13 (AI Field Placement and Pre-fill) — IN PROGRESS
|
Phase: 13 (AI Field Placement and Pre-fill) — IN PROGRESS
|
||||||
Plan: 1 of 4 complete — Plan 01 done; Plans 02-04 remaining
|
Plan: 2 of 4 complete — Plans 01-02 done; Plans 03-04 remaining
|
||||||
Status: Phase 13 Plan 01 complete — AI foundation layer (extract-text.ts, field-placement.ts, aiCoordsToPagePdfSpace unit tests) shipped; openai SDK installed; ready for Plan 02 (AI route handler)
|
Status: Phase 13 Plan 02 complete — POST /api/documents/[id]/ai-prepare route implemented with full guard chain and AI pipeline orchestration; TypeScript compiles clean; ready for Plan 03 (UI button)
|
||||||
Last activity: 2026-03-21 — Phase 13 Plan 01: AI utility modules implemented, TDD unit tests pass, TypeScript compiles clean.
|
Last activity: 2026-03-21 — Phase 13 Plan 02: ai-prepare route handler implemented, writes AI-placed fields to DB, status stays Draft.
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -123,6 +123,10 @@ Recent decisions affecting v1.1 work:
|
|||||||
- [Phase 13-ai-field-placement-and-pre-fill]: Standard field sizes (checkbox=24x24, others=144x36pt) override AI widthPct/heightPct for consistency with FieldPlacer defaults
|
- [Phase 13-ai-field-placement-and-pre-fill]: Standard field sizes (checkbox=24x24, others=144x36pt) override AI widthPct/heightPct for consistency with FieldPlacer defaults
|
||||||
- [Phase 13-ai-field-placement-and-pre-fill]: textFillData keyed by UUID assigned in route handler — matches Phase 12.1 design where DocumentPageClient uses field.id as key
|
- [Phase 13-ai-field-placement-and-pre-fill]: textFillData keyed by UUID assigned in route handler — matches Phase 12.1 design where DocumentPageClient uses field.id as key
|
||||||
- [Phase 13-ai-field-placement-and-pre-fill]: GlobalWorkerOptions.workerSrc='' set at module level in extract-text.ts for Node.js fake-worker mode; client components set workerSrc independently
|
- [Phase 13-ai-field-placement-and-pre-fill]: GlobalWorkerOptions.workerSrc='' set at module level in extract-text.ts for Node.js fake-worker mode; client components set workerSrc independently
|
||||||
|
- [Phase 13-02]: OPENAI_API_KEY guard in ai-prepare route returns 503 — distinguishes config error from 500 server error; more actionable for agent
|
||||||
|
- [Phase 13-02]: try/catch wraps extractPdfText + classifyFieldsWithAI together — single error boundary returns 500 with error message string
|
||||||
|
- [Phase 13-02]: ai-prepare route does NOT change document status — stays Draft so agent can review and adjust AI-placed fields before prepare/send
|
||||||
|
- [Phase 13-02]: Path traversal guard placed before AI calls — fail fast without expensive PDF extraction on invalid paths
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -136,5 +140,5 @@ None yet.
|
|||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-03-21
|
Last session: 2026-03-21
|
||||||
Stopped at: Completed 12.1-per-field-text-editing-and-quick-fill/12.1-02-PLAN.md — human approved all 12 verification steps; phase 12.1 complete; ready for Phase 13
|
Stopped at: Completed 13-ai-field-placement-and-pre-fill/13-02-PLAN.md — ai-prepare route implemented; Plan 02 of 4 done; ready for Plan 03 (UI button)
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
---
|
||||||
|
phase: 13-ai-field-placement-and-pre-fill
|
||||||
|
plan: 02
|
||||||
|
subsystem: api
|
||||||
|
tags: [openai, next-app-router, drizzle, pdfjs-dist, gpt-4o-mini, route-handler]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 13-ai-field-placement-and-pre-fill/13-01
|
||||||
|
provides: extractPdfText, classifyFieldsWithAI, aiCoordsToPagePdfSpace, PageText interface
|
||||||
|
- phase: 12.1-per-field-text-editing-and-quick-fill
|
||||||
|
provides: textFillData keyed by field UUID, DocumentPageClient state architecture
|
||||||
|
- phase: 10-expanded-field-types-end-to-end
|
||||||
|
provides: SignatureFieldData interface, SignatureFieldType union
|
||||||
|
provides:
|
||||||
|
- POST /api/documents/[id]/ai-prepare — full AI placement pipeline orchestration
|
||||||
|
- Returns { fields: SignatureFieldData[], textFillData: Record<string, string> } to client
|
||||||
|
- Writes AI-placed fields to DB signatureFields column; status stays Draft
|
||||||
|
affects: [13-03-ui-button, 13-04-integration-test]
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- Next.js App Router route with params as Promise<{ id: string }> pattern
|
||||||
|
- Drizzle query with { with: { client: true } } to load related client profile in one round-trip
|
||||||
|
- OPENAI_API_KEY guard returns 503 (not 500) — distinguishes config error from server error
|
||||||
|
- try/catch wrapping extractPdfText + classifyFieldsWithAI — AI/PDF errors surface as 500 with message
|
||||||
|
- Document status stays Draft after AI placement — agent reviews and adjusts before prepare
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- teressa-copeland-homes/src/app/api/documents/[id]/ai-prepare/route.ts
|
||||||
|
modified: []
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "OPENAI_API_KEY checked in route handler (503) AND in classifyFieldsWithAI (throws) — belt-and-suspenders; route guard is more user-friendly (503 vs unhandled throw)"
|
||||||
|
- "try/catch wraps both extractPdfText and classifyFieldsWithAI — single error boundary returns 500 with message string; avoids uncaught exception"
|
||||||
|
- "Document status intentionally stays Draft after AI placement — agent must review fields before prepare/send"
|
||||||
|
- "Path traversal guard placed before AI calls — fail fast without expensive PDF extraction on invalid paths"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Pattern: OPENAI_API_KEY guard at top of route (503) before any DB queries or AI calls"
|
||||||
|
- "Pattern: Drizzle with: { client: true } in ai-prepare query mirrors prepare/route.ts pattern for consistent client data access"
|
||||||
|
|
||||||
|
requirements-completed: [AI-01, AI-02]
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 2min
|
||||||
|
completed: 2026-03-21
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 13 Plan 02: AI Prepare Route Summary
|
||||||
|
|
||||||
|
**Next.js App Router POST route orchestrating extract-text + GPT-4o-mini field classification with full guard chain (auth/API key/not-found/Draft-only/path-traversal), writing AI-placed SignatureFieldData[] to DB**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 2 min
|
||||||
|
- **Started:** 2026-03-21T23:03:17Z
|
||||||
|
- **Completed:** 2026-03-21T23:05:00Z
|
||||||
|
- **Tasks:** 1
|
||||||
|
- **Files modified:** 1
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- Created POST /api/documents/[id]/ai-prepare with complete guard chain: 401 (unauth), 503 (no API key), 404 (not found), 422 (no file), 403 (non-Draft or path traversal)
|
||||||
|
- Route loads document with client relation via Drizzle `with: { client: true }` — single DB round-trip for both document and client profile
|
||||||
|
- AI pipeline (extractPdfText + classifyFieldsWithAI) wrapped in try/catch returning 500 with error message on failure
|
||||||
|
- Writes AI-placed fields to DB `signatureFields` column; document status stays Draft for agent review
|
||||||
|
- Returns `{ fields: SignatureFieldData[], textFillData: Record<string, string> }` — client uses this to update FieldPlacer and pre-fill state
|
||||||
|
- TypeScript compiles clean with zero errors
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: Create POST /api/documents/[id]/ai-prepare route** - `e91f29e` (feat)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `teressa-copeland-homes/src/app/api/documents/[id]/ai-prepare/route.ts` - Full AI placement pipeline orchestration: auth guard, API key guard, document load with client relation, Draft-only guard, path traversal guard, extractPdfText + classifyFieldsWithAI in try/catch, DB write, response
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- OPENAI_API_KEY guard in route returns 503 (not 500) — distinguishes misconfiguration from runtime error; more actionable for the agent
|
||||||
|
- try/catch wraps both extractPdfText and classifyFieldsWithAI together — single error boundary; either failing returns 500 with the error message string
|
||||||
|
- Path traversal guard placed before any AI calls so malformed paths fail fast without expensive PDF extraction
|
||||||
|
- Document status intentionally not changed by this route — agent must review and adjust AI-placed fields before using prepare/send workflow
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None - plan executed exactly as written.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
**OPENAI_API_KEY must be set in .env.local** before the AI auto-place feature works. Route returns 503 with `{ error: 'OPENAI_API_KEY not configured. Add it to .env.local.' }` if absent — surfaced clearly to the agent in the browser.
|
||||||
|
|
||||||
|
No other external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- POST /api/documents/[id]/ai-prepare is live and importable as an API endpoint
|
||||||
|
- Plan 03 will add the "AI Auto-Place" button to the FieldPlacer UI and wire the client-side state (fields + textFillData) to DocumentPageClient
|
||||||
|
- Plan 04 integration test will validate AI coordinate accuracy on real Utah REPC forms
|
||||||
|
- Blocker from STATE.md still active: AI coordinate accuracy on real Utah forms untested — integration test required before Phase 13 ships to production
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 13-ai-field-placement-and-pre-fill*
|
||||||
|
*Completed: 2026-03-21*
|
||||||
Reference in New Issue
Block a user