docs(05-02): complete template API handlers plan

This commit is contained in:
2026-03-12 12:11:38 +01:00
parent 387507b468
commit c8fc17c43c
3 changed files with 121 additions and 8 deletions

View File

@@ -91,7 +91,7 @@ Plans:
2. A user's template can be created and fetched via the API — it contains fixed items (with amounts) and variable items (category only, no amount) 2. A user's template can be created and fetched via the API — it contains fixed items (with amounts) and variable items (category only, no amount)
3. One-off items are excluded from template contents — the API never includes them in template responses 3. One-off items are excluded from template contents — the API never includes them in template responses
4. The template API endpoints are documented and return correct data for all three item tiers 4. The template API endpoints are documented and return correct data for all three item tiers
**Plans:** 1/2 plans executed **Plans:** 2/2 plans complete
Plans: Plans:
- [ ] 05-01-PLAN.md — DB migration (item_tier enum, templates/template_items tables) + Go models + query functions - [ ] 05-01-PLAN.md — DB migration (item_tier enum, templates/template_items tables) + Go models + query functions
@@ -153,7 +153,7 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8
| 2. Layout and Brand Identity | v1.0 | 2/2 | Complete | 2026-03-12 | | 2. Layout and Brand Identity | v1.0 | 2/2 | Complete | 2026-03-12 |
| 3. Interaction Quality and Completeness | v1.0 | 4/4 | Complete | 2026-03-12 | | 3. Interaction Quality and Completeness | v1.0 | 4/4 | Complete | 2026-03-12 |
| 4. Chart Polish and Bug Fixes | v1.0 | 2/2 | Complete | 2026-03-12 | | 4. Chart Polish and Bug Fixes | v1.0 | 2/2 | Complete | 2026-03-12 |
| 5. Template Data Model and API | 1/2 | In Progress| | - | | 5. Template Data Model and API | 2/2 | Complete | 2026-03-12 | - |
| 6. Template Frontend and Workflow Replacement | v1.1 | 0/3 | Not started | - | | 6. Template Frontend and Workflow Replacement | v1.1 | 0/3 | Not started | - |
| 7. Quick-Add Library | v1.1 | 0/2 | Not started | - | | 7. Quick-Add Library | v1.1 | 0/2 | Not started | - |
| 8. Layout and Density Rethink | v1.1 | 0/2 | Not started | - | | 8. Layout and Density Rethink | v1.1 | 0/2 | Not started | - |

View File

@@ -3,14 +3,14 @@ gsd_state_version: 1.0
milestone: v1.1 milestone: v1.1
milestone_name: Usability and Templates milestone_name: Usability and Templates
status: planning status: planning
stopped_at: Completed 05-template-data-model-and-api-01-PLAN.md stopped_at: Completed 05-template-data-model-and-api-02-PLAN.md
last_updated: "2026-03-12T11:07:58.758Z" last_updated: "2026-03-12T11:11:30.005Z"
last_activity: 2026-03-12 — v1.1 roadmap created, Phases 5-8 defined last_activity: 2026-03-12 — v1.1 roadmap created, Phases 5-8 defined
progress: progress:
total_phases: 8 total_phases: 8
completed_phases: 4 completed_phases: 5
total_plans: 12 total_plans: 12
completed_plans: 11 completed_plans: 12
percent: 0 percent: 0
--- ---
@@ -51,6 +51,7 @@ Progress: [░░░░░░░░░░] 0%
*Updated after each plan completion* *Updated after each plan completion*
| Phase 05-template-data-model-and-api P01 | 3 | 2 tasks | 4 files | | Phase 05-template-data-model-and-api P01 | 3 | 2 tasks | 4 files |
| Phase 05-template-data-model-and-api P02 | 1min | 2 tasks | 2 files |
## Accumulated Context ## Accumulated Context
@@ -67,6 +68,8 @@ Recent decisions affecting current work:
- [Phase 05-template-data-model-and-api]: New API-created budget items default to item_tier=one_off at the query layer - [Phase 05-template-data-model-and-api]: New API-created budget items default to item_tier=one_off at the query layer
- [Phase 05-template-data-model-and-api]: Template creation is lazy: CreateTemplateItem upserts template via ON CONFLICT - [Phase 05-template-data-model-and-api]: Template creation is lazy: CreateTemplateItem upserts template via ON CONFLICT
- [Phase 05-template-data-model-and-api]: GenerateBudgetFromTemplate returns BudgetExistsError struct for structured 409 response - [Phase 05-template-data-model-and-api]: GenerateBudgetFromTemplate returns BudgetExistsError struct for structured 409 response
- [Phase 05-template-data-model-and-api]: PUT /items/reorder registered before PUT /items/{itemId} for correct chi static-before-param routing
- [Phase 05-template-data-model-and-api]: GenerateBudget returns 409 JSON with budget_id field using BudgetExistsError.ExistingBudgetID
### Pending Todos ### Pending Todos
@@ -79,6 +82,6 @@ None yet.
## Session Continuity ## Session Continuity
Last session: 2026-03-12T11:07:58.757Z Last session: 2026-03-12T11:11:30.004Z
Stopped at: Completed 05-template-data-model-and-api-01-PLAN.md Stopped at: Completed 05-template-data-model-and-api-02-PLAN.md
Resume file: None Resume file: None

View File

@@ -0,0 +1,110 @@
---
phase: 05-template-data-model-and-api
plan: 02
subsystem: api
tags: [go, rest-api, templates, budget-generation, http-handlers]
requires:
- phase: 05-template-data-model-and-api
plan: 01
provides: GetTemplate, CreateTemplateItem, UpdateTemplateItem, DeleteTemplateItem, ReorderTemplateItems, GenerateBudgetFromTemplate, BudgetExistsError
provides:
- GET /api/template returns TemplateDetail (empty items when no template)
- PUT /api/template updates template name
- POST /api/template/items adds template item with validation (no one_off, fixed requires budgeted_amount)
- PUT /api/template/items/{itemId} updates template item
- DELETE /api/template/items/{itemId} removes template item (204)
- PUT /api/template/items/reorder batch-updates sort order (204)
- POST /api/budgets/generate creates budget from template or returns 409 with budget_id
- CreateBudgetItem/UpdateBudgetItem handlers already accept item_tier (done in Plan 01 auto-fix)
affects:
- 06 (frontend template UI will call these endpoints)
tech-stack:
added: []
patterns:
- errors.As for typed BudgetExistsError detection in GenerateBudget handler
- Static route /items/reorder registered before parameterized /items/{itemId} for correct chi routing
- Handler-level validation mirrors DB CHECK constraint as defense in depth
key-files:
created: []
modified:
- backend/internal/api/handlers.go
- backend/internal/api/router.go
key-decisions:
- "PUT /items/reorder registered before PUT /items/{itemId} to prevent chi treating 'reorder' as an itemId"
- "GenerateBudget returns 409 JSON with both error message and budget_id field using BudgetExistsError.ExistingBudgetID"
- "Handler validates month format via time.Parse before calling query layer (redundant but explicit)"
duration: 1min
completed: 2026-03-12
---
# Phase 5 Plan 2: Template API Handlers Summary
**HTTP handlers and routes for template CRUD, item reorder, and budget-from-template generation wired to the query layer built in Plan 01**
## Performance
- **Duration:** ~1 min
- **Started:** 2026-03-12T11:09:32Z
- **Completed:** 2026-03-12T11:10:40Z
- **Tasks:** 2
- **Files modified:** 2
## Accomplishments
- All 7 template handler methods added to handlers.go: GetTemplate, UpdateTemplateName, CreateTemplateItem, UpdateTemplateItem, DeleteTemplateItem, ReorderTemplateItems, GenerateBudget
- Handler-level validation for template items: one_off tier rejected with 400, fixed tier requires budgeted_amount
- GenerateBudget uses errors.As to detect BudgetExistsError and returns structured 409 with budget_id
- /api/template route group fully wired in router.go with correct static-before-param ordering for /items/reorder vs /items/{itemId}
- POST /api/budgets/generate placed before /{id} routes to avoid "generate" being parsed as a budget ID
- Full backend builds and vets clean
## Task Commits
Each task committed atomically:
1. **Task 1: Template handlers and budget generation handler** - `ceca2fc` (feat)
2. **Task 2: Wire routes in router.go** - `387507b` (feat)
## Files Created/Modified
- `backend/internal/api/handlers.go` - Added 7 new handler methods, added `errors` import
- `backend/internal/api/router.go` - Added /api/template route group and POST /api/budgets/generate
## Decisions Made
- `PUT /items/reorder` registered before `PUT /items/{itemId}` — chi matches static routes first when registered in order; this prevents "reorder" being treated as an itemId parameter
- `GenerateBudget` returns JSON body `{"error": "budget already exists", "budget_id": "..."}` on 409 — uses `BudgetExistsError.ExistingBudgetID` (field name established in Plan 01)
- `UpdateTemplateName` handler returns 404 for any error — since lazy creation means the only failure mode before an item exists is "no template", and connection errors are rare; consistent with UpdateCategory pattern
## Deviations from Plan
None - plan executed exactly as written. The budget item handler updates (item_tier pass-through) were already done in Plan 01's auto-fix, so Task 1 focused entirely on new template handlers.
## Issues Encountered
None.
## User Setup Required
None - no external service configuration required. Routes are live after next server start.
## Next Phase Readiness
- All REST endpoints for Phase 6 (template UI) are available
- API contract is stable: GET returns empty items array (not error) when no template exists
- 409 conflict response includes budget_id so frontend can navigate to existing budget
## Self-Check: PASSED
Both modified files verified on disk. Both task commits (ceca2fc, 387507b) present in git log. `go build ./...` and `go vet ./...` pass clean.
---
*Phase: 05-template-data-model-and-api*
*Completed: 2026-03-12*