fix(07): revise plans based on checker feedback

This commit is contained in:
2026-03-12 13:30:10 +01:00
parent c57311adb4
commit cccac351cf
2 changed files with 8 additions and 5 deletions

View File

@@ -15,7 +15,7 @@ requirements: [QADD-01, QADD-03]
must_haves: must_haves:
truths: truths:
- "A quick_add_items table exists with user_id, name, icon, and sort_order columns" - "The API accepts and returns quick-add items with name, icon, and sort_order in all CRUD responses"
- "API returns a list of quick-add items for the authenticated user" - "API returns a list of quick-add items for the authenticated user"
- "API can create, update, and delete quick-add items" - "API can create, update, and delete quick-add items"
- "Quick-add items are user-scoped — one user cannot see another's items" - "Quick-add items are user-scoped — one user cannot see another's items"

View File

@@ -80,6 +80,7 @@ Output: QuickAddPage, QuickAddPicker component, useQuickAdd hook, API client add
@frontend/src/pages/TemplatePage.tsx @frontend/src/pages/TemplatePage.tsx
@frontend/src/pages/DashboardPage.tsx @frontend/src/pages/DashboardPage.tsx
@frontend/src/components/AppLayout.tsx @frontend/src/components/AppLayout.tsx
@frontend/src/components/EmptyState.tsx
@frontend/src/App.tsx @frontend/src/App.tsx
@frontend/src/i18n/en.json @frontend/src/i18n/en.json
@frontend/src/i18n/de.json @frontend/src/i18n/de.json
@@ -187,7 +188,7 @@ const navItems = [
- Table with columns: Name, Icon, Actions (Edit pencil button, Delete trash button) - Table with columns: Name, Icon, Actions (Edit pencil button, Delete trash button)
- Edit mode: clicking edit turns row into inline inputs, Save/Cancel buttons - Edit mode: clicking edit turns row into inline inputs, Save/Cancel buttons
- Delete: immediate delete (no confirmation needed for library items — they are presets, not budget data) - Delete: immediate delete (no confirmation needed for library items — they are presets, not budget data)
- Empty state: use EmptyState component with Zap icon, heading "No saved items", subtext "Save your frequently-used one-off categories here for quick access." - Empty state: use the project's existing `EmptyState` component (`frontend/src/components/EmptyState.tsx`) with Zap icon, heading "No saved items", subtext "Save your frequently-used one-off categories here for quick access."
4. **Sidebar nav** (`frontend/src/components/AppLayout.tsx`): 4. **Sidebar nav** (`frontend/src/components/AppLayout.tsx`):
Add nav item after template: `{ path: '/quick-add', label: t('nav.quickAdd'), icon: Zap }` Add nav item after template: `{ path: '/quick-add', label: t('nav.quickAdd'), icon: Zap }`
@@ -256,9 +257,11 @@ const navItems = [
- On mount, fetch quick-add items via `quickAdd.list()` (direct API call, not hook — this is a lightweight picker, not a full CRUD page) - On mount, fetch quick-add items via `quickAdd.list()` (direct API call, not hook — this is a lightweight picker, not a full CRUD page)
- Render a Popover (from shadcn/ui) with trigger button: icon `Zap` + text "Quick Add" (from i18n `quickAdd.addOneOff`) - Render a Popover (from shadcn/ui) with trigger button: icon `Zap` + text "Quick Add" (from i18n `quickAdd.addOneOff`)
- Inside popover: list of quick-add items, each as a clickable row showing icon + name - Inside popover: list of quick-add items, each as a clickable row showing icon + name
- On click: create a budget item via `budgetItems.create(budgetId, { category_id: null, item_tier: 'one_off', notes: item.name })` — Since quick-add items are independent presets (not linked to categories), the picker creates a one-off budget item. The backend CreateBudgetItem handler must accept this. **However**, looking at the existing BudgetItem model, category_id is required (UUID NOT NULL in DB). So instead: - On click, resolve the category_id then create the budget item. Since category_id is NOT NULL in the DB, the picker must find or create a matching category:
- The picker should first check if a category with the same name exists for the user. If not, create one via `categories.create({ name: item.name, type: 'variable_expense', icon: item.icon })`, then create the budget item with that category_id and `item_tier: 'one_off'`. 1. Fetch the user's categories via `categories.list()`
- Alternatively (simpler): show the quick-add library items, and on click, find or create a matching category, then call `budgetItems.create(budgetId, { category_id, item_tier: 'one_off' })`. 2. Find a category whose name matches `item.name` (case-insensitive)
3. If no match, create one via `categories.create({ name: item.name, type: 'variable_expense', icon: item.icon })`
4. Call `budgetItems.create(budgetId, { category_id: resolvedCategoryId, item_tier: 'one_off' })` with the resolved category_id
- After creation: call `onItemAdded()` to refresh, close popover - After creation: call `onItemAdded()` to refresh, close popover
- If quick-add library is empty: show a small message "No saved items" with a link to /quick-add - If quick-add library is empty: show a small message "No saved items" with a link to /quick-add
- Add loading spinner on the clicked item while creating - Add loading spinner on the clicked item while creating