Files

259 lines
11 KiB
Markdown

---
phase: 20-apply-template-and-portal-nav
plan: 02
type: execute
wave: 2
depends_on: [20-01]
files_modified:
- teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/DocumentPageClient.tsx
- teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/PreparePanel.tsx
autonomous: false
requirements: [TMPL-13, TMPL-15, TMPL-16]
must_haves:
truths:
- "When agent selects a text field that has a hint (from template), a 'Template Hint' chip appears in the Quick Fill section of PreparePanel"
- "Clicking the hint chip fills the selected field with the hint text (same behavior as existing quick-fill)"
- "Fields without hints show no extra chip — existing quick-fill behavior unchanged"
- "Templates nav link exists in portal navigation (Phase 19, already done)"
- "Templates list page shows all templates with form name, field count, last-updated (Phase 19, already done)"
artifacts:
- path: "teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/DocumentPageClient.tsx"
provides: "Fields state fetch + selectedFieldHint derivation"
contains: "selectedFieldHint"
- path: "teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/PreparePanel.tsx"
provides: "Template Hint chip in Quick Fill section"
contains: "selectedFieldHint"
key_links:
- from: "DocumentPageClient.tsx"
to: "GET /api/documents/:docId/fields"
via: "fetch on mount + aiPlacementKey change"
pattern: "api/documents.*fields"
- from: "DocumentPageClient.tsx"
to: "PreparePanel"
via: "selectedFieldHint prop"
pattern: "selectedFieldHint="
- from: "PreparePanel.tsx"
to: "onQuickFill callback"
via: "hint chip onClick"
pattern: "Template Hint"
---
<objective>
Surface template text hints as quick-fill suggestions in PreparePanel and verify the complete Phase 20 feature set with human testing.
Purpose: When a document is created from a template, text fields with hints (e.g., "Property Address", "Purchase Price") show those hints as one-click quick-fill chips, saving the agent from remembering what each blank field is for.
Output: Modified DocumentPageClient.tsx (fields state + hint derivation), modified PreparePanel.tsx (hint chip), human verification of the full template-to-document flow.
</objective>
<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/20-apply-template-and-portal-nav/20-CONTEXT.md
@.planning/phases/20-apply-template-and-portal-nav/20-RESEARCH.md
@.planning/phases/20-apply-template-and-portal-nav/20-01-SUMMARY.md
<interfaces>
<!-- Key types and contracts from codebase. -->
From src/app/portal/(protected)/documents/[docId]/_components/DocumentPageClient.tsx:
```typescript
interface DocumentPageClientProps {
docId: string;
docStatus: string;
defaultEmail: string;
clientName: string;
agentDownloadUrl?: string | null;
signedAt?: Date | null;
clientPropertyAddress?: string | null;
initialSigners: DocumentSigner[];
clientContacts?: { name: string; email: string }[];
}
// Existing state:
// selectedFieldId: string | null
// textFillData: Record<string, string>
// aiPlacementKey: number
// signers: DocumentSigner[]
```
From src/app/portal/(protected)/documents/[docId]/_components/PreparePanel.tsx:
```typescript
interface PreparePanelProps {
docId: string;
defaultEmail: string;
clientName: string;
currentStatus: string;
agentDownloadUrl?: string | null;
signedAt?: Date | null;
clientPropertyAddress?: string | null;
previewToken: string | null;
onPreviewTokenChange: (token: string | null) => void;
textFillData: Record<string, string>;
selectedFieldId: string | null;
onQuickFill: (fieldId: string, value: string) => void;
onAiAutoPlace: () => Promise<void>;
signers?: DocumentSigner[];
onSignersChange?: (signers: DocumentSigner[]) => void;
unassignedFieldIds?: Set<string>;
onUnassignedFieldIdsChange?: (ids: Set<string>) => void;
}
```
Quick Fill section pattern (PreparePanel lines 313-355):
```typescript
{/* Quick-fill panel — only shown when a text field is selected */}
{selectedFieldId ? (
<div className="space-y-1.5">
<p className="text-xs text-gray-400">Click a suggestion to fill the selected field.</p>
{clientName && ( <button onClick={() => onQuickFill(selectedFieldId, clientName)}>...</button> )}
{clientPropertyAddress && ( <button onClick={() => onQuickFill(selectedFieldId, clientPropertyAddress)}>...</button> )}
<button onClick={() => onQuickFill(selectedFieldId, defaultEmail)}>Client Email chip</button>
</div>
) : (
<p>Click a text field on the document...</p>
)}
```
</interfaces>
</context>
<tasks>
<task type="auto">
<name>Task 1: Add fields state to DocumentPageClient and pass selectedFieldHint to PreparePanel</name>
<files>
teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/DocumentPageClient.tsx
teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/PreparePanel.tsx
</files>
<read_first>
teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/DocumentPageClient.tsx
teressa-copeland-homes/src/app/portal/(protected)/documents/[docId]/_components/PreparePanel.tsx
teressa-copeland-homes/src/lib/db/schema.ts
</read_first>
<action>
**In DocumentPageClient.tsx:**
1. Add import: `import type { SignatureFieldData } from '@/lib/db/schema';` (DocumentSigner is already imported).
2. Add state for fields:
```typescript
const [fields, setFields] = useState<SignatureFieldData[]>([]);
```
3. Add useEffect to fetch fields on mount and when aiPlacementKey changes:
```typescript
useEffect(() => {
fetch(`/api/documents/${docId}/fields`)
.then(r => r.json())
.then((data: SignatureFieldData[]) => setFields(Array.isArray(data) ? data : []))
.catch(() => {});
}, [docId, aiPlacementKey]);
```
4. Derive the hint for the selected field:
```typescript
const selectedFieldHint = selectedFieldId
? fields.find(f => f.id === selectedFieldId)?.hint
: undefined;
```
5. Pass new prop to PreparePanel:
```typescript
<PreparePanel
// ... all existing props unchanged ...
selectedFieldHint={selectedFieldHint}
/>
```
**In PreparePanel.tsx:**
1. Add `selectedFieldHint?: string;` to the `PreparePanelProps` interface (after `onQuickFill`).
2. Destructure it in the function signature: add `selectedFieldHint,` to the destructured props.
3. In the Quick Fill section (inside the `{selectedFieldId ? (` branch), add a new chip AFTER the existing Client Email chip button (before the closing `</div>` of `space-y-1.5`):
```tsx
{selectedFieldHint && (
<button
type="button"
onClick={() => onQuickFill(selectedFieldId, selectedFieldHint)}
className="w-full text-left px-3 py-2 text-sm border rounded bg-white hover:bg-blue-50 hover:border-blue-300 transition-colors"
>
<span className="text-xs text-gray-400 block">Template Hint</span>
<span className="truncate block">{selectedFieldHint}</span>
</button>
)}
```
This follows the exact same markup pattern as the existing Client Name / Property Address / Client Email chips. The prop is optional with no default — existing callers (DocumentPageClient without template-sourced documents) simply don't pass it, and `undefined` means no chip renders.
</action>
<verify>
<automated>cd teressa-copeland-homes && npx tsc --noEmit</automated>
</verify>
<acceptance_criteria>
- grep "selectedFieldHint" src/app/portal/\(protected\)/documents/\[docId\]/_components/DocumentPageClient.tsx returns at least 2 matches (derivation + prop pass)
- grep "selectedFieldHint" src/app/portal/\(protected\)/documents/\[docId\]/_components/PreparePanel.tsx returns at least 3 matches (interface + destructure + render)
- grep "Template Hint" src/app/portal/\(protected\)/documents/\[docId\]/_components/PreparePanel.tsx returns 1 match
- grep "api/documents.*fields" src/app/portal/\(protected\)/documents/\[docId\]/_components/DocumentPageClient.tsx returns at least 1 match
- grep "SignatureFieldData" src/app/portal/\(protected\)/documents/\[docId\]/_components/DocumentPageClient.tsx returns at least 1 match (import)
- npx tsc --noEmit exits 0
</acceptance_criteria>
<done>DocumentPageClient fetches fields on mount, derives selectedFieldHint from selected field, passes it to PreparePanel. PreparePanel renders a "Template Hint" quick-fill chip when the hint exists.</done>
</task>
<task type="checkpoint:human-verify" gate="blocking">
<name>Task 2: Human verification of full template-to-document flow</name>
<what-built>
Complete "Start from template" feature:
- My Templates tab in Add Document modal (Plan 01)
- Template apply with fresh field UUIDs and role mapping (Plan 01)
- Text hint quick-fill chips in PreparePanel (Plan 02 Task 1)
- Templates nav + list page (Phase 19, already live)
</what-built>
<how-to-verify>
Prerequisites: At least one saved template with fields and text hints must exist (created in Phase 19 testing).
1. Navigate to /portal/templates — verify the list page shows saved templates with form name, field count, and updated date (TMPL-16)
2. Verify "Templates" appears in the portal top nav (TMPL-15)
3. Go to a client profile page → click "Add Document"
4. Verify the modal shows two tabs: "Forms Library" and "My Templates" (TMPL-10)
5. Click "My Templates" tab → verify saved templates appear with name, form name, and field count
6. Select a template → verify the document name auto-fills with the template name
7. Click "Add Document" → verify the document is created and you're returned to the client page
8. Open the newly created document → verify fields are pre-loaded at the correct positions on the PDF (TMPL-11)
9. In PreparePanel, click a text field that has a hint → verify a "Template Hint" chip appears in the Quick Fill section alongside Client Name/Address/Email (TMPL-13)
10. Click the hint chip → verify the field is filled with the hint text
11. Click the "Forms Library" tab back in a new Add Document modal → verify the existing form library still works exactly as before (D-04)
12. (TMPL-14 — snapshot independence): Go to /portal/templates → edit the template (change a field position) → go back to the document created in step 7 → verify the document's fields are unchanged (still at original positions)
</how-to-verify>
<resume-signal>Type "approved" or describe any issues found</resume-signal>
</task>
</tasks>
<verification>
1. `cd teressa-copeland-homes && npx tsc --noEmit` — zero type errors
2. `cd teressa-copeland-homes && npm run build` — production build succeeds
3. Human verification confirms all 12 steps pass
4. TMPL-10 through TMPL-16 all satisfied (TMPL-14/15/16 by design or Phase 19)
</verification>
<success_criteria>
- Template Hint chip appears in Quick Fill when a text field with a hint is selected
- Chip click fills the field (same behavior as existing quick-fill chips)
- Fields without hints show no extra chip
- Human confirms full template-to-document flow works end-to-end
- All 7 TMPL requirements (TMPL-10 through TMPL-16) are satisfied
</success_criteria>
<output>
After completion, create `.planning/phases/20-apply-template-and-portal-nav/20-02-SUMMARY.md`
</output>