diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md
index bfdcfa8..6f19b13 100644
--- a/.planning/ROADMAP.md
+++ b/.planning/ROADMAP.md
@@ -120,11 +120,11 @@ Plans:
1. A user can save a one-off expense category (with an icon) to their quick-add library from the budget item add flow
2. When adding a one-off item, the user can browse their quick-add library and select a saved category — the item populates with that category and icon
3. The quick-add library management page lets the user add, edit, and remove saved categories
-**Plans**: TBD
+**Plans:** 2 plans
Plans:
-- [ ] 07-01: Quick-add library backend — DB table, API endpoints for saved categories
-- [ ] 07-02: Quick-add library frontend — management page and picker UI in add-item flow
+- [ ] 07-01-PLAN.md — DB migration, QuickAddItem model, CRUD queries, REST handlers at /api/quick-add
+- [ ] 07-02-PLAN.md — QuickAddPage management UI, QuickAddPicker in dashboard, sidebar nav and routing
#### Phase 8: Layout and Density Rethink
**Goal**: The dashboard looks and feels like a beautifully designed spreadsheet — flat containers, tight rows, no wasted chrome — and maximizes the data visible on a desktop screen without scrolling
@@ -153,6 +153,6 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8
| 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 |
| 5. Template Data Model and API | v1.1 | 2/2 | Complete | 2026-03-12 |
-| 6. Template Frontend and Workflow Replacement | 2/2 | Complete | 2026-03-12 | - |
+| 6. Template Frontend and Workflow Replacement | v1.1 | 2/2 | Complete | 2026-03-12 |
| 7. Quick-Add Library | v1.1 | 0/2 | Not started | - |
| 8. Layout and Density Rethink | v1.1 | 0/2 | Not started | - |
diff --git a/.planning/phases/07-quick-add-library/07-01-PLAN.md b/.planning/phases/07-quick-add-library/07-01-PLAN.md
new file mode 100644
index 0000000..2d6bda3
--- /dev/null
+++ b/.planning/phases/07-quick-add-library/07-01-PLAN.md
@@ -0,0 +1,217 @@
+---
+phase: 07-quick-add-library
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - backend/migrations/003_quick_add_library.sql
+ - backend/internal/models/models.go
+ - backend/internal/db/queries.go
+ - backend/internal/api/handlers.go
+ - backend/internal/api/router.go
+autonomous: true
+requirements: [QADD-01, QADD-03]
+
+must_haves:
+ truths:
+ - "A quick_add_items table exists with user_id, name, icon, and sort_order columns"
+ - "API returns a list of quick-add items for the authenticated user"
+ - "API can create, update, and delete quick-add items"
+ - "Quick-add items are user-scoped — one user cannot see another's items"
+ artifacts:
+ - path: "backend/migrations/003_quick_add_library.sql"
+ provides: "quick_add_items table DDL"
+ contains: "CREATE TABLE quick_add_items"
+ - path: "backend/internal/models/models.go"
+ provides: "QuickAddItem Go struct"
+ contains: "QuickAddItem"
+ - path: "backend/internal/db/queries.go"
+ provides: "CRUD query functions for quick-add items"
+ exports: ["ListQuickAddItems", "CreateQuickAddItem", "UpdateQuickAddItem", "DeleteQuickAddItem"]
+ - path: "backend/internal/api/handlers.go"
+ provides: "HTTP handlers for quick-add CRUD"
+ contains: "ListQuickAddItems"
+ - path: "backend/internal/api/router.go"
+ provides: "Route registrations under /api/quick-add"
+ contains: "/api/quick-add"
+ key_links:
+ - from: "backend/internal/api/router.go"
+ to: "backend/internal/api/handlers.go"
+ via: "handler method references"
+ pattern: "h\\..*QuickAdd"
+ - from: "backend/internal/api/handlers.go"
+ to: "backend/internal/db/queries.go"
+ via: "query function calls"
+ pattern: "q\\..*QuickAdd"
+---
+
+
+Create the backend data model and REST API for the quick-add library feature.
+
+Purpose: Users need a persistent library of saved one-off expense categories (name + icon) that they can reuse across months. This plan creates the database table, Go model, query functions, and HTTP endpoints.
+
+Output: Migration file, QuickAddItem model, CRUD queries, REST handlers at /api/quick-add
+
+
+
+@/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md
+@/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+
+@backend/internal/models/models.go
+@backend/internal/db/queries.go
+@backend/internal/api/handlers.go
+@backend/internal/api/router.go
+@backend/migrations/002_templates.sql
+
+
+
+
+From backend/internal/models/models.go:
+```go
+// Category struct pattern — QuickAddItem should follow same shape
+type Category struct {
+ ID uuid.UUID `json:"id"`
+ UserID uuid.UUID `json:"user_id"`
+ Name string `json:"name"`
+ Type CategoryType `json:"type"`
+ Icon string `json:"icon"`
+ SortOrder int `json:"sort_order"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+```
+
+From backend/internal/api/router.go:
+```go
+// Route group pattern — quick-add follows same structure
+r.Route("/api/template", func(r chi.Router) {
+ r.Get("/", h.GetTemplate)
+ r.Put("/", h.UpdateTemplateName)
+ r.Post("/items", h.CreateTemplateItem)
+ // ...
+})
+```
+
+From backend/internal/api/handlers.go:
+```go
+// Handler struct — all handlers are methods on this
+type Handlers struct {
+ queries *db.Queries
+ sessionSecret string
+}
+
+// Helper functions available: writeJSON, writeError, auth.UserIDFromContext
+```
+
+
+
+
+
+
+ Task 1: Migration, model, and query functions
+ backend/migrations/003_quick_add_library.sql, backend/internal/models/models.go, backend/internal/db/queries.go
+
+1. Create migration `backend/migrations/003_quick_add_library.sql`:
+ ```sql
+ CREATE TABLE quick_add_items (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
+ name VARCHAR(100) NOT NULL,
+ icon VARCHAR(50) NOT NULL DEFAULT '',
+ sort_order INT NOT NULL DEFAULT 0,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
+ );
+ CREATE INDEX idx_quick_add_items_user ON quick_add_items(user_id);
+ ```
+ The table stores saved one-off category presets (name + icon). No FK to categories — these are independent presets the user can pick from when adding a one-off budget item.
+
+2. Add `QuickAddItem` struct to `backend/internal/models/models.go`:
+ ```go
+ type QuickAddItem struct {
+ ID uuid.UUID `json:"id"`
+ UserID uuid.UUID `json:"user_id"`
+ Name string `json:"name"`
+ Icon string `json:"icon"`
+ SortOrder int `json:"sort_order"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+ }
+ ```
+
+3. Add four query functions to `backend/internal/db/queries.go` (append after template section):
+
+ - `ListQuickAddItems(ctx, userID) ([]QuickAddItem, error)` — SELECT ordered by sort_order, returns empty slice (not nil) when none exist
+ - `CreateQuickAddItem(ctx, userID, name, icon string) (*QuickAddItem, error)` — INSERT with sort_order = (SELECT COALESCE(MAX(sort_order),0)+1), RETURNING all columns
+ - `UpdateQuickAddItem(ctx, id, userID, name, icon string, sortOrder int) (*QuickAddItem, error)` — UPDATE with WHERE id=$1 AND user_id=$2, return error if no rows affected
+ - `DeleteQuickAddItem(ctx, id, userID) error` — DELETE with WHERE id=$1 AND user_id=$2
+
+ Follow existing query patterns: use context parameter, userID scoping in WHERE clause, fmt.Errorf wrapping, pgx row scanning.
+
+
+ cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/backend && go vet ./...
+
+ QuickAddItem struct compiles, all four query functions compile, migration file exists with CREATE TABLE statement
+
+
+
+ Task 2: HTTP handlers and route registration
+ backend/internal/api/handlers.go, backend/internal/api/router.go
+
+1. Add four handler methods to `backend/internal/api/handlers.go`:
+
+ - `ListQuickAddItems(w, r)` — GET, extracts userID from context, calls queries.ListQuickAddItems, returns JSON array (200)
+ - `CreateQuickAddItem(w, r)` — POST, accepts JSON `{name: string, icon: string}`, validates name is non-empty (400 if missing), calls queries.CreateQuickAddItem, returns created item (201)
+ - `UpdateQuickAddItem(w, r)` — PUT, extracts itemId from chi URL param, accepts JSON `{name: string, icon: string, sort_order: int}`, validates name non-empty, calls queries.UpdateQuickAddItem, returns updated item (200). Return 404 if no rows affected.
+ - `DeleteQuickAddItem(w, r)` — DELETE, extracts itemId from chi URL param, calls queries.DeleteQuickAddItem, returns 204
+
+ Follow existing handler patterns:
+ - Use `auth.UserIDFromContext(r.Context())` for userID
+ - Use `chi.URLParam(r, "itemId")` for path params
+ - Use `writeJSON(w, status, data)` and `writeError(w, status, message)`
+ - Parse UUID with `uuid.Parse()`, return 400 on invalid
+
+2. Register routes in `backend/internal/api/router.go` inside the authenticated group (after the template route block):
+ ```go
+ r.Route("/api/quick-add", func(r chi.Router) {
+ r.Get("/", h.ListQuickAddItems)
+ r.Post("/", h.CreateQuickAddItem)
+ r.Put("/{itemId}", h.UpdateQuickAddItem)
+ r.Delete("/{itemId}", h.DeleteQuickAddItem)
+ })
+ ```
+
+
+ cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/backend && go vet ./... && go build ./cmd/server
+
+ All four handlers compile, routes registered under /api/quick-add, go build succeeds with no errors
+
+
+
+
+
+- `go vet ./...` passes with no issues
+- `go build ./cmd/server` produces binary without errors
+- Migration file 003 exists and has valid SQL
+- QuickAddItem struct has json tags matching API contract
+- All handlers use userID scoping (no cross-user data leak)
+
+
+
+- Backend compiles and builds successfully
+- Migration creates quick_add_items table with correct schema
+- Four REST endpoints exist: GET/POST /api/quick-add, PUT/DELETE /api/quick-add/{itemId}
+- All endpoints require authentication (inside authenticated route group)
+- All queries scope by user_id
+
+
+
diff --git a/.planning/phases/07-quick-add-library/07-02-PLAN.md b/.planning/phases/07-quick-add-library/07-02-PLAN.md
new file mode 100644
index 0000000..3513415
--- /dev/null
+++ b/.planning/phases/07-quick-add-library/07-02-PLAN.md
@@ -0,0 +1,334 @@
+---
+phase: 07-quick-add-library
+plan: 02
+type: execute
+wave: 2
+depends_on: ["07-01"]
+files_modified:
+ - frontend/src/lib/api.ts
+ - frontend/src/hooks/useQuickAdd.ts
+ - frontend/src/pages/QuickAddPage.tsx
+ - frontend/src/components/QuickAddPicker.tsx
+ - frontend/src/components/AppLayout.tsx
+ - frontend/src/App.tsx
+ - frontend/src/i18n/en.json
+ - frontend/src/i18n/de.json
+autonomous: false
+requirements: [QADD-01, QADD-02, QADD-03]
+
+must_haves:
+ truths:
+ - "User can view, add, edit, and remove saved categories on the quick-add library page"
+ - "User can browse their quick-add library when adding a one-off item to a budget"
+ - "Selecting a quick-add item creates a one-off budget item with that name and icon"
+ - "Quick-add library page is accessible from sidebar navigation"
+ artifacts:
+ - path: "frontend/src/lib/api.ts"
+ provides: "QuickAddItem type and quickAdd API namespace"
+ contains: "quickAdd"
+ - path: "frontend/src/hooks/useQuickAdd.ts"
+ provides: "useQuickAdd hook with CRUD operations"
+ exports: ["useQuickAdd"]
+ - path: "frontend/src/pages/QuickAddPage.tsx"
+ provides: "Management page for quick-add library"
+ min_lines: 50
+ - path: "frontend/src/components/QuickAddPicker.tsx"
+ provides: "Picker component for selecting quick-add items when adding one-off budget items"
+ min_lines: 30
+ - path: "frontend/src/components/AppLayout.tsx"
+ provides: "Sidebar nav item for quick-add library"
+ contains: "quick-add"
+ - path: "frontend/src/App.tsx"
+ provides: "Route for /quick-add"
+ contains: "QuickAddPage"
+ key_links:
+ - from: "frontend/src/hooks/useQuickAdd.ts"
+ to: "frontend/src/lib/api.ts"
+ via: "quickAdd namespace import"
+ pattern: "import.*quickAdd.*api"
+ - from: "frontend/src/pages/QuickAddPage.tsx"
+ to: "frontend/src/hooks/useQuickAdd.ts"
+ via: "useQuickAdd hook call"
+ pattern: "useQuickAdd\\(\\)"
+ - from: "frontend/src/components/QuickAddPicker.tsx"
+ to: "frontend/src/lib/api.ts"
+ via: "quickAdd.list and budgetItems.create"
+ pattern: "quickAdd|budgetItems"
+---
+
+
+Build the frontend for the quick-add library: a management page for CRUD operations, a picker component for the budget item add flow, and all routing/navigation wiring.
+
+Purpose: Users need a page to manage their saved one-off categories and a way to insert them as budget items with one click when viewing a budget.
+
+Output: QuickAddPage, QuickAddPicker component, useQuickAdd hook, API client additions, routing and i18n
+
+
+
+@/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md
+@/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/07-quick-add-library/07-01-SUMMARY.md
+
+@frontend/src/lib/api.ts
+@frontend/src/hooks/useTemplate.ts
+@frontend/src/pages/TemplatePage.tsx
+@frontend/src/pages/DashboardPage.tsx
+@frontend/src/components/AppLayout.tsx
+@frontend/src/App.tsx
+@frontend/src/i18n/en.json
+@frontend/src/i18n/de.json
+
+
+
+
+QuickAddItem JSON shape (GET /api/quick-add returns array of these):
+```json
+{
+ "id": "uuid",
+ "user_id": "uuid",
+ "name": "string",
+ "icon": "string",
+ "sort_order": 0,
+ "created_at": "timestamp",
+ "updated_at": "timestamp"
+}
+```
+
+Endpoints:
+- GET /api/quick-add — list all quick-add items
+- POST /api/quick-add — create {name, icon}
+- PUT /api/quick-add/{itemId} — update {name, icon, sort_order}
+- DELETE /api/quick-add/{itemId} — remove
+
+
+From frontend/src/lib/api.ts:
+```typescript
+export const budgetItems = {
+ create: (budgetId: string, data: Partial) =>
+ request(`/budgets/${budgetId}/items`, { method: 'POST', body: JSON.stringify(data) }),
+}
+```
+
+From frontend/src/hooks/useTemplate.ts (hook pattern to follow):
+```typescript
+export function useTemplate() {
+ const [template, setTemplate] = useState(null)
+ const [categories, setCategories] = useState([])
+ const [loading, setLoading] = useState(true)
+ // ... CRUD functions that call API and refresh state
+ return { template, categories, loading, addItem, removeItem, moveItem }
+}
+```
+
+From frontend/src/components/AppLayout.tsx (nav items pattern):
+```typescript
+const navItems = [
+ { path: '/', label: t('nav.dashboard'), icon: LayoutDashboard },
+ { path: '/categories', label: t('nav.categories'), icon: Tags },
+ { path: '/template', label: t('nav.template'), icon: FileText },
+ { path: '/settings', label: t('nav.settings'), icon: Settings },
+]
+```
+
+
+
+
+
+
+ Task 1: API client, hook, management page, routing, and i18n
+ frontend/src/lib/api.ts, frontend/src/hooks/useQuickAdd.ts, frontend/src/pages/QuickAddPage.tsx, frontend/src/components/AppLayout.tsx, frontend/src/App.tsx, frontend/src/i18n/en.json, frontend/src/i18n/de.json
+
+1. **API client** (`frontend/src/lib/api.ts`):
+ Add QuickAddItem interface after the TemplateDetail interface:
+ ```typescript
+ export interface QuickAddItem {
+ id: string
+ user_id: string
+ name: string
+ icon: string
+ sort_order: number
+ created_at: string
+ updated_at: string
+ }
+ ```
+ Add quickAdd namespace after the template namespace:
+ ```typescript
+ export const quickAdd = {
+ list: () => request('/quick-add'),
+ create: (data: { name: string; icon: string }) =>
+ request('/quick-add', { method: 'POST', body: JSON.stringify(data) }),
+ update: (id: string, data: { name: string; icon: string; sort_order: number }) =>
+ request(`/quick-add/${id}`, { method: 'PUT', body: JSON.stringify(data) }),
+ delete: (id: string) =>
+ request(`/quick-add/${id}`, { method: 'DELETE' }),
+ }
+ ```
+
+2. **Hook** (`frontend/src/hooks/useQuickAdd.ts`):
+ Create `useQuickAdd()` hook following the useTemplate pattern:
+ - State: `items: QuickAddItem[]`, `loading: boolean`
+ - On mount: fetch via `quickAdd.list()`, set items (default to empty array)
+ - `addItem(name, icon)`: calls `quickAdd.create()`, refreshes list
+ - `updateItem(id, name, icon, sortOrder)`: calls `quickAdd.update()`, refreshes list
+ - `removeItem(id)`: calls `quickAdd.delete()`, refreshes list
+ - Return: `{ items, loading, addItem, updateItem, removeItem }`
+
+3. **Management page** (`frontend/src/pages/QuickAddPage.tsx`):
+ Follow the TemplatePage pattern (pastel gradient header, table layout):
+ - Header with gradient: `bg-gradient-to-r from-amber-50 to-orange-50` (warm tone for one-offs, distinct from template's violet)
+ - Title from i18n: `t('quickAdd.title')`
+ - Add form row at top: text input for name, text input for icon (emoji or short string), Add 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
+ - 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."
+
+4. **Sidebar nav** (`frontend/src/components/AppLayout.tsx`):
+ Add nav item after template: `{ path: '/quick-add', label: t('nav.quickAdd'), icon: Zap }`
+ Import `Zap` from `lucide-react`.
+
+5. **Route** (`frontend/src/App.tsx`):
+ Add route: `} />`
+ Import QuickAddPage.
+
+6. **i18n** — add keys to both en.json and de.json:
+ English (en.json):
+ ```json
+ "nav": { ... "quickAdd": "Quick Add" },
+ "quickAdd": {
+ "title": "Quick-Add Library",
+ "name": "Name",
+ "icon": "Icon",
+ "addItem": "Add Item",
+ "noItems": "No saved items",
+ "noItemsHint": "Save your frequently-used one-off categories here for quick access.",
+ "editItem": "Edit",
+ "deleteItem": "Remove",
+ "save": "Save",
+ "cancel": "Cancel"
+ }
+ ```
+ German (de.json): translate equivalently:
+ ```json
+ "nav": { ... "quickAdd": "Schnellzugriff" },
+ "quickAdd": {
+ "title": "Schnellzugriff-Bibliothek",
+ "name": "Name",
+ "icon": "Symbol",
+ "addItem": "Hinzufuegen",
+ "noItems": "Keine gespeicherten Eintraege",
+ "noItemsHint": "Speichere hier haeufig genutzte Einmal-Kategorien fuer schnellen Zugriff.",
+ "editItem": "Bearbeiten",
+ "deleteItem": "Entfernen",
+ "save": "Speichern",
+ "cancel": "Abbrechen"
+ }
+ ```
+
+
+ cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun run build
+
+ QuickAddPage renders with add form, table, and empty state. Sidebar shows "Quick Add" nav item. Route /quick-add works. All i18n keys present in both languages. Build succeeds.
+
+
+
+ Task 2: Quick-add picker in dashboard for one-off budget items
+ frontend/src/components/QuickAddPicker.tsx, frontend/src/pages/DashboardPage.tsx
+
+1. **QuickAddPicker component** (`frontend/src/components/QuickAddPicker.tsx`):
+ A dropdown/popover that lets users add a one-off item to the current budget from their quick-add library.
+
+ Props:
+ ```typescript
+ interface Props {
+ budgetId: string
+ onItemAdded: () => void // callback to refresh budget after adding
+ }
+ ```
+
+ Implementation:
+ - 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`)
+ - 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:
+ - 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'`.
+ - 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' })`.
+ - 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
+ - Add loading spinner on the clicked item while creating
+
+ Add i18n keys:
+ - en.json: `"quickAdd": { ... "addOneOff": "Quick Add", "emptyPicker": "No saved items", "goToLibrary": "Manage library" }`
+ - de.json: equivalent translations
+
+2. **Wire into DashboardPage** (`frontend/src/pages/DashboardPage.tsx`):
+ - Import QuickAddPicker
+ - Import `categories as categoriesApi` from api.ts
+ - Add QuickAddPicker next to the budget selector (after the "Create Budget" button), only visible when a budget is selected:
+ ```tsx
+ {current && (
+ selectBudget(current.id)}
+ />
+ )}
+ ```
+ - The `onItemAdded` callback re-fetches the current budget to show the new item
+
+
+ cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun run build
+
+ QuickAddPicker renders in dashboard toolbar. Clicking a quick-add item creates a one-off budget item (finding or creating the category first). Popover closes after add. Empty library shows link to management page. Build succeeds.
+
+
+
+ Task 3: Verify complete quick-add library feature
+
+ Human verifies the complete quick-add library feature:
+ 1. Management page at /quick-add with add/edit/remove for saved one-off categories
+ 2. Quick-add picker button in dashboard toolbar that creates one-off budget items from saved library
+ 3. Sidebar navigation includes Quick Add link
+
+
+ Steps to verify:
+ 1. Start the app: `docker compose up --build`
+ 2. Navigate to /quick-add from sidebar — verify empty state shows
+ 3. Add 2-3 items (e.g., "Pharmacy" with pill emoji, "Haircut" with scissors emoji)
+ 4. Verify items appear in the table with edit/delete actions
+ 5. Edit one item name — verify it updates
+ 6. Delete one item — verify it disappears
+ 7. Go to Dashboard, select a budget
+ 8. Click "Quick Add" button in toolbar — verify popover shows your saved items
+ 9. Click one item — verify a new one-off budget item appears in the budget
+ 10. Verify the new item shows with item_tier badge "one-off"
+
+ All quick-add library features work end-to-end: management page CRUD, picker creates one-off budget items, sidebar nav accessible
+
+
+
+
+
+- `bun run build` succeeds with no TypeScript errors
+- QuickAddPage renders management UI with CRUD operations
+- QuickAddPicker creates one-off budget items from library
+- Sidebar shows Quick Add navigation item
+- Route /quick-add loads the management page
+- All i18n keys present in en.json and de.json
+
+
+
+- User can add, edit, and remove items from the quick-add library page (QADD-03)
+- User can save a one-off category with icon to their library (QADD-01)
+- User can browse and select from library when adding one-off items to a budget (QADD-02)
+- Selected quick-add item creates a one-off budget item in the current budget
+
+
+