docs(20-01): complete apply-template plan — My Templates tab + template apply branch
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -143,11 +143,11 @@
|
|||||||
|
|
||||||
### Apply Template to Document
|
### Apply Template to Document
|
||||||
|
|
||||||
- [ ] **TMPL-10**: When adding a document to a client, agent can choose "Start from template" and pick a saved template
|
- [x] **TMPL-10**: When adding a document to a client, agent can choose "Start from template" and pick a saved template
|
||||||
- [ ] **TMPL-11**: Applying a template creates a document with all template fields pre-loaded (fresh field IDs, positions, types, and role assignments copied)
|
- [x] **TMPL-11**: Applying a template creates a document with all template fields pre-loaded (fresh field IDs, positions, types, and role assignments copied)
|
||||||
- [ ] **TMPL-12**: Template signer roles are automatically mapped to the client's contacts in order (primary contact → first role, co-buyer → second role); agent can override the mapping before sending
|
- [x] **TMPL-12**: Template signer roles are automatically mapped to the client's contacts in order (primary contact → first role, co-buyer → second role); agent can override the mapping before sending
|
||||||
- [ ] **TMPL-13**: Text hints from the template appear as quick-fill suggestions in the document's PreparePanel
|
- [ ] **TMPL-13**: Text hints from the template appear as quick-fill suggestions in the document's PreparePanel
|
||||||
- [ ] **TMPL-14**: Editing a template after documents have been created from it does NOT retroactively change those documents — each document is an independent snapshot
|
- [x] **TMPL-14**: Editing a template after documents have been created from it does NOT retroactively change those documents — each document is an independent snapshot
|
||||||
|
|
||||||
### Portal Navigation
|
### Portal Navigation
|
||||||
|
|
||||||
@@ -279,11 +279,11 @@ Which phases cover which requirements. Updated during roadmap creation.
|
|||||||
| TMPL-07 | Phase 19 | Complete |
|
| TMPL-07 | Phase 19 | Complete |
|
||||||
| TMPL-08 | Phase 19 | Complete |
|
| TMPL-08 | Phase 19 | Complete |
|
||||||
| TMPL-09 | Phase 19 | Complete |
|
| TMPL-09 | Phase 19 | Complete |
|
||||||
| TMPL-10 | Phase 20 | Pending |
|
| TMPL-10 | Phase 20 | Complete |
|
||||||
| TMPL-11 | Phase 20 | Pending |
|
| TMPL-11 | Phase 20 | Complete |
|
||||||
| TMPL-12 | Phase 20 | Pending |
|
| TMPL-12 | Phase 20 | Complete |
|
||||||
| TMPL-13 | Phase 20 | Pending |
|
| TMPL-13 | Phase 20 | Pending |
|
||||||
| TMPL-14 | Phase 20 | Pending |
|
| TMPL-14 | Phase 20 | Complete |
|
||||||
| TMPL-15 | Phase 20 | Complete |
|
| TMPL-15 | Phase 20 | Complete |
|
||||||
| TMPL-16 | Phase 20 | Complete |
|
| TMPL-16 | Phase 20 | Complete |
|
||||||
|
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ Plans:
|
|||||||
**Plans**: 2 plans
|
**Plans**: 2 plans
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
- [ ] 20-01-PLAN.md — Extend POST /api/documents with template branch + Add My Templates tab to AddDocumentModal
|
- [x] 20-01-PLAN.md — Extend POST /api/documents with template branch + Add My Templates tab to AddDocumentModal
|
||||||
- [ ] 20-02-PLAN.md — Template hint quick-fill chips in PreparePanel + human E2E verification
|
- [ ] 20-02-PLAN.md — Template hint quick-fill chips in PreparePanel + human E2E verification
|
||||||
**UI hint**: yes
|
**UI hint**: yes
|
||||||
|
|
||||||
@@ -468,4 +468,4 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
|
|||||||
| 17. Docker Deployment | v1.2 | 2/2 | Complete | 2026-04-03 |
|
| 17. Docker Deployment | v1.2 | 2/2 | Complete | 2026-04-03 |
|
||||||
| 18. Template Schema and CRUD API | v1.3 | 2/2 | Complete | 2026-04-06 |
|
| 18. Template Schema and CRUD API | v1.3 | 2/2 | Complete | 2026-04-06 |
|
||||||
| 19. Template Editor UI | v1.3 | 3/3 | Complete | 2026-04-06 |
|
| 19. Template Editor UI | v1.3 | 3/3 | Complete | 2026-04-06 |
|
||||||
| 20. Apply Template and Portal Nav | v1.3 | 0/TBD | Not started | - |
|
| 20. Apply Template and Portal Nav | v1.3 | 1/2 | In Progress| |
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
gsd_state_version: 1.0
|
gsd_state_version: 1.0
|
||||||
milestone: v1.1
|
milestone: v1.1
|
||||||
milestone_name: Smart Document Preparation
|
milestone_name: Smart Document Preparation
|
||||||
status: completed
|
status: executing
|
||||||
stopped_at: Completed 19-03-PLAN.md — Phase 19 template editor UI complete, human verification passed
|
stopped_at: Completed 20-01-PLAN.md — apply template and portal nav
|
||||||
last_updated: "2026-04-06T19:55:02.977Z"
|
last_updated: "2026-04-06T20:52:20.693Z"
|
||||||
last_activity: 2026-04-06
|
last_activity: 2026-04-06
|
||||||
progress:
|
progress:
|
||||||
total_phases: 21
|
total_phases: 22
|
||||||
completed_phases: 20
|
completed_phases: 20
|
||||||
total_plans: 63
|
total_plans: 65
|
||||||
completed_plans: 62
|
completed_plans: 63
|
||||||
percent: 98
|
percent: 98
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -24,9 +24,9 @@ See: .planning/PROJECT.md (updated 2026-04-03)
|
|||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 19
|
Phase: 20 (apply-template-and-portal-nav) — EXECUTING
|
||||||
Plan: Not started
|
Plan: 2 of 2
|
||||||
Status: Phase 19 complete — Phase 20 (apply-template-and-portal-nav) ready to begin
|
Status: Ready to execute
|
||||||
Last activity: 2026-04-06
|
Last activity: 2026-04-06
|
||||||
|
|
||||||
## Note on v1.1
|
## Note on v1.1
|
||||||
@@ -108,6 +108,7 @@ Progress: [██████████████░] 98% (19/22 phases comp
|
|||||||
| Phase 19-template-editor-ui P02 | 4 | 2 tasks | 5 files |
|
| Phase 19-template-editor-ui P02 | 4 | 2 tasks | 5 files |
|
||||||
| Phase 19-template-editor-ui P03 | 1 | 1 tasks | 0 files |
|
| Phase 19-template-editor-ui P03 | 1 | 1 tasks | 0 files |
|
||||||
| Phase 19 P03 | <1 | 1 tasks | 0 files |
|
| Phase 19 P03 | <1 | 1 tasks | 0 files |
|
||||||
|
| Phase 20-apply-template-and-portal-nav P01 | 2 | 2 tasks | 2 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -202,6 +203,8 @@ Recent decisions affecting v1.1 work:
|
|||||||
- [Phase 19-02]: ConfirmDialog shown for all role removals (not just when fields > 0) — avoids async fetch for conditional UI; simpler and no UX flicker
|
- [Phase 19-02]: ConfirmDialog shown for all role removals (not just when fields > 0) — avoids async fetch for conditional UI; simpler and no UX flicker
|
||||||
- [Phase 19-03]: No code changes in Plan 03 — all deliverables complete in Plans 01 and 02; Plan 03 is pure human E2E verification
|
- [Phase 19-03]: No code changes in Plan 03 — all deliverables complete in Plans 01 and 02; Plan 03 is pure human E2E verification
|
||||||
- [Phase 19-03]: All five TMPL requirements (TMPL-05 through TMPL-09) verified by human in a single 9-step live browser test
|
- [Phase 19-03]: All five TMPL requirements (TMPL-05 through TMPL-09) verified by human in a single 9-step live browser test
|
||||||
|
- [Phase 20-apply-template-and-portal-nav]: documentTemplateId branch in POST /api/documents returns early so all existing paths unchanged; fresh crypto.randomUUID per field ensures snapshot independence
|
||||||
|
- [Phase 20-apply-template-and-portal-nav]: My Templates tab lazy-fetches /api/templates on first click via docTemplatesLoaded flag to avoid unnecessary network requests
|
||||||
|
|
||||||
### v1.2 Pre-decisions (from research)
|
### v1.2 Pre-decisions (from research)
|
||||||
|
|
||||||
@@ -237,6 +240,6 @@ None yet.
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-06T19:46:16.629Z
|
Last session: 2026-04-06T20:52:20.690Z
|
||||||
Stopped at: Completed 19-03-PLAN.md — Phase 19 template editor UI complete, human verification passed
|
Stopped at: Completed 20-01-PLAN.md — apply template and portal nav
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
---
|
||||||
|
phase: 20-apply-template-and-portal-nav
|
||||||
|
plan: "01"
|
||||||
|
subsystem: document-template-apply
|
||||||
|
tags: [templates, documents, modal, api]
|
||||||
|
dependency_graph:
|
||||||
|
requires: [phase-18-template-schema-and-crud-api, phase-19-template-editor-ui]
|
||||||
|
provides: [template-apply-to-document, my-templates-tab]
|
||||||
|
affects: [AddDocumentModal, POST /api/documents]
|
||||||
|
tech_stack:
|
||||||
|
added: []
|
||||||
|
patterns: [snapshot-copy-with-fresh-uuids, role-to-email-mapping, lazy-fetch-on-tab-switch]
|
||||||
|
key_files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- teressa-copeland-homes/src/app/api/documents/route.ts
|
||||||
|
- teressa-copeland-homes/src/app/portal/_components/AddDocumentModal.tsx
|
||||||
|
decisions:
|
||||||
|
- "documentTemplateId branch placed before fileBuffer and formTemplateId branches — returns early so existing paths are fully unchanged"
|
||||||
|
- "SIGNER_COLORS constant extracted at module level for reuse in role-to-email mapping"
|
||||||
|
- "resolvedFormTemplateId used (not reassigning formTemplateId let var) to avoid confusion with the existing library branch variable"
|
||||||
|
- "handleSwitchToTemplates lazy-fetches only on first click — docTemplatesLoaded flag prevents repeated fetches on tab toggle"
|
||||||
|
- "handleSelectDocTemplate clears selectedTemplate and customFile for mutual exclusivity; handleSelectTemplate now also clears selectedDocTemplate"
|
||||||
|
metrics:
|
||||||
|
duration_minutes: 2
|
||||||
|
completed_date: "2026-04-06"
|
||||||
|
tasks_completed: 2
|
||||||
|
files_modified: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 20 Plan 01: Apply Template and Portal Nav Summary
|
||||||
|
|
||||||
|
**One-liner:** Template apply branch in POST /api/documents copies fields with fresh UUIDs and maps signer roles to client contacts; AddDocumentModal gains a My Templates tab with lazy-loaded template list.
|
||||||
|
|
||||||
|
## Tasks Completed
|
||||||
|
|
||||||
|
| # | Task | Commit | Files |
|
||||||
|
|---|------|--------|-------|
|
||||||
|
| 1 | Extend POST /api/documents with documentTemplateId branch | bdf0cb0 | src/app/api/documents/route.ts |
|
||||||
|
| 2 | Add My Templates tab to AddDocumentModal | 2947fa5 | src/app/portal/_components/AddDocumentModal.tsx |
|
||||||
|
|
||||||
|
## What Was Built
|
||||||
|
|
||||||
|
### Task 1 — POST /api/documents template branch
|
||||||
|
|
||||||
|
Extended the JSON body path of the POST handler to accept `documentTemplateId`. When provided:
|
||||||
|
|
||||||
|
1. Fetches the `documentTemplates` record with its `formTemplate` relation (for the PDF filename)
|
||||||
|
2. Copies the PDF from `seeds/forms/` using the form template's filename
|
||||||
|
3. Maps every field to a new object with a fresh `crypto.randomUUID()` — template field IDs never appear in documents
|
||||||
|
4. Collects unique signer role labels (stored in `signerEmail` on template fields) in order of first appearance
|
||||||
|
5. Fetches the client record and builds `clientEmails = [client.email, ...contacts[].email]`
|
||||||
|
6. Maps roles to emails: role[0] → clientEmails[0], role[1] → clientEmails[1], etc.; falls back to the role label if no email at that index
|
||||||
|
7. Inserts the document with `signatureFields: copiedFields` and `signers: mappedSigners` and returns 201
|
||||||
|
|
||||||
|
The existing custom-upload path and form-library path are completely unchanged.
|
||||||
|
|
||||||
|
### Task 2 — AddDocumentModal My Templates tab
|
||||||
|
|
||||||
|
Added a two-tab UI (Forms Library | My Templates) to the AddDocumentModal:
|
||||||
|
|
||||||
|
- Tab bar uses underline-style active indicator matching project Tailwind conventions
|
||||||
|
- My Templates tab lazy-fetches `GET /api/templates` on first click via `docTemplatesLoaded` flag
|
||||||
|
- Empty state shown when no templates exist; loading state shown while fetching
|
||||||
|
- Template rows show name, form name, and field count
|
||||||
|
- Selecting a template clears `selectedTemplate` and `customFile` (mutual exclusivity)
|
||||||
|
- Selecting a form or uploading a file clears `selectedDocTemplate`
|
||||||
|
- `handleSubmit` has a new top branch: when `selectedDocTemplate` is set, sends `documentTemplateId` to POST /api/documents as JSON
|
||||||
|
- Guard condition and submit button disabled state both updated to include `selectedDocTemplate`
|
||||||
|
- All existing Forms Library and custom upload markup preserved exactly — only wrapped in `activeTab === 'forms'` conditional
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
- `npx tsc --noEmit` — zero type errors (both tasks)
|
||||||
|
- `npm run build` — production build succeeds
|
||||||
|
- `documentTemplateId` present in route.ts (4 matches) and AddDocumentModal.tsx (1 match)
|
||||||
|
- `crypto.randomUUID` present in route.ts (2 matches: docId + field copy)
|
||||||
|
- `SIGNER_COLORS` present in route.ts
|
||||||
|
- `activeTab` (5 matches) and `selectedDocTemplate` (6 matches) in AddDocumentModal.tsx
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
### Plan Adjustments
|
||||||
|
|
||||||
|
**handleFileChange also clears selectedDocTemplate** — The plan specified mutual exclusivity in `handleSelectTemplate` and `handleSelectDocTemplate`, but `handleFileChange` (custom file picker) also needed to clear `selectedDocTemplate` to maintain full mutual exclusivity across all three selection paths. Added `setSelectedDocTemplate(null)` to `handleFileChange`. This is a completeness fix, not a deviation from intent.
|
||||||
|
|
||||||
|
**resolvedFormTemplateId instead of reassigning formTemplateId** — The plan showed `formTemplateId = docTemplate.formTemplateId` to override the let variable. Instead used a new `const resolvedFormTemplateId` to avoid modifying a shared variable that existing branches also read. Cleaner and avoids any unintended side effects.
|
||||||
|
|
||||||
|
## Known Stubs
|
||||||
|
|
||||||
|
None — all data paths are fully wired. The template apply branch fetches real data from the database and inserts real documents with copied fields and mapped signers.
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
Files exist:
|
||||||
|
- FOUND: teressa-copeland-homes/src/app/api/documents/route.ts
|
||||||
|
- FOUND: teressa-copeland-homes/src/app/portal/_components/AddDocumentModal.tsx
|
||||||
|
|
||||||
|
Commits exist:
|
||||||
|
- bdf0cb0 — feat(20-01): extend POST /api/documents with documentTemplateId branch
|
||||||
|
- 2947fa5 — feat(20-01): add My Templates tab to AddDocumentModal
|
||||||
Reference in New Issue
Block a user