docs(18-02): complete template CRUD API plan
- 18-02-SUMMARY.md: GET/POST/PATCH/DELETE routes with soft-delete and auth guard - STATE.md: advanced to plan 2/2, progress 98%, decisions recorded - ROADMAP.md: Phase 18 marked Complete (2/2 plans)
This commit is contained in:
@@ -186,7 +186,7 @@ Plans:
|
|||||||
|
|
||||||
**Milestone Goal:** Agent creates reusable document templates with pre-placed fields (including AI auto-placement) so the same PDF never needs to be field-mapped from scratch for every client.
|
**Milestone Goal:** Agent creates reusable document templates with pre-placed fields (including AI auto-placement) so the same PDF never needs to be field-mapped from scratch for every client.
|
||||||
|
|
||||||
- [ ] **Phase 18: Template Schema and CRUD API** - New `document_templates` table with Drizzle migration; list, create, rename, and soft-delete API routes
|
- [x] **Phase 18: Template Schema and CRUD API** - New `document_templates` table with Drizzle migration; list, create, rename, and soft-delete API routes (completed 2026-04-06)
|
||||||
- [ ] **Phase 19: Template Editor UI** - FieldPlacer `onPersist` abstraction, template editor page at `/portal/templates/[id]`, AI auto-place wired to template context, signer role label support, save template
|
- [ ] **Phase 19: Template Editor UI** - FieldPlacer `onPersist` abstraction, template editor page at `/portal/templates/[id]`, AI auto-place wired to template context, signer role label support, save template
|
||||||
- [ ] **Phase 20: Apply Template and Portal Nav** - "Start from template" option in AddDocumentModal, apply operation with field snapshot and role-to-email mapping, text hint quick-fill, Templates portal nav section and list page
|
- [ ] **Phase 20: Apply Template and Portal Nav** - "Start from template" option in AddDocumentModal, apply operation with field snapshot and role-to-email mapping, text hint quick-fill, Templates portal nav section and list page
|
||||||
|
|
||||||
@@ -400,7 +400,7 @@ Plans:
|
|||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
- [x] 18-01-PLAN.md — Drizzle schema: documentTemplates table definition + 0012 migration
|
- [x] 18-01-PLAN.md — Drizzle schema: documentTemplates table definition + 0012 migration
|
||||||
- [ ] 18-02-PLAN.md — CRUD API routes: GET/POST /api/templates, PATCH/DELETE /api/templates/[id]
|
- [x] 18-02-PLAN.md — CRUD API routes: GET/POST /api/templates, PATCH/DELETE /api/templates/[id]
|
||||||
**UI hint**: no
|
**UI hint**: no
|
||||||
|
|
||||||
### Phase 19: Template Editor UI
|
### Phase 19: Template Editor UI
|
||||||
@@ -455,6 +455,6 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
|
|||||||
| 15. Multi-Signer Backend | v1.2 | 3/3 | Complete | 2026-04-03 |
|
| 15. Multi-Signer Backend | v1.2 | 3/3 | Complete | 2026-04-03 |
|
||||||
| 16. Multi-Signer UI | v1.2 | 1/4 | Complete | 2026-04-03 |
|
| 16. Multi-Signer UI | v1.2 | 1/4 | Complete | 2026-04-03 |
|
||||||
| 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 | 1/2 | In Progress| |
|
| 18. Template Schema and CRUD API | v1.3 | 2/2 | Complete | 2026-04-06 |
|
||||||
| 19. Template Editor UI | v1.3 | 0/TBD | Not started | - |
|
| 19. Template Editor UI | v1.3 | 0/TBD | Not started | - |
|
||||||
| 20. Apply Template and Portal Nav | v1.3 | 0/TBD | Not started | - |
|
| 20. Apply Template and Portal Nav | v1.3 | 0/TBD | Not started | - |
|
||||||
|
|||||||
@@ -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: executing
|
status: verifying
|
||||||
stopped_at: Completed 18-01-PLAN.md — documentTemplates schema and migration 0012
|
stopped_at: Completed 18-02-PLAN.md — template CRUD API routes (GET, POST, PATCH, DELETE)
|
||||||
last_updated: "2026-04-06T18:15:59.504Z"
|
last_updated: "2026-04-06T18:18:26.395Z"
|
||||||
last_activity: 2026-04-06
|
last_activity: 2026-04-06
|
||||||
progress:
|
progress:
|
||||||
total_phases: 20
|
total_phases: 20
|
||||||
completed_phases: 18
|
completed_phases: 19
|
||||||
total_plans: 60
|
total_plans: 60
|
||||||
completed_plans: 58
|
completed_plans: 59
|
||||||
percent: 82
|
percent: 82
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-04-03)
|
|||||||
|
|
||||||
Phase: 18 (template-schema-and-crud-api) — EXECUTING
|
Phase: 18 (template-schema-and-crud-api) — EXECUTING
|
||||||
Plan: 2 of 2
|
Plan: 2 of 2
|
||||||
Status: Ready to execute
|
Status: Phase complete — ready for verification
|
||||||
Last activity: 2026-04-06
|
Last activity: 2026-04-06
|
||||||
|
|
||||||
## Note on v1.1
|
## Note on v1.1
|
||||||
@@ -104,6 +104,7 @@ Progress: [████████████░░░] 82% (18/22 phases comp
|
|||||||
| Phase 17-docker-deployment P01 | 2 | 2 tasks | 4 files |
|
| Phase 17-docker-deployment P01 | 2 | 2 tasks | 4 files |
|
||||||
| Phase 17 P02 | 3 | 3 tasks | 6 files |
|
| Phase 17 P02 | 3 | 3 tasks | 6 files |
|
||||||
| Phase 18-template-schema-and-crud-api P01 | 4 | 2 tasks | 2 files |
|
| Phase 18-template-schema-and-crud-api P01 | 4 | 2 tasks | 2 files |
|
||||||
|
| Phase 18-template-schema-and-crud-api P02 | 3 | 2 tasks | 2 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -192,6 +193,8 @@ Recent decisions affecting v1.1 work:
|
|||||||
- [Phase 18-template-schema-and-crud-api]: signatureFields nullable JSONB: template starts empty; Phase 19 fills it via PATCH
|
- [Phase 18-template-schema-and-crud-api]: signatureFields nullable JSONB: template starts empty; Phase 19 fills it via PATCH
|
||||||
- [Phase 18-template-schema-and-crud-api]: formTemplateId FK has no onDelete cascade: archived templates remain even if form is removed
|
- [Phase 18-template-schema-and-crud-api]: formTemplateId FK has no onDelete cascade: archived templates remain even if form is removed
|
||||||
- [Phase 18-template-schema-and-crud-api]: archivedAt nullable timestamp: NULL = active, soft-delete only
|
- [Phase 18-template-schema-and-crud-api]: archivedAt nullable timestamp: NULL = active, soft-delete only
|
||||||
|
- [Phase 18-template-schema-and-crud-api]: fieldCount derived server-side as (signatureFields ?? []).length per D-12 — not stored in DB
|
||||||
|
- [Phase 18-template-schema-and-crud-api]: POST validates FK existence before INSERT to return 404 not 500 on bad formTemplateId
|
||||||
|
|
||||||
### v1.2 Pre-decisions (from research)
|
### v1.2 Pre-decisions (from research)
|
||||||
|
|
||||||
@@ -227,6 +230,6 @@ None yet.
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-06T18:15:59.498Z
|
Last session: 2026-04-06T18:18:26.391Z
|
||||||
Stopped at: Completed 18-01-PLAN.md — documentTemplates schema and migration 0012
|
Stopped at: Completed 18-02-PLAN.md — template CRUD API routes (GET, POST, PATCH, DELETE)
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
---
|
||||||
|
phase: 18-template-schema-and-crud-api
|
||||||
|
plan: "02"
|
||||||
|
subsystem: api
|
||||||
|
tags: [drizzle, next-app-router, rest-api, soft-delete, postgresql]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 18-01
|
||||||
|
provides: documentTemplates Drizzle table + 0012 migration
|
||||||
|
|
||||||
|
provides:
|
||||||
|
- GET /api/templates — list active templates with formName JOIN and computed fieldCount
|
||||||
|
- POST /api/templates — create template with name + formTemplateId FK validation
|
||||||
|
- PATCH /api/templates/[id] — rename and/or update signatureFields with explicit updatedAt
|
||||||
|
- DELETE /api/templates/[id] — soft-delete via archivedAt (no hard delete)
|
||||||
|
|
||||||
|
affects: [Phase 19 template editor UI, Phase 20 apply-template endpoint]
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns: [soft-delete filter (isNull archivedAt), LEFT JOIN for computed field, explicit updatedAt on every UPDATE]
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- teressa-copeland-homes/src/app/api/templates/route.ts
|
||||||
|
- teressa-copeland-homes/src/app/api/templates/[id]/route.ts
|
||||||
|
modified: []
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "fieldCount derived server-side as (signatureFields ?? []).length — not stored in DB per D-12"
|
||||||
|
- "PATCH guards against archived templates via isNull(archivedAt) before update — archived templates return 404"
|
||||||
|
- "DELETE sets archivedAt + updatedAt atomically in a single UPDATE statement, returns 204 No Content"
|
||||||
|
- "POST validates FK existence via db.query.formTemplates.findFirst before INSERT — returns 404 not 500 on bad FK"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Soft-delete list filter: .where(isNull(documentTemplates.archivedAt)) in GET handler"
|
||||||
|
- "Soft-delete guard in mutating handlers: findFirst with and(eq(id), isNull(archivedAt)) → 404 if missing/archived"
|
||||||
|
- "Explicit updatedAt: new Date() in every UPDATE per D-05 pattern"
|
||||||
|
|
||||||
|
requirements-completed: [TMPL-01, TMPL-02, TMPL-03, TMPL-04]
|
||||||
|
|
||||||
|
duration: 3min
|
||||||
|
completed: 2026-04-06
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 18 Plan 02: Template CRUD API Summary
|
||||||
|
|
||||||
|
**Four REST handlers at /api/templates providing full CRUD with soft-delete, auth guard, FK validation, and computed fieldCount via LEFT JOIN on formTemplates.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** ~3 min
|
||||||
|
- **Started:** 2026-04-06T18:16:47Z
|
||||||
|
- **Completed:** 2026-04-06T18:19:30Z
|
||||||
|
- **Tasks:** 2
|
||||||
|
- **Files modified:** 2
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- GET /api/templates lists active templates only (archivedAt IS NULL) with formName from joined formTemplates and computed fieldCount
|
||||||
|
- POST /api/templates validates name + formTemplateId, checks FK exists in formTemplates, inserts and returns 201
|
||||||
|
- PATCH /api/templates/[id] handles rename and signatureFields update with explicit updatedAt, guards archived templates
|
||||||
|
- DELETE /api/templates/[id] soft-deletes via archivedAt = new Date() per D-07, returns 204 — never removes the row
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
1. **Task 1: Create GET and POST routes at /api/templates** - `28c7773` (feat)
|
||||||
|
2. **Task 2: Create PATCH and DELETE routes at /api/templates/[id]** - `12a74fc` (feat)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `teressa-copeland-homes/src/app/api/templates/route.ts` — GET (list active templates with JOIN) and POST (create with FK validation)
|
||||||
|
- `teressa-copeland-homes/src/app/api/templates/[id]/route.ts` — PATCH (rename/update fields, explicit updatedAt) and DELETE (soft-delete via archivedAt)
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- PATCH returns 404 for archived templates (guards via `and(eq(id), isNull(archivedAt))`) — ensures mutating handlers do not resurrect archived templates accidentally
|
||||||
|
- POST verifies `formTemplateId` FK exists before INSERT, returning 404 with a clear error message rather than letting the DB constraint throw a 500
|
||||||
|
- DELETE returns 204 No Content on success (no body) — matches REST convention for soft-delete confirmation
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None - plan executed exactly as written.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- All four CRUD routes are ready for Phase 19 (template editor UI)
|
||||||
|
- Phase 19 will call GET to list templates, POST to create, PATCH with signatureFields to save field layout, and optionally DELETE
|
||||||
|
- Phase 20 (apply template) will call GET to pick a template, then read signatureFields to stamp fresh UUIDs at apply time
|
||||||
|
- No blockers. TypeScript compiles clean.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 18-template-schema-and-crud-api*
|
||||||
|
*Completed: 2026-04-06*
|
||||||
Reference in New Issue
Block a user