From 78d579f965d80f518563610a4d0a355bd20d59e9 Mon Sep 17 00:00:00 2001 From: Chandler Copeland Date: Mon, 6 Apr 2026 14:52:31 -0600 Subject: [PATCH] =?UTF-8?q?docs(20-01):=20complete=20apply-template=20plan?= =?UTF-8?q?=20=E2=80=94=20My=20Templates=20tab=20+=20template=20apply=20br?= =?UTF-8?q?anch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .planning/REQUIREMENTS.md | 16 +-- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 25 +++-- .../20-01-SUMMARY.md | 105 ++++++++++++++++++ 4 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 .planning/phases/20-apply-template-and-portal-nav/20-01-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index c962988..93dcdef 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -143,11 +143,11 @@ ### Apply Template to Document -- [ ] **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) -- [ ] **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-10**: When adding a document to a client, agent can choose "Start from template" and pick a saved template +- [x] **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-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-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 @@ -279,11 +279,11 @@ Which phases cover which requirements. Updated during roadmap creation. | TMPL-07 | Phase 19 | Complete | | TMPL-08 | Phase 19 | Complete | | TMPL-09 | Phase 19 | Complete | -| TMPL-10 | Phase 20 | Pending | -| TMPL-11 | Phase 20 | Pending | -| TMPL-12 | Phase 20 | Pending | +| TMPL-10 | Phase 20 | Complete | +| TMPL-11 | Phase 20 | Complete | +| TMPL-12 | Phase 20 | Complete | | TMPL-13 | Phase 20 | Pending | -| TMPL-14 | Phase 20 | Pending | +| TMPL-14 | Phase 20 | Complete | | TMPL-15 | Phase 20 | Complete | | TMPL-16 | Phase 20 | Complete | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 26ae1c3..726028c 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -436,7 +436,7 @@ Plans: **Plans**: 2 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 **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 | | 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 | -| 20. Apply Template and Portal Nav | v1.3 | 0/TBD | Not started | - | +| 20. Apply Template and Portal Nav | v1.3 | 1/2 | In Progress| | diff --git a/.planning/STATE.md b/.planning/STATE.md index 988e94a..1839a39 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,15 +2,15 @@ gsd_state_version: 1.0 milestone: v1.1 milestone_name: Smart Document Preparation -status: completed -stopped_at: Completed 19-03-PLAN.md — Phase 19 template editor UI complete, human verification passed -last_updated: "2026-04-06T19:55:02.977Z" +status: executing +stopped_at: Completed 20-01-PLAN.md — apply template and portal nav +last_updated: "2026-04-06T20:52:20.693Z" last_activity: 2026-04-06 progress: - total_phases: 21 + total_phases: 22 completed_phases: 20 - total_plans: 63 - completed_plans: 62 + total_plans: 65 + completed_plans: 63 percent: 98 --- @@ -24,9 +24,9 @@ See: .planning/PROJECT.md (updated 2026-04-03) ## Current Position -Phase: 19 -Plan: Not started -Status: Phase 19 complete — Phase 20 (apply-template-and-portal-nav) ready to begin +Phase: 20 (apply-template-and-portal-nav) — EXECUTING +Plan: 2 of 2 +Status: Ready to execute Last activity: 2026-04-06 ## 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 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 @@ -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-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 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) @@ -237,6 +240,6 @@ None yet. ## Session Continuity -Last session: 2026-04-06T19:46:16.629Z -Stopped at: Completed 19-03-PLAN.md — Phase 19 template editor UI complete, human verification passed +Last session: 2026-04-06T20:52:20.690Z +Stopped at: Completed 20-01-PLAN.md — apply template and portal nav Resume file: None diff --git a/.planning/phases/20-apply-template-and-portal-nav/20-01-SUMMARY.md b/.planning/phases/20-apply-template-and-portal-nav/20-01-SUMMARY.md new file mode 100644 index 0000000..c57383c --- /dev/null +++ b/.planning/phases/20-apply-template-and-portal-nav/20-01-SUMMARY.md @@ -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