docs: create milestone v1.1 roadmap (6 phases)

This commit is contained in:
Chandler Copeland
2026-03-21 11:33:52 -06:00
parent e36c6c8ee2
commit fad91366a5
3 changed files with 198 additions and 157 deletions

View File

@@ -166,12 +166,27 @@ Which phases cover which requirements. Updated during roadmap creation.
| LEGAL-04 | Phase 6 | Complete | | LEGAL-04 | Phase 6 | Complete |
| SIGN-07 | Phase 7 | Complete | | SIGN-07 | Phase 7 | Complete |
| LEGAL-03 | Phase 7 | Complete | | LEGAL-03 | Phase 7 | Complete |
| FIELD-01 | Phase 8 | Pending |
| CLIENT-04 | Phase 9 | Pending |
| CLIENT-05 | Phase 9 | Pending |
| FIELD-01 | Phase 10 | Pending |
| FIELD-02 | Phase 10 | Pending |
| FIELD-03 | Phase 10 | Pending |
| FIELD-04 | Phase 10 | Pending |
| AGENT-01 | Phase 11 | Pending |
| AGENT-02 | Phase 11 | Pending |
| AGENT-03 | Phase 11 | Pending |
| AGENT-04 | Phase 11 | Pending |
| PREV-01 | Phase 12 | Pending |
| AI-01 | Phase 13 | Pending |
| AI-02 | Phase 13 | Pending |
**Coverage:** **Coverage:**
- v1 requirements: 28 total - v1.0 requirements: 28 total — mapped to phases 1-7 — all Complete
- Mapped to phases: 28 - v1.1 requirements: 13 total — mapped to phases 8-13 — all Pending
- Total mapped: 41
- Unmapped: 0 - Unmapped: 0
--- ---
*Requirements defined: 2026-03-19* *Requirements defined: 2026-03-19*
*Last updated: 2026-03-19 after roadmap creation* *Last updated: 2026-03-21 after v1.1 roadmap creation (phases 8-13)*

View File

@@ -4,6 +4,13 @@
A dual-product build: a public real estate marketing site for a solo Utah agent and a private document-signing portal that replaces per-month third-party tools with a fully branded, custom implementation. The build proceeds in dependency order — foundation first, then independent public site, then the agent portal in three layers (shell, PDF ingest, PDF fill), then the signing ceremony as a complete vertical slice, then the final visibility and download layer. Every phase delivers a coherent, verifiable capability. The legally critical components (audit trail, one-time tokens, tamper-evident hash) are woven into Phase 6 from the start — they cannot be retrofitted. A dual-product build: a public real estate marketing site for a solo Utah agent and a private document-signing portal that replaces per-month third-party tools with a fully branded, custom implementation. The build proceeds in dependency order — foundation first, then independent public site, then the agent portal in three layers (shell, PDF ingest, PDF fill), then the signing ceremony as a complete vertical slice, then the final visibility and download layer. Every phase delivers a coherent, verifiable capability. The legally critical components (audit trail, one-time tokens, tamper-evident hash) are woven into Phase 6 from the start — they cannot be retrofitted.
v1.1 extends the platform with AI-assisted field placement, expanded field types (text, checkbox, initials, date, agent signature), agent saved signature with draw-once-reuse workflow, and a filled document preview before sending.
## Milestones
-**v1.0 Core Document Signing Platform** - Phases 1-7 (shipped 2026-03-21)
- 🚧 **v1.1 Smart Document Preparation** - Phases 8-13 (in progress)
## Phases ## Phases
**Phase Numbering:** **Phase Numbering:**
@@ -12,16 +19,17 @@ A dual-product build: a public real estate marketing site for a solo Utah agent
Decimal phases appear between their surrounding integers in numeric order. Decimal phases appear between their surrounding integers in numeric order.
<details>
<summary>✅ v1.0 Core Document Signing Platform (Phases 1-7) — SHIPPED 2026-03-21</summary>
- [x] **Phase 1: Foundation** - Next.js project, local PostgreSQL database schema, and single-agent authentication (local dev; eventual home Docker server) (completed 2026-03-19) - [x] **Phase 1: Foundation** - Next.js project, local PostgreSQL database schema, and single-agent authentication (local dev; eventual home Docker server) (completed 2026-03-19)
- [ ] **Phase 2: Marketing Site** - Public-facing hero, bio, contact form, testimonials, and listings placeholder - [x] **Phase 2: Marketing Site** - Public-facing hero, bio, contact form, testimonials, and listings placeholder
- [x] **Phase 3: Agent Portal Shell** - Client management (create/view/profile) and dashboard skeleton with document status (completed 2026-03-19) - [x] **Phase 3: Agent Portal Shell** - Client management (create/view/profile) and dashboard skeleton with document status (completed 2026-03-19)
- [x] **Phase 4: PDF Ingest** - Agent PDF upload, local file storage pipeline, browser rendering, and document record creation (completed 2026-03-20) - [x] **Phase 4: PDF Ingest** - Agent PDF upload, local file storage pipeline, browser rendering, and document record creation (completed 2026-03-20)
- [ ] **Phase 5: PDF Fill and Field Mapping** - Drag-and-drop signature field placement, coordinate conversion, and agent text fill - [x] **Phase 5: PDF Fill and Field Mapping** - Drag-and-drop signature field placement, coordinate conversion, and agent text fill
- [x] **Phase 6: Signing Flow** - Complete end-to-end signing ceremony with legal compliance: email delivery, signing page, canvas capture, audit trail (completed 2026-03-21) - [x] **Phase 6: Signing Flow** - Complete end-to-end signing ceremony with legal compliance: email delivery, signing page, canvas capture, audit trail (completed 2026-03-21)
- [x] **Phase 7: Audit Trail and Download** - Secure signed PDF download, document status tracking, and client-facing confirmation screen (completed 2026-03-21) - [x] **Phase 7: Audit Trail and Download** - Secure signed PDF download, document status tracking, and client-facing confirmation screen (completed 2026-03-21)
## Phase Details
### Phase 1: Foundation ### Phase 1: Foundation
**Goal**: Agent can log in, reach the portal, and the infrastructure that every subsequent phase depends on is in place **Goal**: Agent can log in, reach the portal, and the infrastructure that every subsequent phase depends on is in place
**Depends on**: Nothing (first phase) **Depends on**: Nothing (first phase)
@@ -35,9 +43,9 @@ Decimal phases appear between their surrounding integers in numeric order.
**Plans**: 3 plans **Plans**: 3 plans
Plans: Plans:
- [ ] 01-01-PLAN.md — Next.js scaffold, Drizzle schema, Auth.js v5 config, route-protection middleware, seed script - [x] 01-01-PLAN.md — Next.js scaffold, Drizzle schema, Auth.js v5 config, route-protection middleware, seed script
- [ ] 01-02-PLAN.md — Branded login page, agent portal layout, dashboard stub, logout mechanism - [x] 01-02-PLAN.md — Branded login page, agent portal layout, dashboard stub, logout mechanism
- [ ] 01-03-PLAN.md — Local environment setup (.env.local, db:migrate, db:seed) and local auth flow verification (checkpoint) - [x] 01-03-PLAN.md — Local environment setup (.env.local, db:migrate, db:seed) and local auth flow verification (checkpoint)
### Phase 2: Marketing Site ### Phase 2: Marketing Site
**Goal**: Visitors can find Teressa online, see her brand, view the listings placeholder, and submit a contact inquiry **Goal**: Visitors can find Teressa online, see her brand, view the listings placeholder, and submit a contact inquiry
@@ -51,9 +59,9 @@ Plans:
**Plans**: 3 plans **Plans**: 3 plans
Plans: Plans:
- [ ] 02-01-PLAN.md — Static page shell: sticky nav, split-panel hero, testimonials carousel, listings placeholder, footer - [x] 02-01-PLAN.md — Static page shell: sticky nav, split-panel hero, testimonials carousel, listings placeholder, footer
- [ ] 02-02-PLAN.md — Contact form: Nodemailer SMTP mailer, server action with Zod + honeypot, ContactSection client component - [x] 02-02-PLAN.md — Contact form: Nodemailer SMTP mailer, server action with Zod + honeypot, ContactSection client component
- [ ] 02-03-PLAN.md — Human verification checkpoint: full homepage review across all four MKTG requirements - [x] 02-03-PLAN.md — Human verification checkpoint: full homepage review across all four MKTG requirements
### Phase 3: Agent Portal Shell ### Phase 3: Agent Portal Shell
**Goal**: Agent can manage clients and see all documents with their current status at a glance **Goal**: Agent can manage clients and see all documents with their current status at a glance
@@ -84,10 +92,10 @@ Plans:
**Plans**: 4 plans **Plans**: 4 plans
Plans: Plans:
- [ ] 04-01-PLAN.md — Schema (form_templates + documents columns), migration, seed script - [x] 04-01-PLAN.md — Schema (form_templates + documents columns), migration, seed script
- [ ] 04-02-PLAN.md — API routes: forms-library, documents POST, documents/[id]/file - [x] 04-02-PLAN.md — API routes: forms-library, documents POST, documents/[id]/file
- [ ] 04-03-PLAN.md — Add Document modal, PDF viewer page, react-pdf install - [x] 04-03-PLAN.md — Add Document modal, PDF viewer page, react-pdf install
- [ ] 04-04-PLAN.md — Full Phase 4 human verification checkpoint - [x] 04-04-PLAN.md — Full Phase 4 human verification checkpoint
### Phase 5: PDF Fill and Field Mapping ### Phase 5: PDF Fill and Field Mapping
**Goal**: Agent can place signature fields on any page of a PDF and fill in client/property text fields before sending **Goal**: Agent can place signature fields on any page of a PDF and fill in client/property text fields before sending
@@ -102,9 +110,9 @@ Plans:
Plans: Plans:
- [x] 05-01-PLAN.md — Schema extension (signatureFields, textFillData, assignedClientId, preparedFilePath JSONB columns), migration 0003, @cantoo/pdf-lib prepare utility, GET/PUT /api/documents/[id]/fields, POST /api/documents/[id]/prepare - [x] 05-01-PLAN.md — Schema extension (signatureFields, textFillData, assignedClientId, preparedFilePath JSONB columns), migration 0003, @cantoo/pdf-lib prepare utility, GET/PUT /api/documents/[id]/fields, POST /api/documents/[id]/prepare
- [ ] 05-02-PLAN.md — dnd-kit FieldPlacer component: drag-and-drop signature field placement, Y-axis coordinate conversion, blue rectangle overlay, field persistence - [x] 05-02-PLAN.md — dnd-kit FieldPlacer component: drag-and-drop signature field placement, Y-axis coordinate conversion, blue rectangle overlay, field persistence
- [ ] 05-03-PLAN.md — TextFillForm + PreparePanel: key-value text fill form, client selector dropdown, Prepare and Send workflow - [x] 05-03-PLAN.md — TextFillForm + PreparePanel: key-value text fill form, client selector dropdown, Prepare and Send workflow
- [ ] 05-04-PLAN.md — Full Phase 5 human verification checkpoint - [x] 05-04-PLAN.md — Full Phase 5 human verification checkpoint
### Phase 6: Signing Flow ### Phase 6: Signing Flow
**Goal**: Client receives an email link, opens the prepared PDF in any browser, draws a signature, and the signed document is stored with a complete, legally defensible audit trail **Goal**: Client receives an email link, opens the prepared PDF in any browser, draws a signature, and the signed document is stored with a complete, legally defensible audit trail
@@ -123,10 +131,10 @@ Plans:
Plans: Plans:
- [x] 06-01-PLAN.md — Schema migration 0005 (signingTokens + auditEvents tables + 3 documents columns), signing utility library (token.ts, audit.ts, embed-signature.ts), npm install signature_pad + @react-email - [x] 06-01-PLAN.md — Schema migration 0005 (signingTokens + auditEvents tables + 3 documents columns), signing utility library (token.ts, audit.ts, embed-signature.ts), npm install signature_pad + @react-email
- [ ] 06-02-PLAN.md — Branded signing request email (React Email), signing-mailer utilities, POST /api/documents/[id]/send route, document_prepared audit logging in prepare route - [x] 06-02-PLAN.md — Branded signing request email (React Email), signing-mailer utilities, POST /api/documents/[id]/send route, document_prepared audit logging in prepare route
- [ ] 06-03-PLAN.md — Public /sign/[token] page (3 states: signing/already-signed/expired), react-pdf viewer with pulsing blue field overlays, sticky progress bar, GET /api/sign/[token] data route - [x] 06-03-PLAN.md — Public /sign/[token] page (3 states: signing/already-signed/expired), react-pdf viewer with pulsing blue field overlays, sticky progress bar, GET /api/sign/[token] data route
- [ ] 06-04-PLAN.md — SignatureModal (Draw/Type/Use Saved tabs, signature_pad with devicePixelRatio scaling), POST /api/sign/[token] with atomic usedAt enforcement, PDF embedding, SHA-256 hash - [x] 06-04-PLAN.md — SignatureModal (Draw/Type/Use Saved tabs, signature_pad with devicePixelRatio scaling), POST /api/sign/[token] with atomic usedAt enforcement, PDF embedding, SHA-256 hash
- [ ] 06-05-PLAN.md — Confirmation page (/sign/[token]/confirmed), 15-min client download token, GET /api/sign/[token]/download route - [x] 06-05-PLAN.md — Confirmation page (/sign/[token]/confirmed), 15-min client download token, GET /api/sign/[token]/download route
- [x] 06-06-PLAN.md — DNS (SPF/DKIM/DMARC) verification checkpoint (LEGAL-04 gate) - [x] 06-06-PLAN.md — DNS (SPF/DKIM/DMARC) verification checkpoint (LEGAL-04 gate)
### Phase 7: Audit Trail and Download ### Phase 7: Audit Trail and Download
@@ -140,21 +148,134 @@ Plans:
**Plans**: 3 plans **Plans**: 3 plans
Plans: Plans:
- [ ] 07-01-PLAN.md — Agent download token utilities (createAgentDownloadToken/verifyAgentDownloadToken in token.ts) + GET /api/documents/[id]/download route with 5-min presigned JWT and path traversal guard - [x] 07-01-PLAN.md — Agent download token utilities (createAgentDownloadToken/verifyAgentDownloadToken in token.ts) + GET /api/documents/[id]/download route with 5-min presigned JWT and path traversal guard
- [ ] 07-02-PLAN.md — PreparePanel Signed-state panel with Download button, document detail page server-side token generation, DocumentsTable Date Signed column, dashboard signedAt select - [x] 07-02-PLAN.md — PreparePanel Signed-state panel with Download button, document detail page server-side token generation, DocumentsTable Date Signed column, dashboard signedAt select
- [x] 07-03-PLAN.md — Full Phase 7 human verification checkpoint (SIGN-07 + LEGAL-03) - [x] 07-03-PLAN.md — Full Phase 7 human verification checkpoint (SIGN-07 + LEGAL-03)
</details>
### 🚧 v1.1 Smart Document Preparation (In Progress)
**Milestone Goal:** Teressa can have AI auto-place and pre-fill all document fields with one click, sign as agent before sending, and preview the fully-prepared document before it reaches the client.
- [ ] **Phase 8: Schema Foundation and Signing Page Safety** - Add type discriminant to SignatureFieldData JSONB and harden signing page — safety gate before any new field type ships
- [ ] **Phase 9: Client Property Address** - Add property address to client profiles for AI pre-fill data sourcing
- [ ] **Phase 10: Expanded Field Types End-to-End** - All new field types (text, checkbox, initials, date) available in field mapper UI and embedded correctly by the prepare pipeline
- [ ] **Phase 11: Agent Saved Signature and Signing Workflow** - Draw once, save, apply to agent signature fields during document preparation before sending to client
- [ ] **Phase 12: Filled Document Preview** - Agent sees a live filled preview of the fully-prepared document before the Send button is available
- [ ] **Phase 13: AI Field Placement and Pre-fill** - One-click AI auto-placement of all field types plus pre-fill of text fields from client profile data
## Phase Details
### Phase 8: Schema Foundation and Signing Page Safety
**Goal**: The codebase is safe to receive new field types — SignatureFieldData carries a type discriminant, the signing page filters by type atomically, and agent-signature fields can never surface to clients as required unsigned fields
**Depends on**: Phase 7
**Requirements**: FIELD-01
**Success Criteria** (what must be TRUE):
1. `SignatureFieldData` schema has a `type` discriminant field (`client-signature` | `initials` | `text` | `checkbox` | `date` | `agent-signature`) with backward-compatible fallback defaulting to `client-signature` for all v1.0 documents
2. `/api/sign/[token]` route filters `signatureFields` to client-visible types only — `agent-signature` fields are never returned to the signing page
3. `SigningPageClient.tsx` branches on field type and does not attempt to open the signature modal for non-client-signature types
4. Drizzle migration runs cleanly against the existing database with no data loss on existing documents
**Plans**: TBD
Plans:
- [ ] 08-01-PLAN.md — Discriminated union type extension in schema.ts, Drizzle migration, backward-compat fallback in all field-reading paths
- [ ] 08-02-PLAN.md — Signing page type filter (sign route line 88 + SigningPageClient.tsx type branching) + human verification checkpoint
### Phase 9: Client Property Address
**Goal**: Agent can store a property address on a client profile so it is available as structured data for AI pre-fill
**Depends on**: Phase 8
**Requirements**: CLIENT-04, CLIENT-05
**Success Criteria** (what must be TRUE):
1. Agent can add or edit a property address on any client profile from the portal
2. Property address is saved to the database and displayed on the client profile page
3. Property address is returned alongside client name when the prepare-document pipeline fetches client data (available as a pre-fill source)
**Plans**: TBD
Plans:
- [ ] 09-01-PLAN.md — DB migration (propertyAddress nullable TEXT on clients table), server action update, ClientModal form field, client profile display
### Phase 10: Expanded Field Types End-to-End
**Goal**: Agent can place text, checkbox, initials, and date field markers on any PDF and the prepared document embeds each type correctly
**Depends on**: Phase 8
**Requirements**: FIELD-01, FIELD-02, FIELD-03, FIELD-04
**Success Criteria** (what must be TRUE):
1. Agent can drag text, checkbox, initials, and date tokens from the FieldPlacer palette and place them on any page of a PDF
2. Prepared PDF embeds text fields as typed stamps, checkboxes as boolean marks, initials as placeholder markers, and date fields as auto-stamped signing-date values
3. Client signing page correctly handles initials fields (prompts for initials capture) and ignores text/checkbox/date fields (already embedded at prepare time)
4. A round-trip test (place all four types, prepare, open signing link) produces a correctly embedded PDF with no field type rendered in the wrong position
**Plans**: TBD
Plans:
- [ ] 10-01-PLAN.md — FieldPlacer palette: four new draggable tokens (text, checkbox, initials, date) with distinct visual affordances
- [ ] 10-02-PLAN.md — prepare-document.ts type-aware rendering switch: text stamp, checkbox embed, date auto-stamp, initials placeholder via @cantoo/pdf-lib
- [ ] 10-03-PLAN.md — Full Phase 10 human verification checkpoint (all four field types placed, prepared, and verified in PDF output)
### Phase 11: Agent Saved Signature and Signing Workflow
**Goal**: Agent draws a signature once, saves it to their profile, places agent signature fields on documents, and applies the saved signature during preparation — before the document is sent to the client
**Depends on**: Phase 10
**Requirements**: AGENT-01, AGENT-02, AGENT-03, AGENT-04
**Success Criteria** (what must be TRUE):
1. Agent can draw a signature on a canvas in the portal and save it to their account — a thumbnail of the saved signature is visible on the profile page
2. Agent can update (replace) their saved signature at any time
3. Agent can place agent signature field markers on a PDF from the FieldPlacer palette
4. When the agent prepares a document, their saved signature PNG is embedded at each agent-signature field coordinate — the field does not appear in the client signing session
**Plans**: TBD
Plans:
- [ ] 11-01-PLAN.md — DB migration (agentSignatureData TEXT on users table), GET/PUT /api/agent/signature routes, AgentSignaturePanel component (draw + save + thumbnail)
- [ ] 11-02-PLAN.md — FieldPlacer palette token for agent-signature type, prepare-document.ts PNG embed at agent-sig coordinates
- [ ] 11-03-PLAN.md — Full Phase 11 human verification checkpoint (draw, save, place, prepare, verify embedded in PDF + absent from client signing page)
### Phase 12: Filled Document Preview
**Goal**: Agent sees a live filled preview of the fully-prepared document — with all text, signatures, and field stamps embedded — before the Send button becomes available
**Depends on**: Phase 11
**Requirements**: PREV-01
**Success Criteria** (what must be TRUE):
1. A "Preview" button is available on the document prepare page and opens a modal showing the fully-prepared PDF rendered with all embedded content
2. The Send button is disabled until the agent has generated at least one preview of the current field state
3. If the agent changes any fields after previewing, the Send button is re-disabled until a fresh preview is generated (staleness detection)
4. The preview PDF uses a versioned path and does not overwrite the final prepared PDF (legal integrity of prepared document is preserved)
**Plans**: TBD
Plans:
- [ ] 12-01-PLAN.md — POST /api/documents/[id]/preview route (reuses preparePdf in preview mode, versioned path, staleness token), PreviewModal component with react-pdf rendering + ArrayBuffer copy
- [ ] 12-02-PLAN.md — Send button gating logic (disabled until preview generated, re-disabled on field change) + full Phase 12 human verification checkpoint
### Phase 13: AI Field Placement and Pre-fill
**Goal**: Agent clicks one button and AI auto-places all field types on the PDF in correct positions and pre-fills text fields with known client and property data
**Depends on**: Phase 12
**Requirements**: AI-01, AI-02
**Success Criteria** (what must be TRUE):
1. Agent can click "AI Auto-place" and the system extracts text from the PDF, classifies field labels via GPT-4o-mini, and populates the FieldPlacer with placed fields — no manual drag required
2. AI-placed text fields are pre-filled with client name, property address, and signing date where those values are available from the client profile
3. AI placement produces correct field positions on a full 20-page Utah REPC — coordinates convert correctly from percentage-based AI output to PDF user-space points (Y-axis inversion verified by unit test)
4. Agent can review, adjust, or delete any AI-placed field before proceeding to prepare — AI placement is a starting point, not a lock
**Plans**: TBD
Plans:
- [ ] 13-01-PLAN.md — lib/ai/extract-text.ts (pdfjs-dist legacy build, server-only), lib/ai/field-placement.ts (GPT-4o-mini structured output, manual JSON schema, server-only guard), aiCoordsToPagePdfSpace() utility + unit test
- [ ] 13-02-PLAN.md — POST /api/documents/[id]/ai-prepare route (orchestrate extract + AI call + coordinate conversion + field write), "AI Auto-place" button in PreparePanel with loading state
- [ ] 13-03-PLAN.md — AI pre-fill: map client profile fields (name, property address, date) to placed text fields; agent review step before fields are committed
- [ ] 13-04-PLAN.md — Integration test with full 20-page Utah REPC + full Phase 13 human verification checkpoint
## Progress ## Progress
**Execution Order:** **Execution Order:**
Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 12 → 13
| Phase | Plans Complete | Status | Completed | | Phase | Milestone | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------| |-------|-----------|----------------|--------|-----------|
| 1. Foundation | 1/3 | Complete | 2026-03-19 | | 1. Foundation | v1.0 | 3/3 | Complete | 2026-03-19 |
| 2. Marketing Site | 2/3 | In Progress| | | 2. Marketing Site | v1.0 | 3/3 | Complete | 2026-03-21 |
| 3. Agent Portal Shell | 4/4 | Complete | 2026-03-19 | | 3. Agent Portal Shell | v1.0 | 4/4 | Complete | 2026-03-19 |
| 4. PDF Ingest | 4/4 | Complete | 2026-03-20 | | 4. PDF Ingest | v1.0 | 4/4 | Complete | 2026-03-20 |
| 5. PDF Fill and Field Mapping | 3/4 | In Progress| | | 5. PDF Fill and Field Mapping | v1.0 | 4/4 | Complete | 2026-03-21 |
| 6. Signing Flow | 6/6 | Complete | 2026-03-21 | | 6. Signing Flow | v1.0 | 6/6 | Complete | 2026-03-21 |
| 7. Audit Trail and Download | 4/4 | Complete | 2026-03-21 | | 7. Audit Trail and Download | v1.0 | 3/3 | Complete | 2026-03-21 |
| 8. Schema Foundation and Signing Page Safety | v1.1 | 0/2 | Not started | - |
| 9. Client Property Address | v1.1 | 0/1 | Not started | - |
| 10. Expanded Field Types End-to-End | v1.1 | 0/3 | Not started | - |
| 11. Agent Saved Signature and Signing Workflow | v1.1 | 0/3 | Not started | - |
| 12. Filled Document Preview | v1.1 | 0/2 | Not started | - |
| 13. AI Field Placement and Pre-fill | v1.1 | 0/4 | Not started | - |

View File

@@ -2,12 +2,12 @@
gsd_state_version: 1.0 gsd_state_version: 1.0
milestone: v1.1 milestone: v1.1
milestone_name: smart-document-preparation milestone_name: smart-document-preparation
status: unknown status: ready-to-plan
last_updated: "2026-03-21T17:02:31.470Z" last_updated: "2026-03-21"
progress: progress:
total_phases: 7 total_phases: 13
completed_phases: 7 completed_phases: 7
total_plans: 28 total_plans: 43
completed_plans: 28 completed_plans: 28
--- ---
@@ -15,141 +15,49 @@ progress:
## Project Reference ## Project Reference
See: .planning/PROJECT.md (updated 2026-03-19) See: .planning/PROJECT.md (updated 2026-03-21)
**Core value:** Teressa can prepare and send any real estate form to a client for signing in minutes, from her browser, without leaving her site. **Core value:** Teressa can prepare and send any real estate form to a client for signing in minutes, from her browser, without leaving her site.
**Current focus:** Phase 7 - Audit Trail and Download **Current focus:** Phase 8 — Schema Foundation and Signing Page Safety (v1.1 start)
## Current Position ## Current Position
Phase: Not started (defining requirements) Phase: 8 of 13 (Schema Foundation and Signing Page Safety)
Plan: Plan: 0 of 2 in current phase
Status: Defining requirements for v1.1 — Smart Document Preparation Status: Ready to plan
Last activity: 2026-03-21 — Milestone v1.1 started (13 requirements defined, roadmap pending) Last activity: 2026-03-21 — v1.1 roadmap created (phases 8-13 defined); v1.0 complete (phases 1-7 all shipped)
Progress: [░░░░░░░░░░] 0% (v1.1 not started) Progress: [███████░░░░░░] 54% (7/13 phases complete)
## Performance Metrics ## Performance Metrics
**Velocity:** **Velocity:**
- Total plans completed: 2 - Total plans completed: 28 (v1.0 complete)
- Average duration: 4 min - Average duration: ~4 min/plan
- Total execution time: 0.1 hours - Total execution time: ~2 hours
**By Phase:** **By Phase:**
| Phase | Plans | Total | Avg/Plan | | Phase | Plans | Avg/Plan |
|-------|-------|-------|----------| |-------|-------|----------|
| 01-foundation | 2/3 | 8 min | 4 min | | v1.0 phases 1-7 | 28 | ~4 min |
| 02-marketing-site | 2/3 | 8 min | 4 min |
**Recent Trend:** **Recent Trend:**
- Last 5 plans: 01-01 (6 min), 01-02 (2 min), 02-01 (4 min), 02-02 (4 min) - Trend: Stable
- Trend: stable
*Updated after each plan completion* *Updated after each plan completion*
| Phase 02-marketing-site P01 | 5 | 2 tasks | 8 files |
| Phase 03-agent-portal-shell P01 | 3 | 2 tasks | 6 files |
| Phase 03-agent-portal-shell P02 | 8 | 3 tasks | 5 files |
| Phase 03-agent-portal-shell P03 | 9 | 3 tasks | 7 files |
| Phase 03-agent-portal-shell P04 | 5 | 2 tasks | 3 files |
| Phase 04-pdf-ingest P01 | 8 | 2 tasks | 7 files |
| Phase 04-pdf-ingest P02 | 1 | 2 tasks | 3 files |
| Phase 04-pdf-ingest P04-03 | 5 | 2 tasks | 8 files |
| Phase 05-pdf-fill-and-field-mapping P02 | 1 | 2 tasks | 2 files |
| Phase 05-pdf-fill-and-field-mapping P03 | 3 | 2 tasks | 4 files |
| Phase 06-signing-flow P01 | 2 | 2 tasks | 8 files |
| Phase 06-signing-flow P02 | 2 | 2 tasks | 4 files |
| Phase 06-signing-flow P03 | 3 | 2 tasks | 6 files |
| Phase 06-signing-flow P04 | 7 | 2 tasks | 4 files |
| Phase 06-signing-flow P05 | 3 | 2 tasks | 4 files |
| Phase 06-signing-flow P06 | 2 | 2 tasks | 2 files |
| Phase 07-audit-trail-and-download P01 | 2 | 2 tasks | 2 files |
| Phase 07-audit-trail-and-download P02 | 2 | 2 tasks | 6 files |
| Phase 07-audit-trail-and-download P03 | 0 | 1 task (checkpoint) | 0 files |
| Phase 07-audit-trail-and-download P04 | 1 | 2 tasks | 2 files |
## Accumulated Context ## Accumulated Context
### Decisions ### Decisions
Decisions are logged in PROJECT.md Key Decisions table. Decisions are logged in PROJECT.md Key Decisions table.
Recent decisions affecting current work: Recent decisions affecting v1.1 work:
- Custom e-signature over DocuSign: lower ongoing cost for solo agent; full brand control - [v1.1 Research]: Use pdfjs-dist legacy build (already installed via react-pdf) for server-side PDF text extraction — no new dependency
- Next.js full-stack: single repo for marketing + web app via API routes - [v1.1 Research]: Use manual `json_schema` response_format for OpenAI — do NOT use `zodResponseFormat` (broken with Zod v4, confirmed issues #1540, #1602, #1709)
- Email-link signing (no client account): lowest friction for clients; standard in real estate - [v1.1 Research]: Agent signature stored as base64 PNG TEXT column on users table (2-8KB) — no new file storage needed
- utahrealestate.com forms scraping: AVOID — violates ToS; use manual PDF upload instead - [v1.1 Research]: Phase 8 must ship atomically (schema discriminant + signing page filter) before any new field type can be placed or sent
- Infrastructure: local PostgreSQL (Docker) + local `npm run dev`; no Vercel, no Neon, no cloud storage — home Docker server is eventual target
- [Phase 01-foundation]: Lazy Proxy singleton for db/index.ts prevents neon() crash during Next.js build when DATABASE_URL absent
- [Phase 01-foundation]: next-auth pinned to exact version 5.0.0-beta.30; middleware.ts at project root not src/; force-dynamic on auth route
- [Phase 01-foundation 01-02]: PasswordField extracted as co-located client sub-component — keeps login page.tsx as pure server component
- [Phase 01-foundation 01-02]: loginAction re-throws non-AuthError (NEXT_REDIRECT must bubble) — critical Auth.js v5 server action pattern
- [Phase 01-foundation 01-02]: Brand colors applied via inline style props — Tailwind JIT may miss one-off hex values
- [Phase 02-marketing-site]: CSS hover classes in server components — onMouseEnter/onMouseLeave not valid in server component props; use className with style blocks instead
- [Phase 02-marketing-site]: lucide-react installed for marketing site icons (Home, Menu, X, ChevronLeft, ChevronRight)
- [Phase 02-marketing-site 02-02]: nodemailer pinned to ^7.0.7 — v8 conflicts with next-auth@5.0.0-beta.30 peerOptional dep
- [Phase 02-marketing-site 02-02]: useActionState imported from 'react' not 'react-dom' — React 19 canonical API (useFormState removed in React 19)
- [Phase 02-marketing-site 02-02]: Honeypot silent success pattern — bots receive status:success without email sent, preventing bot discovery of rejection
- [Phase 03-agent-portal-shell]: documentStatusEnum exported before documents table in schema.ts — pgEnum must precede referencing table or drizzle-kit may omit CREATE TYPE from migration
- [Phase 03-agent-portal-shell]: Portal route protection: add new prefix to both middleware.ts matcher array AND auth.config.ts authorized callback isPortalRoute check — mirrors existing /agent pattern
- [Phase 03-agent-portal-shell]: Post-login redirect changed from /agent/dashboard to /portal/dashboard — agent portal lives at /portal prefix going forward
- [Phase 03-agent-portal-shell]: Zod v4 uses .issues not .errors for ZodError — updated plan-specified .errors[0].message to .issues[0].message in client server actions
- [Phase 03-agent-portal-shell]: updateClient uses bind pattern (id pre-bound) so useActionState passes prevState + formData as remaining args — caller does updateClient.bind(null, clientId)
- [Phase 03-agent-portal-shell]: PortalNav is a client component (usePathname requires use client); active link state driven by pathname.startsWith(href) with gold border-b-2 underline
- [Phase 03-agent-portal-shell]: DashboardFilters extracted to separate file — use client directive must be at file top in Next.js, cannot be inlined inside server component file
- [Phase 03-agent-portal-shell]: ClientsPageClient extracted to _components/ClientsPageClient.tsx for cleaner server/client split following project convention
- [Phase 03-agent-portal-shell]: Seed script requires DOTENV_CONFIG_PATH=.env.local — dotenv/config reads .env by default but project uses .env.local
- [Phase 03-agent-portal-shell 03-04]: ClientProfileClient extracted to _components/ClientProfileClient.tsx (not inlined) — consistent with project convention for client sub-components
- [Phase 03-agent-portal-shell 03-04]: deleteClient called directly from async event handler in client component — Next.js 15+ supports calling server actions as async functions without form wrappers
- [Phase 03-agent-portal-shell 03-04]: ConfirmDialog message constructed with client name inline — reusable with title + message string props, no JSX message needed
- [Phase 04-pdf-ingest 04-01]: formTemplates table uses text PK (crypto.randomUUID()) — consistent with all other tables in schema.ts
- [Phase 04-pdf-ingest 04-01]: formTemplateId and filePath are nullable — custom uploads have no template; legacy document rows need no file path
- [Phase 04-pdf-ingest 04-01]: seed:forms uses onConflictDoUpdate on filename — filename is natural unique key for idempotent monthly sync re-runs
- [Phase 04-pdf-ingest]: uploads/ at project root not under public/ — PDFs never accessible as static files
- [Phase 04-pdf-ingest]: Relative paths stored in DB (clients/{clientId}/{uuid}.pdf) — absolute paths would break on server move
- [Phase 04-pdf-ingest]: Path traversal guard on both write (POST) and read (GET /file) — prevents directory escape via malicious clientId or filePath
- [Phase 04-pdf-ingest]: react-pdf v9 requires transpilePackages in next.config.ts — ships as ESM, Next.js webpack must transpile
- [Phase 04-pdf-ingest]: pdfjs worker uses new URL(import.meta.url) pattern — no CDN URL; works in local/Docker environments without internet access
- [Phase 04-pdf-ingest]: documentsRelations added to schema.ts — required for Drizzle db.query relational API with-relations support
- [Phase 04-pdf-ingest 04-04]: Phase 4 declared complete after human agent verified all 7 browser verification steps pass — forms library, modal, PDF render, file storage, and auth guards confirmed working
- [Phase 05-pdf-fill-and-field-mapping 05-01]: @cantoo/pdf-lib used instead of pdf-lib — packages conflict; @cantoo is the maintained fork with same API
- [Phase 05-pdf-fill-and-field-mapping 05-01]: signatureFields and textFillData stored as JSONB in documents table — flexible schema for field arrays and key/value maps without additional tables
- [Phase 05-pdf-fill-and-field-mapping 05-01]: Atomic write (tmp → rename) for prepared PDFs — prevents corrupting source PDF on partial write failure
- [Phase 05-pdf-fill-and-field-mapping 05-01]: form.flatten() called BEFORE drawing signature rectangles — required order; if reversed, AcroForm overlay obscures drawn rectangles
- [Phase 05-pdf-fill-and-field-mapping 05-01]: jest + ts-jest chosen for unit tests — straightforward TypeScript test support without ESM complications for coordinate formula tests
- [Phase 05-pdf-fill-and-field-mapping 05-01]: Y-flip formula pdfY = ((renderedH - screenY) / renderedH) * originalHeight is scale-invariant — verified at 1:1 and 50% zoom in test suite
- [Phase 05-pdf-fill-and-field-mapping 05-02]: DragOverlay used for ghost rendering — avoids transform-based dragging which breaks coordinate math relative to droppable container
- [Phase 05-pdf-fill-and-field-mapping 05-02]: containerRef.getBoundingClientRect() called at drop time (not stale pageInfo.width) — captures current rendered size after zoom changes
- [Phase 05-pdf-fill-and-field-mapping 05-02]: activatorEvent + delta pattern for final drop coordinates — activatorEvent gives client position at drag start, delta gives displacement
- [Phase 05-pdf-fill-and-field-mapping 05-02]: top: top - heightPx on overlay divs — pdfToScreenCoords returns y of bottom-left corner; must shift up by field height for DOM top-left origin
- [Phase 05-pdf-fill-and-field-mapping]: PreparePanel canPrepare guard: only show prepare form for Draft status — read-only message for Sent/Signed
- [Phase 05-pdf-fill-and-field-mapping]: currentClientId defaults to doc.assignedClientId ?? doc.clientId — allows reassigning client before preparing
- [Phase 06-signing-flow 06-01]: SIGNING_JWT_SECRET uses real openssl rand -base64 32 value (not placeholder) — generated at plan execution time
- [Phase 06-signing-flow 06-01]: auditEventTypeEnum defined before auditEvents table in schema.ts — pgEnum must precede referencing table (established Phase 3 pattern)
- [Phase 06-signing-flow 06-01]: Signing utilities live in src/lib/signing/ — server-only, never import from client components
- [Phase 06-signing-flow 06-01]: JWT jti stored in signingTokens table on createSigningToken — enables one-time-use enforcement in later plans
- [Phase 06-signing-flow 06-01]: SHA-256 hash computed from disk after atomic rename — never from in-memory bytes (LEGAL-02)
- [Phase 06-signing-flow]: Sender address hardcoded as teressa@teressacopelandhomes.com — matches brand identity requirement in CONTEXT.md
- [Phase 06-signing-flow]: sendMail failure triggers 502 without DB status update — document stays in current state if email delivery fails
- [Phase 06-signing-flow]: Status update in send/route.ts guarded by status=Draft — prevents downgrading Sent/Signed documents
- [Phase 06-signing-flow]: SigningPageClientWrapper uses dynamic import (ssr:false) — react-pdf requires browser APIs that cannot run server-side
- [Phase 06-signing-flow]: PDF served via /api/sign/[token]/pdf (token-authenticated) not /api/documents/[id]/file (agent-authenticated) — signing page is public
- [Phase 06-signing-flow 06-04]: signedFields changed from Set<string> to Map<string,string> (fieldId->dataURL) to support signature preview image in signed overlays
- [Phase 06-signing-flow 06-04]: POST /api/sign/[token] atomic claim via Drizzle UPDATE...WHERE isNull(usedAt).returning() — 0 rows = 409, PDF never written on race condition
- [Phase 06-signing-flow 06-04]: /sign/[token]/confirmed is static server component — token already used at this point, no re-validation needed
- [Phase 06-signing-flow 06-04]: sendAgentNotificationEmail is fire-and-forget via .then().catch() — email failure must never prevent the signing confirmation from reaching the client
- [Phase 06-signing-flow 06-05]: Download token uses purpose:'download' claim with same SIGNING_JWT_SECRET — no DB record needed for 15-min ephemeral download authorization
- [Phase 06-signing-flow 06-05]: Buffer cast to Uint8Array for Response constructor BodyInit compatibility in Next.js 16 TypeScript strict mode
- [Phase 06-signing-flow 06-05]: router.push replaces window.location.href for confirmed page navigation — SPA navigation consistent with Next.js App Router patterns
- [Phase 07-audit-trail-and-download]: Agent download token uses same SIGNING_JWT_SECRET with purpose:'agent-download' claim; 5-min TTL; no DB record needed for ephemeral presigned download authorization
- [Phase 07-audit-trail-and-download]: Token documentId vs route [id] cross-check added as defense-in-depth: valid token for doc A cannot download doc B (403)
- [Phase 07-audit-trail-and-download 07-02]: agentDownloadUrl generated in server component (page.tsx) not in PreparePanel — PreparePanel is 'use client' and cannot call createAgentDownloadToken (server-only)
- [Phase 07-audit-trail-and-download 07-02]: Download button is a plain anchor tag — browser follows href directly, Content-Disposition:attachment header in API route drives save dialog
- [Phase 07-audit-trail-and-download 07-02]: signedAt added to both dashboard and client profile queries — all document tables show consistent Date Signed column
- [Phase 07-audit-trail-and-download 07-03]: Phase 7 declared complete after human confirmation of all 4 browser verification criteria — SIGN-07 and LEGAL-03 verified working end-to-end in live browser
- [Phase 07-audit-trail-and-download]: /file route reads doc.filePath only — signedFilePath fallback removed per LEGAL-03; presigned /download?adt=[token] is sole signed PDF download path
- [Phase 07-audit-trail-and-download]: PdfViewer Download anchor wrapped in {docStatus \!== 'Signed' && ...} — toolbar download hidden for Signed docs, PDF still loads via /file for in-browser display
### Pending Todos ### Pending Todos
@@ -157,14 +65,11 @@ None yet.
### Blockers/Concerns ### Blockers/Concerns
- WFRMLS vendor enrollment takes 2-4 weeks — start process immediately, build Phase 2 listings with mock data while waiting - [Phase 12]: Deployment target (Vercel serverless vs. self-hosted container) must be confirmed before implementing preview route — write-to-disk preview pattern silently fails on Vercel serverless (ephemeral filesystem)
- Phase 6 (Signing Flow) warrants a /gsd:research-phase before planning — JWT one-time enforcement + ESIGN/UETA audit + mobile touch has edge cases - [Phase 13]: AI coordinate accuracy on real Utah forms is untested — integration test with full 20-page Utah REPC required before Phase 13 ships
- DNS (SPF/DKIM/DMARC) for teressacopelandhomes.com must be configured before any signing link reaches a real client (Phase 6 acceptance criterion)
- Exact WFRMLS required IDX disclaimer text must be obtained directly from WFRMLS before listings feature ships (Phase 2)
- WFRMLS vendor enrollment takes 2-4 weeks — start process immediately, build Phase 2 listings with mock data while waiting (moved from Blockers)
## Session Continuity ## Session Continuity
Last session: 2026-03-21 Last session: 2026-03-21
Stopped at: Completed 07-04-PLAN.md — LEGAL-03 gap closure complete, all 28 plans done Stopped at: v1.1 roadmap created — ROADMAP.md, STATE.md, and REQUIREMENTS.md traceability updated; ready to plan Phase 8
Resume file: None Resume file: None