# Feature Research

**Domain:** Real estate agent website + document signing portal — v1.1 Smart Document Preparation
**Researched:** 2026-03-21
**Confidence:** HIGH for field types and signing flows (strong industry evidence); MEDIUM for AI field detection accuracy (implementation approach has a critical constraint); HIGH for document preview expectations

---

## Scope Note

This file covers only the v1.1 milestone features. The existing v1.0 features (agent portal, client management, PDF upload/preview, drag-drop field placement, PreparePanel text fill, email-link signing, presigned download) are already built and validated.

**New features under research:**
1. AI-assisted field placement and pre-fill (gpt-4o-mini)
2. Expanded field types: text, checkbox, initials, date, agent signature
3. Agent saved signature + sign-first workflow
4. Filled document preview before sending

---

## Feature Landscape

### Table Stakes (Users Expect These)

Features a real estate agent would expect from any "smart document prep" upgrade. Missing these makes the v1.1 feel like a half-measure.

| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| Initials field type | Every Utah standard form (REPC, listing agreement, addenda) has initials lines on every page — initialing page-by-page is a core legal convention | MEDIUM | At signing time: initials block shows a condensed canvas (not full signature); auto-scrolls to each initials field after previous completion; behaves identically to signature field but smaller canvas |
| Date field type | Date-of-signing is required on nearly every field block; agents expect it to auto-fill at signing moment, not require client to type a date | LOW | Industry standard: date field is a read-only "Date Signed" stamp — system fills it at the moment the signer completes the signature block; client never types a date; dotloop and DocuSign both implement this as locked/auto-populated |
| Checkbox field type | Utah REPC and addenda use boolean checkboxes throughout (mediation clauses, contingency elections, disclosure acknowledgments) | LOW | At signing time: client taps/clicks to check; visual distinction (empty square vs. checked square); must be assigned to a specific signer or it defaults to "no one" and never gets checked (dotloop behavior confirmed) |
| Agent signature field type | Agent needs to counter-sign documents before sending; this is a separate field type from client signature — tied to agent's saved signature, not client's canvas | MEDIUM | Distinct from client signature: pre-filled by agent in the prep flow; client sees it as already signed when they open the document; not a client-facing interactive field |
| Agent signs before sending | Industry convention in real estate: the listing agent or buyer's agent signs first to demonstrate they've reviewed and authorized the document, then sends to client for counter-signature | MEDIUM | Sign-first is the dominant pattern; agent signs as Routing Order 1, client signs as Routing Order 2; DocuSign community documentation confirms this as the standard real estate workflow |
| Filled document preview before send | Agents expect to see the document exactly as the client will see it — with all pre-filled text, agent signature, and field placement visible — before hitting Send | MEDIUM | Preview must show: pre-filled text values, agent signature applied, all field markers overlaid on the PDF; client-facing fields should appear interactive but not be submittable from the preview |

### Differentiators (Competitive Advantage)

Features that go beyond the baseline — meaningful specifically for this app's single-agent, Utah-forms workflow.

| Feature | Value Proposition | Complexity | Notes |
|---------|-------------------|------------|-------|
| AI field placement via gpt-4o-mini | Teressa can click one button and have all signature, initials, date, checkbox, and text fields placed on a Utah standard form automatically — eliminating the manual drag-drop session for known forms | HIGH | **Critical constraint:** gpt-4o does not reliably return accurate pixel coordinates from images (< 3% accuracy in bounding box studies). Correct approach: extract PDF text with positional metadata via pdf-lib or pdfjs-dist, then use gpt-4o-mini for semantic understanding of field labels ("Buyer's Signature", "Date", "Initial Here") and return normalized page coordinates calculated from the text's own bounding box data — not from vision inference. AI does the label-understanding; the PDF SDK does the coordinate math. |
| AI pre-fill of text fields | Client name, property address, and date fields can be populated from client profile data + property data without manual typing in PreparePanel | MEDIUM | gpt-4o-mini maps known data (client.firstName, client.lastName, client.email, property.address) to identified text fields by label proximity. Low risk of hallucination because input is structured profile data, not free text inference. Model simply matches "Buyer" label to client name. |
| Agent saved signature (draw once, reuse) | Agent draws signature once on first use; it is stored as a PNG data URL and applied to any agent signature field with one click — eliminating per-document re-drawing | MEDIUM | Standard in every major real estate e-sig tool (DocuSign, dotloop, SkySlope); agents expect this; re-drawing every document is a daily friction point. Stored in agent profile. Can be cleared and redrawn. Display a "preview" of the saved signature before applying. |
| Property address on client profile | Teressa adds the property address to the client record so AI pre-fill knows what to insert into property address fields across all documents for that transaction | LOW | Simple field addition to client profile schema; enables AI pre-fill to be property-specific without Teressa re-typing the address on every document |

### Anti-Features (Commonly Requested, Often Problematic)

| Feature | Why Requested | Why Problematic | Alternative |
|---------|---------------|-----------------|-------------|
| AI generates pixel-perfect field placement from visual PDF analysis | "Just have AI look at the PDF image and tell me where the fields are" | gpt-4o and Claude 3.5 Sonnet return accurate pixel coordinates less than 3% of the time in bounding box studies (February 2025 research); placing a signature field 200px from the actual signature line produces a broken document | Extract text positions from the PDF's own data structures via pdfjs-dist or pdf-lib; use AI for label-matching only; compute coordinates from extracted text bounding boxes |
| AI auto-fill replaces the agent's PreparePanel review | "AI should fill everything and I just hit Send" | For legal documents, pre-fill values that are wrong create liability; purchase price, closing date, earnest money must be agent-verified before the document goes to a client | AI pre-fills obvious known values (names, address); agent reviews in PreparePanel and edits before sending; preview step is the final check |
| AI confidence thresholds surface to the agent | "Show me which fields AI isn't sure about" | Confidence scoring UX adds noise; solo agent workflow doesn't need a triage interface; if a field is missed, the agent sees it in preview | If AI misses a field, agent adds it manually in the existing drag-drop UI; preview step catches any gaps |
| Signature type-in fallback for agent signature | "Let agent type their name as their signature" | Typed signatures have lower perceived legal weight in real estate; clients may question them; canvas signature is the industry standard for agent counter-signatures | Canvas-drawn signature stored and reused; never degrade to typed for agent's own signature |
| Per-document redraw option for agent signature | "Maybe I want to sign slightly differently for important contracts" | Adds decision fatigue at the exact moment agents want speed; the value of saved signature is consistency and one-click application | Store one saved signature; provide a "Re-draw my signature" option in agent profile settings only, not in the per-document flow |
| Fully locked preview (no corrections possible) | "The preview is just a review step — agent can't change anything" | If the preview reveals a mistake (wrong address pre-filled, agent signature in wrong position), the agent needs to correct it before sending; a read-only preview that requires going back to square one increases frustration | Preview includes a back-to-edit button; light inline corrections (move a field, fix a pre-filled value) should be possible from or after the preview |

---

## Feature Dependencies

```
[v1.0 Client Management]
    └──enables──> [Property Address Field on Client Profile] (new field addition)
                      └──enables──> [AI Pre-fill of Text Fields]

[v1.0 PDF Upload + Rendering]
    └──enables──> [AI Field Detection] (needs PDF text extraction)
    └──enables──> [Expanded Field Types] (builds on existing field overlay system)

[v1.0 Drag-Drop Field Placement UI]
    └──extended by──> [Expanded Field Types (checkbox, initials, date, agent sig)]
    └──enhanced by──> [AI Field Detection] (pre-populates fields; agent adjusts)

[v1.0 PreparePanel (text fill)]
    └──enhanced by──> [AI Pre-fill] (populates known values automatically)
    └──enables──> [Filled Document Preview] (preview shows PreparePanel values rendered)

[Agent Saved Signature]
    └──requires──> [Agent Profile / Settings storage]
    └──enables──> [Agent Signature Field Type] (one-click apply)
    └──enables──> [Agent Signs First Workflow]

[Agent Signs First Workflow]
    └──requires──> [Agent Saved Signature]
    └──requires──> [Agent Signature Field Type]
    └──enables──> [Filled Document Preview] (preview makes most sense after agent signs)

[Filled Document Preview]
    └──requires──> [Agent Signs First Workflow] (or at minimum: PreparePanel fill complete)
    └──requires──> [Expanded Field Types] (all field types must render correctly in preview)
    └──gates──> [Send to Client] (Send button lives in or after the preview step)
```

### Dependency Notes

- **AI Field Detection requires PDF text extraction, not vision:** The correct implementation extracts text with positional bounding boxes from the PDF (via pdfjs-dist `getTextContent()` or pdf-lib) and passes labeled text positions to gpt-4o-mini for semantic field-type classification. The AI returns field type + which extracted text object to anchor to; the coordinate calculation uses the text object's own `transform` data. This avoids the coordinate-from-vision accuracy problem entirely.

- **Expanded field types extend the existing field overlay system:** The v1.0 signature field is already rendered as an overlay div on the PDF canvas with stored x/y/page/width/height. Adding checkbox, initials, date, and agent signature types means adding field-type discriminants to the same data model and rendering different UI chrome per type. Not a new system — an extension.

- **Agent Saved Signature is a prerequisite for Agent Signs First:** The one-click agent signing workflow only makes sense if the agent's signature is already stored. Without it, the agent would need to draw their signature in the agent-facing flow, which is equivalent to the client signing flow — functional but not the intended UX.

- **Filled Document Preview gates Send:** The preview is the final checkpoint. Send to Client should only be reachable from the preview screen (or with explicit bypass). This prevents the common mistake of sending the wrong document version.

- **Date fields must be non-editable by the client at signing time:** Date fields auto-populate at the moment the client completes the signing session. This is the DocuSign "Date Signed" pattern — a read-only auto-stamped field, not a calendar picker. The client cannot alter the date. This is legally important (it records when they actually signed, not a date they type in).

- **Checkbox fields must be signer-assigned to function:** Based on dotloop behavior, checkboxes default to "no one" if not explicitly assigned to a signer role. In this app's model, the agent assigns each checkbox to either the agent role (pre-checked during agent signing) or the client role (checked by client during signing). Unassigned checkboxes that are pre-checked by the agent are treated as acknowledgment fields (not interactive for the client).

---

## v1.1 Feature Definitions

### v1.1 Launch Features (the four areas)

- [ ] **Property address on client profile** — add `propertyAddress` field to client schema; display and edit in client detail view; used as AI pre-fill source for property address fields in documents
- [ ] **Expanded field types: checkbox** — checkbox field type in field placement sidebar; renders as empty square overlay; at signing: client taps to check; stores boolean checked state in document record; embeds checkmark into final PDF
- [ ] **Expanded field types: initials** — initials field type; renders as smaller signature canvas at signing time; same capture mechanics as signature (canvas drawing, stored as PNG); labeled "Initial Here" vs "Sign Here"
- [ ] **Expanded field types: date** — date field type; renders as read-only overlay; auto-populates with signing timestamp when client completes signing session; client cannot edit; embed formatted date string into final PDF
- [ ] **Expanded field types: agent signature** — agent signature field type placed by agent during prep; displays agent's saved signature image in preview and in the document sent to client; client sees it as already-signed; not interactive for client
- [ ] **Agent saved signature** — canvas draw interface on agent profile/settings; stores as base64 PNG; persists across sessions; "Re-draw" clears and prompts re-capture; shown as thumbnail in profile settings
- [ ] **Agent signs first workflow** — after field placement and PreparePanel fill, agent applies saved signature to all agent-signature fields; clicking an agent-sig field applies the stored PNG; all agent-sig fields must be filled before Proceed to Preview is enabled
- [ ] **AI field placement** — single "Auto-place Fields" button in the prep flow; PDF text extracted via pdfjs-dist with bounding boxes; payload sent to gpt-4o-mini with label-to-field-type mapping prompt; AI returns field type + text anchor identifier; system computes coordinates from text bounding box; places fields on PDF overlay; agent reviews and adjusts; always falls back gracefully to manual placement if AI returns nothing
- [ ] **AI pre-fill** — after AI field placement, text fields with high-confidence label matches (buyer name, seller name, property address, today's date) are pre-populated from client profile data; agent reviews in PreparePanel; agent can edit any pre-filled value
- [ ] **Filled document preview** — full-page PDF render with all overlays visible: pre-filled text values, agent signature rendered in-place, all client-facing fields shown with their type chrome (empty sig box, unchecked checkbox, "Initial Here" box, date placeholder); Send to Client button lives here; Back to Edit button returns to PreparePanel

### Defer to v1.2

- [ ] **AI confidence display to agent** — show which fields AI was uncertain about; adds UI complexity; agent can see and correct in preview instead; defer until volume of AI misses proves it necessary
- [ ] **Template save from AI placement** — save AI-generated field layout as a reusable template per form type; high value but requires template management UI; defer until AI placement is validated as accurate
- [ ] **Multiple agent signature fields** — currently one agent sig is the typical pattern; multiple is possible with the field system but needs UX thought (which signature applies where); defer

---

## Feature Prioritization Matrix (v1.1)

| Feature | User Value | Implementation Cost | Priority |
|---------|------------|---------------------|----------|
| Agent saved signature | HIGH | LOW | P1 |
| Initials field type | HIGH | LOW | P1 |
| Date field (auto-stamp) | HIGH | LOW | P1 |
| Checkbox field type | HIGH | LOW | P1 |
| Agent signature field type | HIGH | MEDIUM | P1 |
| Agent signs first workflow | HIGH | MEDIUM | P1 |
| Filled document preview | HIGH | MEDIUM | P1 |
| Property address on client profile | HIGH | LOW | P1 |
| AI pre-fill from profile data | HIGH | MEDIUM | P1 |
| AI field placement (gpt-4o-mini + text extraction) | HIGH | HIGH | P1 |
| AI field placement template save | MEDIUM | HIGH | P3 |
| AI confidence display to agent | LOW | MEDIUM | P3 |

**Priority key:**
- P1: Must have for v1.1 launch
- P2: Should have, add when possible
- P3: Nice to have, future consideration

---

## Behavioral Specifications by Feature

### (1) AI-Assisted Field Detection

**How it works in production tools:** Apryse, Instafill, and DocuSign Iris (January 2026) all use a hybrid approach: PDF structure parsing to extract text positions, then LLM for semantic classification. Raw vision-based bounding box inference is not production-viable — GPT-4o returns accurate pixel coordinates in under 3% of attempts in published benchmarks.

**Accuracy expectations:** On structured Utah standard forms (REPC, listing agreements, addenda), which have consistent label patterns ("Buyer's Signature", "Seller's Initials", "Date", "Property Address"), label-matching accuracy should be HIGH (90%+) because the label text is predictable. The risk is on non-standard addenda or scanned/image-based PDFs where text extraction fails.

**Fallback hierarchy:**
1. PDF has extractable text → text extraction + AI label matching → place fields at text positions (HIGH confidence path)
2. PDF is image-based (scanned) → AI cannot extract text → show message "Auto-placement requires a text-based PDF. Place fields manually." → agent falls back to drag-drop
3. AI returns no fields or low-confidence results → show "AI couldn't detect fields confidently. Review the placement or add fields manually." → pre-filled fields from AI are shown as suggestions with a different visual treatment; agent confirms or removes each one

**What the agent sees:** A "Detecting fields..." loading state (2-5 seconds), then fields appear on the PDF overlay. A summary count: "AI placed 14 fields — 8 signature, 3 date, 2 initials, 1 checkbox. Review and adjust." Misplaced fields can be dragged or deleted.

**gpt-4o-mini vs gpt-4o:** Use gpt-4o-mini for this task. The task is classification and mapping (semantic understanding of form labels), not complex reasoning. gpt-4o-mini handles this at lower cost (~0.15-0.60 cents per PDF page vs gpt-4o's 2.5-10 cents). At Teressa's volume (solo agent, dozens of documents per month), either is negligible cost.

### (2) Expanded Field Types at Signing Time

**Initials:** Renders as a smaller version of the signature canvas ("Initial Here" label instead of "Sign Here"). Client draws their initials. Same capture mechanics as signature (canvas, PNG data URL). Stored separately from signature so audit trail distinguishes "initialed page 3" from "signed on page 8". The industry convention on Utah forms is to initial every page — this field type handles that pattern.

**Checkboxes:** Renders as an empty square (24x24px). Client taps or clicks to toggle. A checkmark renders inside on selection. Toggle is allowed before final submission (client can uncheck and recheck). At submission, the checked/unchecked state is embedded as a drawn checkmark or empty box in the PDF. Checkboxes assigned to agent are pre-checked during agent signing flow and appear pre-checked when client opens the document (read-only from client perspective).

**Date fields:** Auto-stamp pattern only — no calendar picker for the client. The field shows a placeholder ("Date will be filled at signing") when the agent previews. At the moment the client clicks "Complete Signing", all date fields are stamped with the UTC timestamp formatted as the local date (e.g., "March 21, 2026"). This matches DocuSign's "Date Signed" field behavior. The client cannot type a date. This is the legally correct approach — it records when they actually signed.

**Agent signature fields:** The agent places these during prep. During agent signing (before preview), clicking an agent-sig field applies the stored PNG. The PNG renders at the field's bounding box dimensions. When the document is sent to the client, these fields are already filled and read-only. The client cannot modify or remove the agent's signature.

### (3) Agent Counter-Signature Flow

**Sign-first is the industry norm:** In real estate, the agent (representing one party) typically signs first to show they've reviewed and authorized the document, then it routes to the client. This is confirmed by DocuSign's recommended routing for real estate: agent at Order 1, client at Order 2. Dotloop's auto-date behavior applies the same timestamp logic to the agent's first signature.

**Saved vs. per-document redraw:** All major tools store a saved signature. DocuSign calls it "Adopted Signature." Dotloop stores it per account. SkySlope DigiSign stores it account-wide. Per-document redraw exists in some tools as an option but agents rarely use it. The saved pattern is the standard because: (a) agents sign dozens of documents per transaction, (b) consistency across documents matters for authenticity, (c) re-drawing adds 30-60 seconds per document that adds up across a week.

**Implementation pattern for this app:** Agent Profile page has a "My Signature" section with a canvas draw interface. On first use (when an agent tries to apply a signature to a field), if no signature is saved, the app prompts them to draw and save one. After saving, applying is one click. "Re-draw Signature" in profile settings clears and prompts a new canvas session.

**What happens if no agent signature fields exist in the document:** If the agent places no agent-sig fields, the "Agent Signing" step is skipped and the flow goes directly from PreparePanel to Preview. The workflow should not require agent signature — it should be optional based on whether agent-sig fields were placed.

### (4) Document Preview Before Sending

**What users expect to see:** The industry standard preview (DocuSign, BoldSign, Adobe Sign) shows the document exactly as the recipient will see it: all filled fields rendered in-place, all empty fields visible with their interaction chrome (highlighted boxes for client-interactive fields). The agent is not in "edit mode" — they're seeing the client's view.

**What users expect to be able to do:** The most common expectation is a Back button to return to editing. Users do not expect to edit inline in the preview, but they do expect: (a) ability to scroll through all pages, (b) see a "Document is ready to send" or "X fields still need agent action" status, (c) confirm the send action from the preview. A "Download Preview" option (PDF download of the current state) is valued but not table stakes.

**Common pre-send mistake preview prevents:** Sending the wrong version of a document is the most-cited error in the industry. Agents also commonly send documents with unfilled agent signature fields (forgot to sign). The preview step catches both: the agent can see if their signature is missing from any agent-sig fields, and the document version is explicitly what they reviewed.

**Preview in the context of this app:** The preview should render using the same PDF.js rendering pipeline as the existing prep view, but with all overlay fields in "signed/filled" visual state rather than "editable" state. Pre-filled text values appear as rendered text on the PDF. Agent signature fields show the saved signature PNG. Client-interactive fields (signature, initials, checkbox) show their placeholder chrome (highlighted box, "Sign Here" label) so the agent can see what the client will see. Date fields show "—" or "Auto-fill on signing."

---

## Competitor Feature Analysis (v1.1 Scope)

| Feature | DocuSign | Dotloop | SkySlope DigiSign | This App (v1.1) |
|---------|----------|---------|-------------------|-----------------|
| AI field placement | DocuSign Iris (Jan 2026) — AI auto-places via agreement analysis | No AI placement — template-based only | Smart Suite auto-audit, not field placement | gpt-4o-mini + pdfjs text extraction; Utah-specific label patterns |
| Initials field | Yes — condensed signature canvas | Yes — same as signature but labeled "Initial" | Yes | Canvas draw, labeled "Initial Here"; same capture as signature |
| Date field behavior | "Date Signed" — auto-stamp, locked, client cannot edit | Auto-date/time stamp on signature and initials | Add time/date to signatures automatically | Auto-stamp at signing session completion; client cannot type a date |
| Checkbox field | Yes — toggle checkbox | Yes — binary check | Yes | Tap/click toggle; embed checkmark or empty box into PDF |
| Agent saved signature | Yes — "Adopted Signature" stored account-wide | Yes — stored per account | Yes | Canvas-drawn, stored in agent profile as PNG |
| Agent signs first | Yes — Routing Order 1 agent, Order 2 client | Yes — sequential signing order supported | Yes | Agent signing step before preview; agent-sig fields pre-filled before client sees doc |
| Pre-send preview | Yes — "Preview" step shows filled document | Yes — document preview in loop before sharing | Yes | Full PDF render with all overlays in filled state; Send button lives in preview |
| AI pre-fill from contact data | Yes — Rooms for Real Estate prefills from transaction data | Yes — via transaction record | Yes — via transaction file | Pre-fill from client profile (name, email, property address) |

---

## Sources

**AI field detection and coordinate accuracy:**
- [Auto-detect PDF Form Fields with Smart Data Extraction — Apryse](https://apryse.com/blog/auto-detect-pdf-form-fields-with-smart-data-extraction)
- [SAM 2 + GPT-4o Cascading Foundation Models — Edge AI and Vision Alliance (Feb 2025)](https://www.edge-ai-vision.com/2025/02/sam-2-gpt-4o-cascading-foundation-models-via-visual-prompting-part-2/) — confirms GPT-4o returns accurate bounding box coordinates in fewer than 3% of attempts
- [GPT-4o Model: Image Coordinate Recognition — OpenAI Community](https://community.openai.com/t/gpt-4o-model-image-coordinate-recognition/907625)
- [Case Study: Real Estate Law Flat PDF Form Automation — Instafill.ai (Feb 2026)](https://blog.instafill.ai/2026/02/18/case-study-real-estate-law-flat-pdf-form-automation/)
- [Intelligent Document Processing for Real Estate — Syntora](https://syntora.io/solutions/ai-document-processing-for-real_estate)
- [Using Confidence Scoring to Reduce Risk in AI-Driven Decisions — Multimodal.dev](https://www.multimodal.dev/post/using-confidence-scoring-to-reduce-risk-in-ai-driven-decisions)
- [Understanding Accuracy and Confidence in Azure Document Intelligence — Microsoft Learn](https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/concept/accuracy-confidence?view=doc-intel-4.0.0)

**Field types and signing behavior:**
- [Adding Signatures or Initials to Locked Templates — Dotloop Support](https://support.dotloop.com/hc/en-us/articles/217936457-Adding-Signatures-or-Initials-to-Locked-Templates)
- [Understanding Signing — Dotloop Support](https://support.dotloop.com/hc/en-us/articles/202790063-How-clients-sign)
- [Am I able to auto-populate the date field? — DocuSign Community](https://community.docusign.com/esignature-111/am-i-able-to-auto-populate-the-date-field-2271)
- [DigiSign by SkySlope — E-Signature for Realtors](https://skyslope.com/products-services/digisign/)
- [Electronic Signatures for Real Estate: 2026 Guide — DocuPilot](https://www.docupilot.com/blog/electronic-signature-for-real-estate)

**Agent counter-signature and routing order:**
- [Prefill fields before sending envelope for signature — DocuSign Community](https://community.docusign.com/esignature-111/prefill-fields-before-sending-envelope-for-signature-180) — confirms agent at routing order 1, client at routing order 2 as real estate standard
- [Mastering Sequential Multi-Signer Workflows — Docomotion](https://www.docomotion.com/mastering-sequential-multi-signer-workflows-for-salesforce-real-estate/)
- [Best Electronic Signature Software for Real Estate in 2026 — SignEasy](https://signeasy.com/blog/business/electronic-signature-software-for-real-estate)
- [Lone Wolf Authentisign — Real estate's leading eSignature solution](https://www.lwolf.com/operate/esignature)

**Document preview and prefill:**
- [Prefill agreement fields before sending — Adobe Acrobat Sign](https://helpx.adobe.com/sign/authoring/prefill.html)
- [Simplify Document Signing with Prefilled Fields — BoldSign](https://boldsign.com/blogs/how-to-prefill-form-details-before-sending-a-document-for-signature/)
- [DocuSign Rooms for Real Estate](https://www.docusign.com/products/rooms-for-real-estate)
- [How E-Signatures Transform Real Estate Transactions in 2026 — Legitt AI](https://legittai.com/blog/e-signatures-transform-real-estate-2026)
- [Top eSignature Trends to Watch in 2026 — BlueInk](https://www.blueink.com/blog/top-esignature-trends-2026)

**Utah REPC form specifics:**
- [Utah Division of Real Estate — State Approved Forms](https://realestate.utah.gov/real-estate/forms/state-approved/)
- [Utah Real Estate Purchase Contract (REPC) — Utah Division of Commerce](https://commerce.utah.gov/wp-content/uploads/2023/03/purchase-contract.pdf)

---
*Feature research for: Teressa Copeland Homes — v1.1 Smart Document Preparation*
*Researched: 2026-03-21*

---
---

# Feature Research — v1.2 Multi-Signer Workflow

**Domain:** Multi-signer document signing — parallel dispatch, signer-scoped signing pages, completion tracking
**Researched:** 2026-04-03
**Confidence:** HIGH — grounded in existing codebase inspection (ARCHITECTURE.md already defines the implementation model), verified against DocuSign/HelloSign/PandaDoc behavioral patterns from web research

---

## Scope Note

This section covers only the v1.2 milestone additions. The existing v1.0/v1.1 features (single-signer flow, field placement, AI pre-fill, agent signature, filled preview) are already built.

**New features under research (multi-signer only):**
1. Signer list entry on the document (replace single recipient with named signer rows)
2. Field-to-signer assignment when placing fields
3. Per-signer signing tokens and parallel dispatch
4. Signer-filtered signing page
5. Per-signer completion tracking
6. Document completion: all-signed notification + final PDF to all parties

---

## Feature Landscape

### Table Stakes (Users Expect These)

These are behaviors that DocuSign, HelloSign (Dropbox Sign), and PandaDoc all implement as defaults. An agent who has used any of these tools will expect them. Missing any one of these makes the multi-signer feature feel broken.

| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| Name each signer (email + optional display name) | Every major tool requires identifying signers before placing fields. Without it, field assignment has no target and the email has no greeting. | LOW | Replaces the single email textarea in PreparePanel with a list of name+email rows. Names used in the email greeting ("Hi Sarah,"). Emails drive field routing. Minimum 1 signer; no enforced maximum for MVP. |
| Assign each client-visible field to a specific signer | Core of multi-signer — a field without a signer assignment is ambiguous. Which canvas does Buyer sign on vs. Seller? DocuSign, PandaDoc, and dotloop all require explicit field-to-recipient assignment before sending. | MEDIUM | Per-field signer selector in FieldPlacer. Agent-owned fields (agent signature, agent-pre-filled text) have no signer assignment — they are filled at prepare time and locked. Only client-visible fields (signature, initials, checkbox) need assignment. Date fields are client-visible but auto-stamp — they inherit the assignment of the adjacent signature/initials field they accompany. |
| Block send if any client-visible field is unassigned | DocuSign enforces this as a hard error before sending. Agents expect it because sending an unassigned signature field means no one will ever sign it. | LOW | UI validation: "Send" button is disabled and shows "2 fields have no signer assigned." Agent fixes in FieldPlacer before proceeding. |
| Each signer receives their own unique signing link | Standard behavior. Sharing one link among multiple signers is not a pattern any tool uses — it removes identity, makes completion tracking impossible, and creates legal ambiguity about who signed what. | MEDIUM | Each signer gets a JWT signed with their email stored in the `signer_email` column of `signing_tokens`. Links sent simultaneously via `Promise.all()`. |
| Each signer sees only their own fields | Expected by analogy with single-signer: when you receive a DocuSign link, you see only your fields. Seeing another signer's name on an empty signature field you cannot fill is confusing and creates "who signs where?" support calls. | MEDIUM | Signing GET endpoint filters `signatureFields` by `field.signerEmail === tokenRow.signerEmail`. Other signers' fields are simply not sent to the client. The PDF renders in full; only the interactive overlay elements are scoped. |
| Signing page shows progress ("X of Y signers have signed") | Users expect to know where the document stands. DocuSign shows "1 of 3 recipients have signed." HelloSign shows a progress indicator. In real estate, agents are frequently asked "has everyone signed yet?" | LOW | Simple count from `signing_tokens` WHERE `document_id = ? AND used_at IS NOT NULL` vs total tokens. Shown on the signing confirmation page and in the agent portal document detail. |
| Agent is notified when all signers complete | Universal behavior. DocuSign sends a "Document Completed" email to the sender by default. Without this, the agent has no way to know the document is fully executed without polling the portal. | LOW | Triggered once all tokens are claimed (`document_completed` audit event). One email to agent. Subject: "All parties have signed — [Document Name]". |
| All parties receive the final PDF when complete | DocuSign attaches the completed PDF to the completion email (subject to a 5 MB size limit). Real estate agents expect all parties to have a copy of the fully-executed document. It is also an industry norm for legal record-keeping. | MEDIUM | Each signer gets an email with a presigned download link to the final merged PDF. Agent gets the same. Not an attachment (avoids size limits and expired links from email attachment storage policies) — a time-limited download link from Vercel Blob. |

### Differentiators (Competitive Advantage)

These are not expected behaviors in a basic multi-signer implementation, but they fit the context of this specific app.

| Feature | Value Proposition | Complexity | Notes |
|---------|-------------------|------------|-------|
| Per-signer color coding on the field placement canvas | When the agent is placing fields, it is easy to lose track of which fields belong to which signer. DocuSign uses color-coded recipient fields (blue for Recipient 1, green for Recipient 2). This prevents misassignment. | LOW | CSS border/background color per `signerEmail`. Color assigned deterministically (first signer = blue, second = green, etc.). Legend shown in FieldPlacer sidebar. No user-configurable color. |
| Signing confirmation page shows what was just signed | After submitting, the signer sees "Thanks Sarah — you've signed. Bob Smith still needs to sign." This is the Dropbox Sign post-sign experience. It reduces "did it work?" anxiety without exposing any privacy details about the other signer's contact info. | LOW | Simple post-submit page. Shows: signer's own name, document name, completion timestamp, number of remaining signers (not their names/emails). Download link for the in-progress PDF (the accumulator). |
| Document status shows per-signer completion in agent portal | The agent can see at a glance which signers have completed and which have not. In single-signer this was binary (Sent/Signed). Multi-signer needs granularity: "Buyer signed March 3 — Seller has not yet signed." | MEDIUM | Agent portal document detail reads `doc.signers[]` array. Each entry shows: signer name/email, `signedAt` timestamp if completed, "Awaiting" if not. This is the `signers` JSONB column from ARCHITECTURE.md. |

### Anti-Features (Commonly Requested, Often Problematic)

| Feature | Why Requested | Why Problematic | Alternative |
|---------|---------------|-----------------|-------------|
| Sequential signing (Signer 2 cannot sign until Signer 1 completes) | "Agent should sign before the buyer" or "Seller must sign before buyer sees it" | PROJECT.md explicitly specifies parallel signing ("any order"). Sequential adds routing logic, waiting states, and re-notification emails — significant complexity for a feature the project owner explicitly rejected. For this app, the agent signs first at prepare time (before sending). The remaining signers are all clients who sign in parallel. | Agent signs before sending (already built in v1.1 as agent-signature flow). All client signers receive links simultaneously. |
| Signing reminder emails (automated resend if not signed in N days) | "What if the client doesn't sign for a week?" | Requires background job infrastructure (cron or worker queue). For a solo agent sending to known clients, a manual "Resend reminder" button is sufficient and avoids the infra cost. | Manual resend: agent can click "Resend link" in the portal for any signer who has not yet completed. This creates a new token and sends a fresh email. LOW complexity, same user outcome for 95% of cases. |
| Signer can see other signers' completed signatures on the PDF before they sign | "It feels more complete to see the buyer already signed when the seller opens the doc" | Requires a different field visibility model: fetching all signers' submitted data and rendering it on the PDF before the current signer submits. The accumulator model in ARCHITECTURE.md handles this post-hoc (each signer signs into the accumulator), not pre-emptively. Getting this right without creating privacy or sequence issues (what if buyer changes their mind?) is genuinely complex. | Signers see the base PDF with their own fields. After ALL signers complete, the final merged PDF goes to everyone — this is the standard industry pattern. |
| Signing order labels on fields ("Sign here - Signer 2") | "Helps signers know which fields are theirs" | Since each signer only sees their own fields on their signing page, the label is redundant. It adds visual noise and raises questions ("why does it say Signer 2 — am I in the right place?"). | Per-signer filtered signing page already solves this. Each signer sees a clean page with only their fields, labeled by type ("Sign here", "Initial here"). |
| Signer-level expiry (Signer A's link expires in 7 days, Signer B's in 14 days) | "Different parties have different deadlines" | Adds per-token configuration to the send flow. For real estate, all parties in a transaction are on the same deadline. Universal expiry (e.g., 14 days) covers 100% of Teressa's use cases. | All tokens for a document share the same expiry duration. Agent sets it once at send time (or uses the default). A future resend flow handles expired tokens. |
| Email address validation against a contacts database | "Warn me if I enter an email that's not in my clients list" | Signers may be parties Teressa hasn't added to her contacts (co-buyers, lenders, title officers). Restricting to the clients table introduces friction for the 30-40% of signers who aren't pre-loaded. | Free-text email input with standard email format validation only. Signer does not need a client record. This is confirmed in ARCHITECTURE.md: "signers may not be in clients table." |
| Bulk send to a document template (one form, many different transactions) | "Send this listing agreement template to 10 different clients at once" | Requires template management, variable substitution, and per-recipient field instances. Equivalent to DocuSign PowerForms. Multi-signer in v1.2 is scoped to one document, one transaction, multiple parties. | Template save is deferred to v2 per v1.1 research. Bulk send depends on templates. Correct scope is: one document, name the signers, send. |

---

## Feature Dependencies (v1.2)

```
[v1.0 Single-Signer Signing Flow]
    └──extended by──> [Per-Signer Token Creation]
                          └──requires──> [Signer List Entry UI]
                          └──enables──> [Parallel Email Dispatch]
                          └──enables──> [Signer-Filtered Signing Page]

[v1.1 Field Placement UI]
    └──extended by──> [Field-to-Signer Assignment]
                          └──requires──> [Signer List Entry UI] (must know signers before tagging fields)
                          └──enables──> [Per-Signer Color Coding]

[Signer List Entry UI]
    └──gates──> [Field-to-Signer Assignment] (chicken-and-egg: signers must exist before fields can be tagged)
    └──gates──> [Per-Signer Token Creation + Dispatch]

[Field-to-Signer Assignment]
    └──gates──> [Send] (unassigned client-visible fields block send)

[Per-Signer Token Creation + Dispatch]
    └──enables──> [Signer-Filtered Signing Page]
    └──enables──> [Per-Signer Completion Tracking]

[Per-Signer Completion Tracking]
    └──enables──> [Document Completion Detection]
                      └──triggers──> [Agent Completion Notification Email]
                      └──triggers──> [All-Parties Final PDF Email]

[v1.1 Accumulator PDF (signed by one signer, file updated)]
    └──extended by──> [Multi-Signer Sequential Accumulation]
                          └──requires──> [Postgres Advisory Lock] (concurrent signer writes)
                          └──produces──> [Final Merged PDF]
```

### Dependency Notes

- **Signer list must be entered before fields are placed.** This is the most important UX sequencing constraint. If the agent enters signers after placing fields, existing fields have no `signerEmail` and the validation block prevents sending. Resolution: the PreparePanel prompts for signers as the first step in the prepare flow. Fields can be placed after signers are defined.

- **The chicken-and-egg problem with signer entry order.** Some agents will want to place fields first, then decide who the signers are. The system should allow out-of-order workflows: agent places fields with "Unassigned" status, then enters signers and assigns them. The send block validates that no client-visible field is unassigned at send time — it does not prevent field placement before signer entry.

- **Accumulator PDF depends on the advisory lock.** Two signers submitting simultaneously without a lock will produce a corrupted PDF (both read the same input file and write conflicting outputs). The `pg_advisory_xact_lock` pattern from ARCHITECTURE.md is mandatory, not optional.

- **Date fields inherit their signer from context.** A date field adjacent to a buyer signature field should be tagged to the buyer. Currently date fields are auto-stamped at session completion — in multi-signer, the timestamp is written at the moment that signer's token is claimed, not at "all done." A date field on buyer's row uses buyer's signing timestamp. This means date fields need a `signerEmail` assignment just like signature fields. The agent should assign date fields to the adjacent signer, or UI could auto-assign based on proximity.

- **Completion emails require the final merged PDF path to be stable.** The all-parties completion email contains a download link. That link must point to the final accumulator output, which is only stable after the last signer submits. The completion detection step in ARCHITECTURE.md (step 10b of the signing POST) correctly gates the email send until after all tokens are claimed.

---

## v1.2 Feature Definitions

### Launch With (v1.2 — this milestone)

- [ ] **Signer list entry UI** — PreparePanel adds a "Signers" section. Agent enters rows of (optional name, required email). Minimum 1 signer. Add/remove rows. Saved to `documents.signers` JSONB via PUT `/api/documents/[id]/signers`. Displayed above field placement step so signers are known before tagging begins.

- [ ] **Field-to-signer assignment** — In FieldPlacer, when placing a client-visible field (signature, initials, checkbox), a dropdown appears to select which signer the field belongs to. Options populated from `doc.signers[]`. Color-coded by signer. Unassigned fields shown in a distinct "no signer" color. Field data stores `signerEmail` in `SignatureFieldData` JSONB.

- [ ] **Per-signer color coding** — Each signer is assigned a color deterministically (first signer = blue, second = green, etc.). Placed fields render with that signer's color border/background. A color legend appears in the FieldPlacer sidebar. Maximum 4-5 signers before colors become indistinct — adequate for real estate documents which rarely have more than 3 parties.

- [ ] **Send validation: block if fields unassigned** — Before sending, server validates all client-visible fields have a `signerEmail`. UI shows: "3 fields are not assigned to a signer." Send button disabled. Agent resolves in FieldPlacer.

- [ ] **Per-signer token creation and parallel dispatch** — Send route detects `doc.signers?.length > 0`. For each signer: create a signing token with `signer_email`, send signing request email, log `signer_email_sent` audit event. All dispatched via `Promise.all()` (parallel, any order). Legacy single-signer path (no `doc.signers`) remains unchanged.

- [ ] **Signer-filtered signing page** — Signing GET endpoint reads `tokenRow.signerEmail`. Returns only `signatureFields` where `field.signerEmail === tokenRow.signerEmail`. Legacy null `signer_email` falls through to `isClientVisibleField()` (unchanged). The signing page renders the full PDF with only the current signer's fields as interactive overlays.

- [ ] **Per-signer completion tracking in portal** — Agent portal document detail shows a signers list: name/email, status ("Signed March 3 at 2:14 PM" or "Awaiting signature"). Data sourced from `doc.signers[].signedAt`. Simple read from JSONB — no new query required.

- [ ] **Document completion detection** — After each signer submits, the signing POST checks: all tokens for this document have `used_at IS NOT NULL`. If yes, fires `document_completed` audit event, sets `documents.status = 'Signed'`, sets `signedAt`, computes `pdfHash`.

- [ ] **Agent completion notification email** — On `document_completed`, send one email to the agent: "All parties have signed [Document Name]. Download the final document: [link]." Presigned download link from Vercel Blob, 30-day expiry.

- [ ] **All-parties final PDF email** — On `document_completed`, send to each signer: "The document is fully signed. Here is your copy: [link]." Same presigned download link. Personalized greeting using `signer.name` if available, fallback to email address.

- [ ] **Post-sign confirmation page** — After a signer submits, they see: document name, their name/email, signing timestamp, "X of Y signers have completed." If they are the last signer: "The document is fully executed. All parties will receive a copy by email." Download link to the current merged PDF state.

### Add After Validation (v1.x)

- [ ] **Manual resend link to a specific signer** — Agent portal: "Resend link" button per signer row in the document detail. Creates a new signing token, invalidates the old one (sets `used_at` to a sentinel value or deletes and reissues), sends fresh email. Triggered by: agent reporting a signer didn't receive their link or token expired.

- [ ] **Token expiry handling at signing time** — Currently expired tokens show a generic "link expired" error. In multi-signer context, show: "This signing link has expired. Contact [agent name] to request a new link." Include agent contact info from agent profile.

### Future Consideration (v2+)

- [ ] **Automated reminder emails** — Reminder sent to unsigned signers after N days. Requires a background job (cron). For current volume (solo agent, known clients), manual resend covers the need. Add when agent requests automation.

- [ ] **Sequential signing order** — Signer 2 does not receive their link until Signer 1 completes. PROJECT.md explicitly out of scope for v1.2. If Teressa requests this in the future, it requires: routing state machine, deferred email dispatch, per-signer "waiting" status.

- [ ] **Template-based multi-signer** — Save a field layout + signer role map as a reusable template. "Buyer/Seller roles" pre-assigned; agent enters names/emails at send time. Requires template management UI and role-based field assignment (rather than email-based). Depends on template save feature (also v2).

- [ ] **Signing deadline per document** — Agent sets an expiry date ("all signers must sign by March 15"). System rejects signing submissions after deadline. Useful for offer deadlines in real estate. Not needed for v1.2 — use token expiry as a proxy for now.

---

## Feature Prioritization Matrix (v1.2)

| Feature | User Value | Implementation Cost | Priority |
|---------|------------|---------------------|----------|
| Signer list entry UI | HIGH | LOW | P1 |
| Field-to-signer assignment | HIGH | MEDIUM | P1 |
| Send validation: block if fields unassigned | HIGH | LOW | P1 |
| Per-signer token creation + parallel dispatch | HIGH | MEDIUM | P1 |
| Signer-filtered signing page | HIGH | MEDIUM | P1 |
| Agent completion notification email | HIGH | LOW | P1 |
| All-parties final PDF email | HIGH | LOW | P1 |
| Document completion detection | HIGH | MEDIUM | P1 |
| Per-signer completion tracking in portal | MEDIUM | LOW | P1 |
| Post-sign confirmation page | MEDIUM | LOW | P1 |
| Per-signer color coding | MEDIUM | LOW | P2 |
| Manual resend link | MEDIUM | MEDIUM | P2 |
| Token expiry UX for multi-signer | LOW | LOW | P2 |
| Automated reminder emails | MEDIUM | HIGH | P3 |
| Sequential signing order | LOW | HIGH | P3 |
| Template-based multi-signer | MEDIUM | HIGH | P3 |

**Priority key:**
- P1: Must have for v1.2 milestone
- P2: Should have, add when possible within this milestone
- P3: Defer to v2+

---

## Competitor Feature Analysis (v1.2 Scope: Multi-Signer)

| Feature | DocuSign | Dropbox Sign (HelloSign) | PandaDoc | This App (v1.2) |
|---------|----------|--------------------------|----------|-----------------|
| Signer identity model | Named recipients with email + role | Named recipients with email | Named signers (Signer 1, 2, 3) | Name + email rows in PreparePanel; no role abstraction |
| Field-to-signer assignment | Explicit per-field recipient assignment, color-coded | Explicit per-field signer assignment | Explicit; template roles pre-assigned | Per-field signer dropdown with deterministic color coding |
| Parallel vs sequential dispatch | Both; configurable via signing order numbers (same number = parallel group) | Both; set via signing order | Both | Parallel only (any order); PROJECT.md explicitly rejects sequential for v1.2 |
| Signer sees only own fields | Yes — recipient-scoped signing page | Yes | Yes | Yes — field filtering by `signerEmail` in token at signing GET |
| Completion notification to sender | Yes — automatic email + PDF | Yes | Yes | Agent email on `document_completed` with download link |
| Completion PDF to all signers | Yes — configurable; PDF attached or linked | Yes | Yes | Presigned Vercel Blob link sent to each signer on completion |
| Per-signer status in sender dashboard | Yes — "Delivered", "Viewed", "Signed" per recipient | Yes | Yes | "Signed [timestamp]" or "Awaiting" per signer in portal |
| Reminder emails | Yes — configurable auto-reminders | Yes — "Send reminder" manually or auto | Yes | Manual resend (v1.2); auto-reminders deferred to v2 |
| In-progress PDF visibility | Sender can view; signers do not see others' submissions | Same | Same | Final PDF only sent on completion; no mid-process access |

---

## Behavioral Specifications (v1.2)

### UX Flow: Agent Prepares and Sends a Multi-Signer Document

1. **Agent opens document** in portal → navigates to Prepare tab
2. **Signer entry step** (new): "Who needs to sign this document?" — agent adds rows: "Sarah Chen (sarah@example.com)" and "Mike Chen (mikec@example.com)" — clicks Save Signers
3. **Field placement**: agent uses drag-drop or AI auto-place — fields appear on canvas; each client-visible field shows a signer selector; agent assigns "Signature (Sarah)" to the buyer fields and "Signature (Mike)" to the co-buyer fields — color distinction makes it clear at a glance
4. **Validation**: agent clicks Send — system checks: all client-visible fields have a signer. If not, shows "2 fields unassigned — resolve in field placement"
5. **Dispatch**: send route creates two signing tokens, sends two emails simultaneously. Agent sees: "Signing links sent to 2 signers."
6. **Signing**: Sarah opens her link and sees only her 4 fields. She signs and submits. Mike opens his link and sees only his 3 fields. He signs and submits. (Order does not matter.)
7. **Completion**: after both submit, agent receives "All parties have signed — Sales Agreement Chen." Sarah and Mike each receive an email with the final PDF download link.

### What Happens at the Signing Page (Per Signer)

The signing page is functionally identical to the existing single-signer page with one difference: only the current signer's fields appear as interactive. The PDF renders in full — the signer can read the entire document (this is legally important — they are agreeing to the whole document, not just their fields). The interactive signature/initials/checkbox overlays appear only at the positions assigned to their email.

There is no indication of where the other signers' fields are. No greyed-out fields, no "this field belongs to someone else" markers. Clean presentation with only actionable elements visible.

### Accumulator PDF Integrity

Each signer's signing POST acquires a Postgres advisory lock keyed to the document ID, reads the current accumulator path (`doc.signedFilePath ?? doc.preparedFilePath`), embeds that signer's captured signatures at their field positions, writes the result to a new path, updates `doc.signedFilePath`, then releases the lock. This is sequential within the lock — two signers who submit simultaneously are serialized, not concurrent. The final accumulator after the last signer completes is the authoritative fully-signed document. See ARCHITECTURE.md for the full implementation detail.

---

## Sources

**Multi-signer signing behavior — DocuSign:**
- [DocuSign Trainer Tips: Mastering Signing Order](https://community.docusign.com/tips-from-docusign-155/docusign-trainer-tips-mastering-signing-order-22771) — MEDIUM confidence (community doc)
- [Quick Tip: Setting a Signing Order for Recipients — DocuSign](https://www.docusign.com/en-gb/blog/quick-tip-setting-signing-order) — HIGH confidence (official)
- [Does fully executed contract automatically get emailed back to all parties? — DocuSign Community](https://community.docusign.com/esignature-111/does-fully-executed-contracts-automatically-get-emailed-back-to-all-parties-3772) — MEDIUM confidence (confirms default completion behavior)
- [Why are documents not attached to the Completed email notification — DocuSign Support](https://support.docusign.com/s/articles/Why-are-documents-not-attached-to-the-Completed-email-notification?language=en_US) — HIGH confidence (official support)

**Multi-signer signing behavior — HelloSign / PandaDoc:**
- [PandaDoc vs HelloSign feature comparison — eSignGlobal](https://www.esignglobal.com/blog/pandadoc-vs-hellosign-comparison) — MEDIUM confidence
- [How to set up a signature workflow with multiple signers — PandaDoc Blog](https://www.pandadoc.com/blog/digital-signature-workflow/) — MEDIUM confidence
- [PandaDoc vs Hellosign: Detailed Comparison 2025 — DocuPilot](https://www.docupilot.com/vs/pandadoc-vs-hellosign) — MEDIUM confidence

**Real estate multi-signer and reminder patterns:**
- [Multi-party signing workflow — eSignGlobal](https://www.esignglobal.com/blog/multi-party-signing-workflow) — MEDIUM confidence
- [Electronic Signatures for Real Estate: 2026 Guide — DocuPilot](https://www.docupilot.com/blog/electronic-signature-for-real-estate) — MEDIUM confidence
- [Lone Wolf Authentisign — Real estate's leading eSignature solution](https://www.lwolf.com/operate/esignature) — HIGH confidence (industry tool)
- [BoldSign — E-Signature for Real Estate](https://boldsign.com/solutions/electronic-signature-for-real-estate/) — MEDIUM confidence

**Implementation architecture (codebase-derived — HIGH confidence):**
- `/Users/ccopeland/temp/red/.planning/research/ARCHITECTURE.md` — direct codebase inspection, schema decisions, data flow, build order

---
*Feature research for: Teressa Copeland Homes — v1.2 Multi-Signer Workflow*
*Researched: 2026-04-03*
