Files
2026-04-03 15:59:46 -06:00

7.7 KiB
Raw Permalink Blame History

Phase 16: Multi-Signer UI - Context

Gathered: 2026-04-03 Status: Ready for planning

## Phase Boundary

UI-only changes. No new API routes. No schema migrations. Phase 16 wires the Phase 15 backend into the agent's PreparePanel/FieldPlacer workflow and adds per-signer status to the dashboard.

Three UI areas:

  1. PreparePanel signer list — add/remove signers by email; signers saved to documents.signers via existing document update API
  2. FieldPlacer signer assignment — active-signer selector + per-signer field coloring; fields tagged with signerEmail via existing field placement API
  3. Send-block validation + dashboard — pre-send check for unassigned fields; N/M signed badge on dashboard
## Implementation Decisions

Signer Color Palette

  • D-01: Colors are auto-assigned when a signer is added — no agent choice needed. Fixed palette in order:
    1. #6366f1 (indigo)
    2. #f43f5e (rose)
    3. #10b981 (emerald)
    4. #f59e0b (amber)
    • If more than 4 signers, cycle the palette. The color is stored in documents.signers[].color when saved to DB.

PreparePanel Signer List

  • D-02: Signer list UI lives inside PreparePanel — between the existing "AI Auto-place" button section and the "Prepare and Send" button. It appears only for Draft documents (same gate as the rest of PreparePanel).
  • D-03: UI: an email input + "Add" button. Below it, a list of added signers showing a colored dot (their color), their email, and a remove (×) button. Signers are saved to the document record immediately when added/removed (PATCH to document update API, or inline save on "Prepare and Send" click — planner decides which is simpler).
  • D-04: Agent must add at least one signer before sending. If documents.signers is empty AND the document has client-visible fields, the send is blocked with a message: "Add at least one signer before sending."

FieldPlacer Active Signer Selector

  • D-05: An "Active signer" dropdown appears at the top of FieldPlacer (above the field palette), but ONLY when documents.signers has at least one signer. When no signers are configured, FieldPlacer behaves exactly as today.
  • D-06: All fields dragged onto the canvas while a signer is selected automatically get signerEmail set to that signer's email. The field box is colored using the signer's color (from documents.signers) instead of the field-type color.
  • D-07: Fields with no signerEmail (agent-signature, agent-initials, OR client fields placed before signers were configured) use the existing type-based color (unchanged behavior).
  • D-08: The active signer selector defaults to the first signer in documents.signers[] when the component loads. Agent can switch before dragging fields.

Send-Block Validation

  • D-09: Before calling /api/documents/[id]/send, PreparePanel checks: count of client-visible fields (isClientVisibleField) with no signerEmail. If count > 0:
    • Show red outline on each unassigned field in FieldPlacer (pass a validationErrors prop or similar from DocumentPageClient)
    • Show inline error below the Send button: "X field(s) need a signer assigned before sending."
    • Block the API call.
  • D-10: The red highlight is a validation state, not permanent — it clears as soon as the agent assigns signers to those fields.

Dashboard Per-Signer Status

  • D-11: The documents dashboard table gains a "Signers" column (or augments the existing Status column). For documents where documents.signers is non-empty AND status is "Sent" (partially signed): show N/M signed badge (e.g., 1/2 signed). Computed from counting signingTokens WHERE documentId = X AND usedAt IS NOT NULL vs total tokens for that document.
  • D-12: For single-signer documents (no documents.signers), this column shows nothing — status badge is unchanged.
  • D-13: For fully-signed documents (status = "Signed"), the existing "Signed" badge is sufficient — no N/M badge needed.

Claude's Discretion

  • Whether to save signers on every add/remove vs on "Prepare and Send" click (planner picks simpler approach)
  • Exact placement of "Active signer" selector within FieldPlacer layout
  • Whether the N/M badge appears in its own column or appended to the existing Status column
  • Email validation UX for the signer input (prevent duplicate emails, basic format check)

<canonical_refs>

Canonical References

Downstream agents MUST read these before planning or implementing.

Files Being Modified

  • teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/PreparePanel.tsx — Add signer list UI + send-block validation
  • teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/FieldPlacer.tsx — Active signer selector + per-signer field coloring
  • teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/DocumentPageClient.tsx — Thread signers state between PreparePanel and FieldPlacer
  • Dashboard document table (find exact file via grep for "DocumentsTable" or similar)

Schema (Phase 14 output)

  • teressa-copeland-homes/src/lib/db/schema.tsDocumentSigner interface { email, color }, documents.signers JSONB, isClientVisibleField()

Phase Context

  • .planning/phases/14-multi-signer-schema/14-CONTEXT.md — Schema decisions
  • .planning/phases/15-multi-signer-backend/15-CONTEXT.md — Backend decisions (send route, field filtering)

</canonical_refs>

<code_context>

Existing Code Insights

Reusable Assets

  • PALETTE_TOKENS in FieldPlacer.tsx — existing per-type color palette (lines 70-78); signer colors augment this, not replace it — fields with a signer use signer color, fields without use type color
  • isClientVisibleField() in schema.ts — already used in FieldPlacer; reuse for send-block validation check
  • DocumentSigner interface — already in schema.ts from Phase 14
  • Existing field-click-to-select UX in FieldPlacer — the selectedFieldId and onFieldSelect props are already threaded through; the active signer selector builds alongside this

Established Patterns

  • PreparePanel receives document state as props from DocumentPageClient (DocumentPageClient.tsx is the state owner)
  • FieldPlacer uses onFieldsChanged callback to bubble field changes up — signer assignment changes follow same pattern
  • Field colors computed inline in FieldPlacer at render time from PALETTE_TOKENS.find(t => t.id === fieldType) — signerEmail check added before this lookup
  • Dashboard uses Drizzle queries in a server component — adding a token count join follows same pattern

Integration Points

  • documents.signers (nullable JSONB) — read in PreparePanel to seed the signer list; written via document update call when signers are modified
  • SignatureFieldData.signerEmail? (Phase 14) — written when field is placed with active signer; read in FieldPlacer for color lookup and in PreparePanel for send-block validation
  • signingTokens — read (count query) in dashboard server component for N/M badge

</code_context>

## Specific Ideas
  • Signer color palette order: indigo → rose → emerald → amber (D-01). These contrast well against each other and against the existing type colors.
  • The "Active signer" selector is a simple <select> or styled dropdown showing signer email with a colored dot. It appears only when signers.length > 0.
  • Red highlight for unassigned fields: add a CSS border/box-shadow override (e.g., border: 2px solid #ef4444) when a field ID is in the unassignedFieldIds set passed from DocumentPageClient.
## Deferred Ideas

None — discussion stayed within phase scope.


Phase: 16-multi-signer-ui Context gathered: 2026-04-03