documents.signers JSONB shape is { email, color }[] — not string[] — so Phase 16 can retrieve consistent per-signer colors from DB without recalculating
signingTokens.signerEmail is nullable TEXT — NULL = legacy single-signer token, no existing token creation code requires changes
documents.completionTriggeredAt is nullable TIMESTAMP used as atomic completion guard in Phase 15 UPDATE...WHERE completionTriggeredAt IS NULL
SignatureFieldData.signerEmail? follows exact same additive-nullable pattern as type? — zero breakage to existing JSONB field rows
No Partially Signed status added to documentStatusEnum — partial state computed dynamically in Phase 16 by counting used tokens
duration
completed_date
tasks_completed
files_modified
5 min
2026-04-03
2
3
Phase 14 Plan 01: Multi-Signer Schema Summary
Additive Drizzle migration 0010 adding signerEmail to SignatureFieldData and signingTokens, plus signers JSONB and completionTriggeredAt to documents — all nullable, zero backfills, TypeScript compiles cleanly.
What Was Built
Three new nullable database columns and one TypeScript interface extension, establishing the data foundation for Phases 15 (sign handler rewrite) and 16 (multi-signer UI):
documents.signers uses { email, color }[] JSONB shape so Phase 16 PreparePanel can render consistent signer-assigned colors without recalculating by index position
signerEmail on SignatureFieldData is optional (not required) so every existing JSONB field row stored in the DB remains valid with no migration needed
completionTriggeredAt is Phase 14 schema-only; write logic (UPDATE...WHERE...IS NULL RETURNING) is Phase 15 scope
No Partially Signed enum value added — computed dynamically by counting usedAt IS NOT NULL tokens in Phase 16