Files
Chandler Copeland a19163855b docs(15-02): complete multi-signer send route plan
- SUMMARY.md: multi-signer token loop + legacy fallback route rewrite
- STATE.md: advance to plan 3, record metrics, add decisions
- ROADMAP.md: update phase 15 progress (2/3 plans complete)
- REQUIREMENTS.md: mark MSIGN-05, MSIGN-06 complete
2026-04-03 15:48:01 -06:00

4.2 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
15-multi-signer-backend 02 api
multi-signer
signing
email
jwt
drizzle
nextjs
phase provides
15-01 createSigningToken with signerEmail param, DocumentSigner type, signingTokens.signerEmail column
phase provides
14-multi-signer-schema documents.signers JSONB column, DocumentSigner interface
Multi-signer send route with one token per signer and parallel email dispatch
Legacy single-signer fallback preserved when doc.signers is null/empty
APP_BASE_URL used for all signing URLs (not NEXT_PUBLIC_BASE_URL)
Audit event with metadata.signerEmail per signer in multi-signer path
15-03
16-multi-signer-ui
added patterns
Promise.all over signers array for parallel token creation and email dispatch
Branch on doc.signers?.length > 0 for multi vs. legacy path
APP_BASE_URL (server-side env) instead of NEXT_PUBLIC_BASE_URL for signing URLs
created modified
teressa-copeland-homes/src/app/api/documents/[id]/send/route.ts
Kept Promise.all fail-fast behavior: if one signer email fails, entire send fails and agent retries (consistent with legacy behavior)
clientName omitted for multi-signer emails (DocumentSigner has email+color only); email template handles gracefully
Return NextResponse.json({ ok: true }) without expiresAt in multi-signer path (all tokens same 72h TTL anyway)
Multi-signer branch: doc.signers && (doc.signers as DocumentSigner[]).length > 0
Legacy fallback: resolve clientId = doc.assignedClientId ?? doc.clientId, same as before
MSIGN-05
MSIGN-06
5min 2026-04-03

Phase 15 Plan 02: Multi-Signer Send Route Summary

Send route rewritten to loop over doc.signers, create one JWT per signer with signerEmail, and dispatch all emails in parallel via Promise.all — with full legacy fallback when signers is null.

Performance

  • Duration: ~5 min
  • Started: 2026-04-03T00:00:00Z
  • Completed: 2026-04-03T00:05:00Z
  • Tasks: 1
  • Files modified: 1

Accomplishments

  • Multi-signer path: doc.signers loop calls createSigningToken(doc.id, signer.email) for each signer, dispatches all emails in parallel via Promise.all
  • Legacy single-signer path preserved exactly: resolves assignedClientId ?? clientId, creates token without signerEmail, sends to client.name
  • NEXT_PUBLIC_BASE_URL replaced with APP_BASE_URL (server-side env var) across both paths
  • Per-signer audit events with metadata.signerEmail in multi-signer path
  • DocumentSigner imported from schema for proper type casting

Task Commits

  1. Task 1: Rewrite send route with multi-signer token loop and legacy fallback - 7a04a4f (feat)

Plan metadata: (pending)

Files Created/Modified

  • teressa-copeland-homes/src/app/api/documents/[id]/send/route.ts - Multi-signer token loop + legacy fallback, APP_BASE_URL, parallel email dispatch

Decisions Made

  • Kept Promise.all fail-fast: if one signer's email fails, entire send rolls back; agent retries. Consistent with existing single-signer pattern.
  • Omitted clientName in multi-signer path — DocumentSigner only has { email, color }, and the email template already handles undefined clientName gracefully.
  • Returned { ok: true } without expiresAt in multi-signer response (all tokens share the same 72h TTL).

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

None.

User Setup Required

None — no new environment variables introduced. APP_BASE_URL was already referenced in Phase 15 context (Pitfall 5); update .env to add it if not already present.

Next Phase Readiness

  • Send route is ready; Plan 15-03 (GET/POST sign handler rewrites) can proceed
  • signingTokens.signerEmail is now written at send time — GET handler can filter fields by it in 15-03

Self-Check: PASSED

  • teressa-copeland-homes/src/app/api/documents/[id]/send/route.ts — FOUND
  • .planning/phases/15-multi-signer-backend/15-02-SUMMARY.md — FOUND
  • Commit 7a04a4f — FOUND

Phase: 15-multi-signer-backend Completed: 2026-04-03