Commit Graph

224 Commits

Author SHA1 Message Date
Chandler Copeland
9f190b3fc8 docs(10-01): complete expanded field types palette plan — SUMMARY, STATE, ROADMAP, REQUIREMENTS
- Create 10-01-SUMMARY.md with decisions, deviations, and phase readiness
- Update STATE.md: phase 10 current position, 10-01 decisions recorded
- Update ROADMAP.md: phase 10 plan progress (1/3 plans complete)
- Update REQUIREMENTS.md: mark FIELD-03 complete
2026-03-21 12:52:13 -06:00
Chandler Copeland
9875c1a0af docs(10-02): complete type-branched field rendering and POST handler fix plan
- Create 10-02-SUMMARY.md with decisions, commits, and deviation docs
- Update STATE.md with decisions and metrics
- Update ROADMAP.md phase 10 progress (2/3 summaries)
- Mark FIELD-02 and FIELD-04 requirements complete
2026-03-21 12:51:42 -06:00
Chandler Copeland
d395d85ebb feat(10-02): fix POST handler — signable field filter and date stamping at sign time
- Add getFieldType to schema import
- Add PDFDocument, StandardFonts, rgb from @cantoo/pdf-lib for date stamping
- Add readFile, writeFile, unlink from node:fs/promises
- Hoist const now = new Date() to before step 8 (shared for date stamp + DB update)
- Step 8a: stamp signing date onto date fields in prepared PDF before embed
- Step 8b: filter signableFields to client-signature and initials only
- signaturesWithCoords now maps only signable fields (no 500 on text/checkbox/date)
- Update embedSignatureInPdf call to use dateStampedPath
- Fire-and-forget cleanup of temporary .datestamped.tmp file after embed
2026-03-21 12:50:21 -06:00
Chandler Copeland
1e92ca363a feat(10-01): update handleDragEnd and renderFields for typed field creation
- handleDragEnd: determine droppedType from active.id with validTypes set guard
- handleDragEnd: checkbox fields drop at 24x24pt; all other types drop at 144x36pt
- handleDragEnd: newField now includes type property set to droppedType
- renderFields: use getFieldType() + PALETTE_TOKENS lookup to get per-field color and label
- renderFields: border, background, and text color are now driven by fieldColor
- renderFields: resize handle corners use fieldColor instead of hardcoded blue
- renderFields: span displays fieldLabel instead of hardcoded 'Signature'
2026-03-21 12:50:18 -06:00
Chandler Copeland
4140c220b1 feat(10-01): parameterize DraggableToken and add four new palette tokens
- Add PALETTE_TOKENS array with 5 typed tokens (Signature/blue, Initials/purple, Checkbox/green, Date/amber, Text/slate)
- Update DraggableToken to accept id, label, color props with per-type styling
- Change isDraggingToken from boolean to string | null to track active token id
- Update onDragStart to record active.id instead of just true
- Replace single static token with PALETTE_TOKENS.map() in palette JSX
- Update DragOverlay ghost to show correct label, color, and checkbox-appropriate dimensions (24x24 vs 144x36)
2026-03-21 12:49:25 -06:00
Chandler Copeland
7510c8ee08 feat(10-02): type-branched field rendering in preparePdf()
- Add getFieldType import from @/lib/db/schema
- Replace single-variant blue loop with branched rendering per field type
- client-signature: unchanged blue rectangle + "Sign Here"
- initials: purple rectangle + "Initials" label
- checkbox: gray rectangle + X diagonal lines (embedded at prepare time)
- date: amber rectangle + "Date" label (actual date stamped at POST time)
- text: light gray rectangle, no label (visual marker only)
- agent-signature: skipped (no placeholder drawn)
2026-03-21 12:49:20 -06:00
Chandler Copeland
2205a7bce5 docs(10-expanded-field-types-end-to-end): create phase 10 plan
Three plans covering the full field type pipeline end-to-end:
- 10-01: FieldPlacer palette extension (5 typed tokens, per-type colors, typed DragOverlay)
- 10-02: preparePdf() type-branched rendering + POST route signable filter and date stamp
- 10-03: SigningPageClient initials capture + overlay suppression + human verification

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 12:45:25 -06:00
Chandler Copeland
fadfbb3fd7 docs(phase-10): research expanded field types end-to-end
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 12:38:49 -06:00
Chandler Copeland
d1e4979e1f docs(phase-9): complete phase execution 2026-03-21 12:32:39 -06:00
Chandler Copeland
27003af70f fix(09-01): bg-gray-100 on prepare panel, stack field name/value rows to fit narrow panel 2026-03-21 12:31:20 -06:00
Chandler Copeland
28a460e9cc fix(09-01): sticky prepare panel, bg-gray-50 background, max-height scroll 2026-03-21 12:29:01 -06:00
Chandler Copeland
a77a144f6f fix(09-01): fix hydration mismatch in TextFillForm — use useEffect for initialData seed 2026-03-21 12:27:09 -06:00
Chandler Copeland
a784e50e10 docs(09-01): complete client-property-address plan — SUMMARY, STATE, ROADMAP
- 09-01-SUMMARY.md created documenting all 3 tasks and 2 auto-fixed deviations
- STATE.md updated: Phase 9 complete, session continuity, two decisions added
- ROADMAP.md updated: Phase 9 marked Complete (1/1 plans)
- REQUIREMENTS.md: CLIENT-04 and CLIENT-05 marked complete
2026-03-21 12:22:12 -06:00
Chandler Copeland
11f2b80217 fix(09-01): fix propertyAddress pre-seed and polish PreparePanel text fill UI
- TextFillForm: add initialData prop; buildInitialRows seeds rows from
  pre-seeded data so propertyAddress row renders populated on mount
- PreparePanel: pass initialData={...} to TextFillForm so the lazy
  useState in PreparePanel correctly flows through to the visible UI
- TextFillForm: replace AcroForm jargon instruction with friendly copy
- TextFillForm: add Field name / Value column headers for clear layout
- TextFillForm: improve spacing (py-1.5), softer remove button (gray→red on hover)
- TypeScript: npx tsc --noEmit passes clean
2026-03-21 12:20:08 -06:00
Chandler Copeland
fa9981edd9 feat(09-01): UI layer — property address modal input, profile display, PreparePanel pre-seed
- ClientModal: add defaultPropertyAddress prop, property address input field after email
- ClientProfileClient: add propertyAddress to Props type, display address under email when non-null, pass defaultPropertyAddress to edit modal
- documents/[docId]/page.tsx: extend client select to include propertyAddress, pass as clientPropertyAddress to PreparePanel
- PreparePanel: add clientPropertyAddress prop, lazy-initialize textFillData with { propertyAddress } when client has address
2026-03-21 12:15:27 -06:00
Chandler Copeland
baa1c785a5 feat(09-01): add property_address column to clients — schema, migration, server actions
- Add propertyAddress: text("property_address") nullable column to clients pgTable
- Generate migration drizzle/0007_equal_nekra.sql: ALTER TABLE "clients" ADD COLUMN "property_address" text
- Apply migration successfully to local postgres database
- Extend clientSchema Zod schema with propertyAddress: z.string().optional()
- createClient: persist propertyAddress || null to coerce empty string to NULL
- updateClient: persist propertyAddress || null alongside name, email, updatedAt
2026-03-21 12:13:55 -06:00
Chandler Copeland
569dc0fc97 docs(09-client-property-address): create phase plan 2026-03-21 12:09:21 -06:00
Chandler Copeland
b37cba4030 docs(09): research phase client-property-address 2026-03-21 12:05:08 -06:00
Chandler Copeland
fbf9e0aa98 docs(phase-08): complete phase execution 2026-03-21 12:00:27 -06:00
Chandler Copeland
0cfe0d9e7a docs(08-02): complete signing page safety plan — Phase 8 fully done
- 08-02-SUMMARY.md: server-side filter + type-branching guards documented
- STATE.md: position advanced to Phase 9, decisions recorded, progress 62%
- ROADMAP.md: Phase 8 marked Complete (2/2 plans)
- REQUIREMENTS.md: FIELD-01 marked complete

Phase 8 ships atomically: schema discriminant (08-01) + boundary enforcement (08-02)
2026-03-21 11:56:15 -06:00
Chandler Copeland
0db26db5d8 docs(08-02): human verification approved — Phase 8 safety gate confirmed
- TypeScript compiles clean across the project
- Server-side agent-signature filter verified in GET /api/sign/[token]
- Client-side type guards verified in SigningPageClient.tsx
- Backward compatibility confirmed: v1.0 signing sessions unaffected
- Phase 8 ships atomically: schema foundation + signing page safety active
2026-03-21 11:54:28 -06:00
Chandler Copeland
06e477b455 feat(08-02): add type-branching guards to SigningPageClient
- Import getFieldType from @/lib/db/schema
- handleFieldClick returns early for non-client-signature fields (defense-in-depth)
- handleSubmit counts only client-signature fields for completeness check
- SigningProgressBar total reflects client-signature count only
- signatureFields added to handleFieldClick and handleSubmit dependency arrays
2026-03-21 11:52:09 -06:00
Chandler Copeland
ea3365feb4 feat(08-02): add isClientVisibleField server-side filter to GET /api/sign/[token]
- Import isClientVisibleField from @/lib/db/schema
- Filter signatureFields in GET response to exclude agent-signature fields
- POST handler untouched — reads signatureFields from DB directly
2026-03-21 11:51:30 -06:00
Chandler Copeland
2468fdb21c docs(08-01): complete schema foundation plan — SignatureFieldType discriminant
- Create 08-01-SUMMARY.md with full task documentation and deviation notes
- Update STATE.md: plan 1 of 2 complete, decisions recorded, session updated
- Update ROADMAP.md: phase 8 progress 1/2, 08-01-PLAN.md marked complete
2026-03-21 11:50:09 -06:00
Chandler Copeland
b5f8b62dc5 chore(08-01): add Drizzle migration snapshot for TypeScript-only schema change
- Create drizzle/0006_type_discriminant.sql (empty SQL - no DDL required)
- Create drizzle/meta/0006_snapshot.json (identical DDL state to 0005)
- Update drizzle/meta/_journal.json to include 0006_type_discriminant entry
- Note: db:migrate skipped (DB unavailable); migration is a no-op placeholder
2026-03-21 11:48:22 -06:00
Chandler Copeland
2dd1b6101f feat(08-01): extend SignatureFieldData with type discriminant and helper exports
- Add SignatureFieldType union type with 6 literals (client-signature, initials, text, checkbox, date, agent-signature)
- Add optional type field to SignatureFieldData interface (backward-compat; v1.0 docs have no type)
- Export getFieldType() helper that coalesces field.type ?? 'client-signature'
- Export isClientVisibleField() predicate that returns false for agent-signature only
2026-03-21 11:46:49 -06:00
Chandler Copeland
dbd217b2e2 docs(08): create phase 8 plan files 2026-03-21 11:43:42 -06:00
Chandler Copeland
4a9a6a18f5 docs(08): research phase 8 schema foundation and signing page safety
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 11:39:27 -06:00
Chandler Copeland
fad91366a5 docs: create milestone v1.1 roadmap (6 phases) 2026-03-21 11:33:52 -06:00
Chandler Copeland
e36c6c8ee2 docs: complete project research 2026-03-21 11:28:42 -06:00
Chandler Copeland
8c69deeb68 docs: start milestone v1.1 smart-document-preparation 2026-03-21 11:15:06 -06:00
Chandler Copeland
5f2507a69e docs(phase-7): complete phase execution and verification 2026-03-21 11:02:37 -06:00
Chandler Copeland
d910288e42 docs(07-04): complete LEGAL-03 gap closure plan — SUMMARY, STATE, ROADMAP updated
- 07-04-SUMMARY.md: plan execution documented
- STATE.md: position advanced to 07-04 complete, decisions added, metrics recorded
- ROADMAP.md: phase 7 progress updated (4/4 plans)
2026-03-21 10:57:03 -06:00
Chandler Copeland
cac5d5bbb6 fix(07-04): hide Download anchor in PdfViewer for Signed documents (LEGAL-03)
- Wrap Download anchor in conditional: only rendered when docStatus !== 'Signed'
- PDF viewer still loads original via /file for in-browser display regardless of status
- PreparePanel presigned URL remains sole download path for signed PDFs
2026-03-21 10:54:43 -06:00
Chandler Copeland
6775cc76eb fix(07-04): restrict /file route to original PDF only (LEGAL-03)
- Remove signedFilePath fallback from /file route
- Route now always serves doc.filePath (unsigned original)
- Signed PDF exclusively available via presigned /download?adt=[token]
2026-03-21 10:53:56 -06:00
Chandler Copeland
6239a30bfd docs(07-audit-trail-and-download): create gap closure plan 07-04 for LEGAL-03 2026-03-21 10:52:53 -06:00
Chandler Copeland
3ac1d1e1ea docs(07): add verification report — gaps found 2026-03-21 10:50:40 -06:00
Chandler Copeland
e942a28247 docs(07-03): complete Phase 7 browser verification — Phase 7 complete
- Created 07-03-SUMMARY.md: human verification checkpoint approved
- STATE.md: Phase 7 marked complete (3/3 plans), all 4 criteria verified
- ROADMAP.md: Phase 7 status updated to Complete (3/3 plans)
- SIGN-07 and LEGAL-03 confirmed working end-to-end in live browser

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 10:46:26 -06:00
Chandler Copeland
86ca6dce85 docs(07-02): complete download UI wiring plan — SUMMARY, STATE, ROADMAP updated
- 07-02-SUMMARY.md: documents PreparePanel Signed panel, agentDownloadUrl server-side generation, Date Signed column, and auto-fix of ClientProfileClient type mismatch
- STATE.md: advanced to Phase 7 plan 2 of 3, added 3 key decisions, logged metrics row
- ROADMAP.md: updated phase 7 progress (2/3 plans complete)
2026-03-21 10:40:46 -06:00
Chandler Copeland
68d94a779f feat(07-02): wire agentDownloadUrl to doc detail page, add signedAt to dashboard and client profile
- document detail page: import createAgentDownloadToken, generate agentDownloadUrl server-side for
  signed docs (signedFilePath present), pass agentDownloadUrl and signedAt props to PreparePanel
- DocumentsTable: add signedAt to DocumentRow type, add Date Signed column header and cell
- dashboard page: add signedAt to db select so allRows includes signed date for Signed documents
- ClientProfileClient: add signedAt to local DocumentRow type (fixes type mismatch with DocumentsTable)
- clients/[id]/page: add signedAt to query select to satisfy updated DocumentRow type
2026-03-21 10:39:03 -06:00
Chandler Copeland
b823ae5c58 feat(07-02): extend PreparePanel with agentDownloadUrl/signedAt props and Signed download section
- Added agentDownloadUrl and signedAt to PreparePanelProps interface (optional, nullable)
- Destructure new props in function signature
- Added Signed status branch: green panel with signed timestamp and Download Signed PDF anchor
- Kept Sent/Viewed branch: gray read-only message
- Draft status: existing prepare form unchanged
- Download is a plain <a href> anchor — no fetch/onClick; browser follows link directly
2026-03-21 10:37:37 -06:00
Chandler Copeland
36069cb1ef docs(07-01): complete agent download token and route plan
- 07-01-SUMMARY.md: execution summary with decisions and file references
- STATE.md: position updated to Phase 7 Plan 1 complete; two decisions logged
- ROADMAP.md: Phase 7 progress updated (1/3 plans complete)
- REQUIREMENTS.md: SIGN-07 and LEGAL-03 marked complete
2026-03-21 10:36:19 -06:00
Chandler Copeland
ebc47ae954 feat(07-01): create GET /api/documents/[id]/download agent download route
- Streams signed PDF via short-lived agent-download JWT (adt query param)
- Returns 401 for missing/expired token, 403 for ID mismatch or path traversal
- Returns 404 for unsigned documents or missing files on disk
- Path traversal guard: absPath.startsWith(UPLOADS_DIR) before readFile
- Token/route ID cross-check: documentId !== id returns 403
- new Uint8Array(fileBuffer) for Next.js 16 TypeScript strict mode compatibility
2026-03-21 10:34:43 -06:00
Chandler Copeland
cd4cb75b60 feat(07-01): add createAgentDownloadToken and verifyAgentDownloadToken
- Appends two new exports to token.ts (existing exports untouched)
- purpose: 'agent-download', 5-min TTL, no DB record
- Mirrors existing createDownloadToken/verifyDownloadToken pattern
2026-03-21 10:33:53 -06:00
Chandler Copeland
9fe7936304 docs(07-audit-trail-and-download): create phase 7 plan
3 plans in 3 sequential waves: agent download token + API route (01),
UI wiring for download button + signedAt column (02), human verification
checkpoint (03). Covers SIGN-07 and LEGAL-03.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 10:30:05 -06:00
Chandler Copeland
45f49ce498 docs(07): research phase audit-trail-and-download 2026-03-21 10:24:17 -06:00
Chandler Copeland
cf877d7443 wip: 06-signing-flow paused at post-execution bug fixes 2026-03-21 10:16:06 -06:00
Chandler Copeland
bf6d361973 fix(06): log audit events and set Viewed status in signing page server component 2026-03-21 10:15:16 -06:00
Chandler Copeland
1171b2fa86 fix(06): update status to Viewed on link open; serve signedFilePath in agent portal after signing 2026-03-21 10:01:46 -06:00
Chandler Copeland
5aef96786a fix(06): wire /send route after /prepare in PreparePanel — signing email was never being sent 2026-03-21 09:53:38 -06:00