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

127 lines
7.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 16: Multi-Signer UI - Context
**Gathered:** 2026-04-03
**Status:** Ready for planning
<domain>
## 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
</domain>
<decisions>
## 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)
</decisions>
<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.ts``DocumentSigner` 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>
<specifics>
## 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.
</specifics>
<deferred>
## Deferred Ideas
None — discussion stayed within phase scope.
</deferred>
---
*Phase: 16-multi-signer-ui*
*Context gathered: 2026-04-03*