79 lines
3.6 KiB
Markdown
79 lines
3.6 KiB
Markdown
|
|
---
|
||
|
|
phase: 15-multi-signer-backend
|
||
|
|
plan: "01"
|
||
|
|
subsystem: signing
|
||
|
|
tags: [multi-signer, jwt, email, download-route]
|
||
|
|
dependency_graph:
|
||
|
|
requires: [14-multi-signer-schema]
|
||
|
|
provides: [signer-download-token, signer-completion-email, public-download-route]
|
||
|
|
affects: [15-02-send-route, 15-03-sign-handler]
|
||
|
|
tech_stack:
|
||
|
|
added: []
|
||
|
|
patterns: [jose-jwt, nodemailer-plain-text, nextjs-app-router-route-handler]
|
||
|
|
key_files:
|
||
|
|
created:
|
||
|
|
- teressa-copeland-homes/src/app/api/sign/download/[token]/route.ts
|
||
|
|
modified:
|
||
|
|
- teressa-copeland-homes/src/lib/signing/token.ts
|
||
|
|
- teressa-copeland-homes/src/lib/signing/signing-mailer.tsx
|
||
|
|
decisions:
|
||
|
|
- "signerEmail stored in DB only (not JWT) — keeps JWT payload minimal, consistent with D-03"
|
||
|
|
- "signer-download token is 72h with no DB record — same pattern as agent-download, longer TTL for signer latency"
|
||
|
|
- "public download route guards on doc.status === Signed AND signedFilePath — prevents serving partial accumulation files"
|
||
|
|
metrics:
|
||
|
|
duration: "2 min"
|
||
|
|
completed: "2026-04-03"
|
||
|
|
tasks_completed: 3
|
||
|
|
files_modified: 3
|
||
|
|
---
|
||
|
|
|
||
|
|
# Phase 15 Plan 01: Multi-Signer Utility Building Blocks Summary
|
||
|
|
|
||
|
|
**One-liner:** Extended createSigningToken with optional signerEmail, added signer-download JWT pair (72h), sendSignerCompletionEmail mailer, and public GET /api/sign/download/[token] route.
|
||
|
|
|
||
|
|
## Tasks Completed
|
||
|
|
|
||
|
|
| Task | Name | Commit | Files |
|
||
|
|
|------|------|--------|-------|
|
||
|
|
| 1 | Extend token.ts with signerEmail param and signer-download token pair | 70c48cc | src/lib/signing/token.ts |
|
||
|
|
| 2 | Add sendSignerCompletionEmail to signing-mailer.tsx | e1cdfe9 | src/lib/signing/signing-mailer.tsx |
|
||
|
|
| 3 | Create public signer download route GET /api/sign/download/[token] | 14efa1d | src/app/api/sign/download/[token]/route.ts |
|
||
|
|
|
||
|
|
## What Was Built
|
||
|
|
|
||
|
|
### token.ts changes
|
||
|
|
- `createSigningToken` now accepts optional `signerEmail?: string` — persists to `signingTokens.signerEmail` column (written as `null` if absent, preserving all existing call sites)
|
||
|
|
- `createSignerDownloadToken(documentId)` — 72h JWT with `purpose: 'signer-download'` claim, no DB record
|
||
|
|
- `verifySignerDownloadToken(token)` — validates purpose claim, returns `{ documentId }`
|
||
|
|
|
||
|
|
### signing-mailer.tsx changes
|
||
|
|
- `sendSignerCompletionEmail({ to, documentName, downloadUrl })` — plain-text email "All parties have signed...", subject "Signed copy ready: {name}", 72h expiry noted in body
|
||
|
|
|
||
|
|
### New route: GET /api/sign/download/[token]
|
||
|
|
- Public (no auth session)
|
||
|
|
- App Router async params pattern: `{ params }: { params: Promise<{ token: string }> }`
|
||
|
|
- Guards: invalid/expired token → 401, doc not Signed or no signedFilePath → 404, path traversal → 403
|
||
|
|
- Serves PDF with `Content-Type: application/pdf` and `Content-Disposition: attachment`
|
||
|
|
|
||
|
|
## Verification
|
||
|
|
|
||
|
|
- `npx tsc --noEmit` passes with zero errors
|
||
|
|
- Token utility now has 4 token types: sign, download, agent-download, signer-download
|
||
|
|
- Mailer now has 3 email functions: sendSigningRequestEmail, sendAgentNotificationEmail, sendSignerCompletionEmail
|
||
|
|
- Download route file exists at correct App Router path and imports from token.ts
|
||
|
|
|
||
|
|
## Deviations from Plan
|
||
|
|
|
||
|
|
None — plan executed exactly as written.
|
||
|
|
|
||
|
|
## Known Stubs
|
||
|
|
|
||
|
|
None — all functionality is fully implemented. Plans 02 and 03 will wire these utilities into the send route and sign handler.
|
||
|
|
|
||
|
|
## Self-Check: PASSED
|
||
|
|
|
||
|
|
- [x] teressa-copeland-homes/src/lib/signing/token.ts — modified, committed 70c48cc
|
||
|
|
- [x] teressa-copeland-homes/src/lib/signing/signing-mailer.tsx — modified, committed e1cdfe9
|
||
|
|
- [x] teressa-copeland-homes/src/app/api/sign/download/[token]/route.ts — created, committed 14efa1d
|
||
|
|
- [x] All three commits confirmed in git log
|