- 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
- 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
- Remove signedFilePath fallback from /file route
- Route now always serves doc.filePath (unsigned original)
- Signed PDF exclusively available via presigned /download?adt=[token]
- 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>
- 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)
- 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
- 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
- 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
- Appends two new exports to token.ts (existing exports untouched)
- purpose: 'agent-download', 5-min TTL, no DB record
- Mirrors existing createDownloadToken/verifyDownloadToken pattern
- SPF: MISSING — no TXT records at root domain
- DKIM: MISSING — NXDOMAIN for all common selectors
- DMARC: EXISTS but rua points to hosting default, not teressa@
- SMTP: credentials still placeholder in .env.local
- DNS provider: GoDaddy (ns63/ns64.domaincontrol.com)
- Add POST handler to sign/[token]/route.ts with atomic one-time enforcement
- UPDATE signing_tokens SET usedAt WHERE usedAt IS NULL RETURNING — 0 rows = 409
- Log signature_submitted and pdf_hash_computed audit events
- Merge client dataURLs with server-stored field coordinates (NEVER trust client coords)
- Call embedSignatureInPdf, store pdfHash + signedFilePath in documents table
- Update document status to Signed with signedAt timestamp
- Fire-and-forget sendAgentNotificationEmail (catches errors without failing response)
- Create /sign/[token]/confirmed success page for POST redirect destination
- Create SignatureModal.tsx with signature_pad Draw tab (devicePixelRatio scaling, touch-none)
- Type tab renders name in Dancing Script cursive via offscreen canvas
- Use Saved tab conditionally shown when localStorage has saved signature
- Save for later checkbox persists drawn/typed sig to localStorage on confirm
- Update SigningPageClient.tsx: import modal, track signedFields as Map<string,string>
- Field overlay shows signature preview image after signing
- handleSubmit POSTs to /api/sign/[token] and redirects to /sign/[token]/confirmed on 200
- 06-03-SUMMARY.md created with decisions, deviations, file list
- STATE.md advanced to Plan 3 complete; two new decisions recorded
- ROADMAP.md phase 6 updated to 3/6 summaries complete
- page.tsx: server component validates JWT + one-time-use before rendering any UI
- Three error states (expired/used/invalid) show static pages with no canvas
- SigningPageClientWrapper: dynamic import (ssr:false) for react-pdf browser requirement
- SigningPageClient: full-scroll PDF viewer with pulsing blue field overlays
- Field overlay coordinates convert PDF user-space (bottom-left) to screen (top-left)
- SigningProgressBar: sticky bottom bar with X/Y count + jump-to-next + submit button
- api/sign/[token]/pdf: token-authenticated PDF streaming route (no agent auth)
- Add send/route.ts: creates signing token, sends branded email, logs email_sent, updates status to Sent
- Auth guard returns 401 for unauthenticated requests; 422 if not prepared; 409 if already signed
- Wraps sendMail in try/catch — returns 502 without DB update if email delivery fails
- Add logAuditEvent(document_prepared) to prepare/route.ts after successful PDF preparation
- Validates JWT with verifySigningToken(); returns expired/invalid/used/pending
- Checks signingTokens.usedAt for one-time-use enforcement
- Logs link_opened + document_viewed audit events on valid pending access
- Extracts IP from x-forwarded-for/x-real-ip headers for audit trail
- Public route — no auth() import or session required
- created 06-01-SUMMARY.md with full task and decision documentation
- STATE.md: advanced to phase 6 plan 1, added 5 signing foundation decisions
- ROADMAP.md: marked 06-01-PLAN.md complete, Signing Flow at 1/6
- REQUIREMENTS.md: marked SIGN-02, LEGAL-01, LEGAL-02 complete