From 3bc778219864975516e33158563306bb791da4fd Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 20 Apr 2026 17:47:47 +0200 Subject: [PATCH 1/3] feat(06-02): create 19-item preset budget library - Add PresetItem interface with slug, type, defaultAmount, item_tier - Export PRESETS array with 19 items across 6 category types - Distribution: 4 income, 4 bill, 5 variable_expense, 2 debt, 2 saving, 2 investment - All item_tier values are fixed or variable (no one_off) --- src/data/presets.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/data/presets.ts diff --git a/src/data/presets.ts b/src/data/presets.ts new file mode 100644 index 0000000..4d593f4 --- /dev/null +++ b/src/data/presets.ts @@ -0,0 +1,36 @@ +import type { CategoryType } from "@/lib/types" + +export interface PresetItem { + slug: string + type: CategoryType + defaultAmount: number // EUR, round number — do NOT suffix with currency symbol + item_tier: "fixed" | "variable" +} + +export const PRESETS: PresetItem[] = [ + // income (4) + { slug: "salary", type: "income", defaultAmount: 3000, item_tier: "fixed" }, + { slug: "freelance", type: "income", defaultAmount: 500, item_tier: "variable" }, + { slug: "rental_income", type: "income", defaultAmount: 800, item_tier: "fixed" }, + { slug: "other_income", type: "income", defaultAmount: 200, item_tier: "variable" }, + // bill (4) + { slug: "rent", type: "bill", defaultAmount: 1000, item_tier: "fixed" }, + { slug: "electricity", type: "bill", defaultAmount: 80, item_tier: "fixed" }, + { slug: "internet", type: "bill", defaultAmount: 40, item_tier: "fixed" }, + { slug: "phone", type: "bill", defaultAmount: 30, item_tier: "fixed" }, + // variable_expense (5) + { slug: "groceries", type: "variable_expense", defaultAmount: 400, item_tier: "variable" }, + { slug: "transport", type: "variable_expense", defaultAmount: 100, item_tier: "variable" }, + { slug: "dining_out", type: "variable_expense", defaultAmount: 150, item_tier: "variable" }, + { slug: "health", type: "variable_expense", defaultAmount: 50, item_tier: "variable" }, + { slug: "clothing", type: "variable_expense", defaultAmount: 100, item_tier: "variable" }, + // debt (2) + { slug: "loan_repayment", type: "debt", defaultAmount: 200, item_tier: "fixed" }, + { slug: "credit_card", type: "debt", defaultAmount: 100, item_tier: "fixed" }, + // saving (2) + { slug: "emergency_fund", type: "saving", defaultAmount: 200, item_tier: "fixed" }, + { slug: "vacation", type: "saving", defaultAmount: 100, item_tier: "fixed" }, + // investment (2) + { slug: "etf", type: "investment", defaultAmount: 200, item_tier: "fixed" }, + { slug: "pension", type: "investment", defaultAmount: 100, item_tier: "fixed" }, +] From d23508017af2c2c03b42a84228663b24239d3565 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 20 Apr 2026 17:48:11 +0200 Subject: [PATCH 2/3] feat(06-02): add preset i18n translations to en.json and de.json - Add top-level presets key with presets.{type}.{slug} structure - 19 English translations covering all 6 category types - 19 German translations covering all 6 category types - Both JSON files remain valid after edits --- src/i18n/de.json | 33 +++++++++++++++++++++++++++++++++ src/i18n/en.json | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/i18n/de.json b/src/i18n/de.json index 5974499..cf7e00f 100644 --- a/src/i18n/de.json +++ b/src/i18n/de.json @@ -120,5 +120,38 @@ "loading": "Laden...", "error": "Etwas ist schiefgelaufen", "confirm": "Bestätigen" + }, + "presets": { + "income": { + "salary": "Gehalt", + "freelance": "Freelance-Einkommen", + "rental_income": "Mieteinnahmen", + "other_income": "Sonstiges Einkommen" + }, + "bill": { + "rent": "Miete", + "electricity": "Strom", + "internet": "Internet", + "phone": "Telefon" + }, + "variable_expense": { + "groceries": "Lebensmittel", + "transport": "Transport", + "dining_out": "Auswärts essen", + "health": "Gesundheit & Apotheke", + "clothing": "Kleidung" + }, + "debt": { + "loan_repayment": "Kreditrückzahlung", + "credit_card": "Kreditkarte" + }, + "saving": { + "emergency_fund": "Notfallfonds", + "vacation": "Urlaubskasse" + }, + "investment": { + "etf": "ETF / Indexfonds", + "pension": "Altersvorsorge" + } } } diff --git a/src/i18n/en.json b/src/i18n/en.json index a85fa41..a38a475 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -120,5 +120,38 @@ "loading": "Loading...", "error": "Something went wrong", "confirm": "Confirm" + }, + "presets": { + "income": { + "salary": "Salary", + "freelance": "Freelance Income", + "rental_income": "Rental Income", + "other_income": "Other Income" + }, + "bill": { + "rent": "Rent", + "electricity": "Electricity", + "internet": "Internet", + "phone": "Phone" + }, + "variable_expense": { + "groceries": "Groceries", + "transport": "Transport", + "dining_out": "Dining Out", + "health": "Health & Pharmacy", + "clothing": "Clothing" + }, + "debt": { + "loan_repayment": "Loan Repayment", + "credit_card": "Credit Card" + }, + "saving": { + "emergency_fund": "Emergency Fund", + "vacation": "Vacation Fund" + }, + "investment": { + "etf": "ETF / Index Fund", + "pension": "Pension" + } } } From 934ae0e4c7e2821123969703ddc48383b2d2e8d9 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 20 Apr 2026 17:48:28 +0200 Subject: [PATCH 3/3] docs(06-02): complete preset data library plan summary --- .../06-02-SUMMARY.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .planning/phases/06-preset-data-first-run-detection-and-db-safety/06-02-SUMMARY.md diff --git a/.planning/phases/06-preset-data-first-run-detection-and-db-safety/06-02-SUMMARY.md b/.planning/phases/06-preset-data-first-run-detection-and-db-safety/06-02-SUMMARY.md new file mode 100644 index 0000000..037520d --- /dev/null +++ b/.planning/phases/06-preset-data-first-run-detection-and-db-safety/06-02-SUMMARY.md @@ -0,0 +1,65 @@ +--- +phase: 06-preset-data-first-run-detection-and-db-safety +plan: "02" +subsystem: data +tags: [presets, i18n, static-data] +dependency_graph: + requires: [] + provides: [PresetItem, PRESETS] + affects: [src/data/presets.ts, src/i18n/en.json, src/i18n/de.json] +tech_stack: + added: [] + patterns: [static-data-module, i18n-dot-path] +key_files: + created: + - src/data/presets.ts + modified: + - src/i18n/en.json + - src/i18n/de.json +decisions: + - "item_tier restricted to fixed|variable only (no one_off) to match DB check constraint on template_items" + - "presets.{type}.{slug} i18n key structure matches type+slug fields in PRESETS array" +metrics: + duration: "~5 minutes" + completed: "2026-04-20" + tasks_completed: 2 + files_changed: 3 +--- + +# Phase 06 Plan 02: Preset Data Library Summary + +Static 19-item preset budget library with English and German translations, structured as `presets.{type}.{slug}` i18n keys matching the PRESETS array shape. + +## Tasks Completed + +| Task | Name | Commit | Files | +|------|------|--------|-------| +| 1 | Create src/data/presets.ts | 3bc7782 | src/data/presets.ts (created) | +| 2 | Add preset translations to en.json and de.json | d235080 | src/i18n/en.json, src/i18n/de.json | + +## What Was Built + +`src/data/presets.ts` exports `PresetItem` interface and `PRESETS` array with exactly 19 items: +- 4 income, 4 bill, 5 variable_expense, 2 debt, 2 saving, 2 investment +- All `item_tier` values are `"fixed"` or `"variable"` (no `"one_off"`) +- Pure static module — no Supabase or React imports + +Both i18n files now have a top-level `"presets"` key with nested `{type}.{slug}` structure covering all 19 slugs in English and German. + +## Deviations from Plan + +None - plan executed exactly as written. + +## Threat Surface Scan + +No new network endpoints, auth paths, or trust boundaries introduced. T-06-05 (JSON malformed) mitigated — both files verified valid via `node -e "JSON.parse(...)"` before commit. + +## Self-Check: PASSED + +- src/data/presets.ts: FOUND +- src/i18n/en.json "presets" key: FOUND +- src/i18n/de.json "presets" key: FOUND +- 19 PRESETS items confirmed (grep '{ slug:' returns 19) +- no one_off in presets.ts confirmed +- tsc --noEmit: PASSED +- Commits 3bc7782 and d235080: confirmed in git log