Files
Chandler Copeland 970bb4f7cf 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>
2026-03-21 17:05:37 -06:00

5.5 KiB

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