From 808ecfae3d66053dd3854b2a30a43186d7c458bc Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Thu, 12 Mar 2026 11:41:44 +0100 Subject: [PATCH] docs: create milestone v1.1 roadmap (4 phases) Co-Authored-By: Claude Opus 4.6 --- .planning/REQUIREMENTS.md | 34 +++++----- .planning/ROADMAP.md | 133 ++++++++++++++++++++++++++++---------- .planning/STATE.md | 64 +++++------------- 3 files changed, 134 insertions(+), 97 deletions(-) diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 46e6c01..4ac1851 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -139,27 +139,27 @@ Which phases cover which requirements. Updated during roadmap creation. | STATE-03 | Phase 3 (v1.0) | Complete | | IXTN-04 | Phase 4 (v1.0) | Complete | | FIX-01 | Phase 4 (v1.0) | Complete | -| TMPL-01 | TBD | Pending | -| TMPL-02 | TBD | Pending | -| TMPL-03 | TBD | Pending | -| TMPL-04 | TBD | Pending | -| TMPL-05 | TBD | Pending | -| TMPL-06 | TBD | Pending | -| QADD-01 | TBD | Pending | -| QADD-02 | TBD | Pending | -| QADD-03 | TBD | Pending | -| LYOT-01 | TBD | Pending | -| LYOT-02 | TBD | Pending | -| LYOT-03 | TBD | Pending | -| LYOT-04 | TBD | Pending | -| LYOT-05 | TBD | Pending | +| TMPL-01 | Phase 5 (v1.1) | Pending | +| TMPL-02 | Phase 5 (v1.1) | Pending | +| TMPL-04 | Phase 5 (v1.1) | Pending | +| TMPL-03 | Phase 6 (v1.1) | Pending | +| TMPL-05 | Phase 6 (v1.1) | Pending | +| TMPL-06 | Phase 6 (v1.1) | Pending | +| QADD-01 | Phase 7 (v1.1) | Pending | +| QADD-02 | Phase 7 (v1.1) | Pending | +| QADD-03 | Phase 7 (v1.1) | Pending | +| LYOT-01 | Phase 8 (v1.1) | Pending | +| LYOT-02 | Phase 8 (v1.1) | Pending | +| LYOT-03 | Phase 8 (v1.1) | Pending | +| LYOT-04 | Phase 8 (v1.1) | Pending | +| LYOT-05 | Phase 8 (v1.1) | Pending | **Coverage:** - v1.0 requirements: 23 total (all complete) - v1.1 requirements: 14 total -- Mapped to phases: 0 -- Unmapped: 14 (pending roadmap creation) +- Mapped to phases: 14 +- Unmapped: 0 --- *Requirements defined: 2026-03-11* -*Last updated: 2026-03-12 after v1.1 milestone requirements* +*Last updated: 2026-03-12 after v1.1 roadmap creation* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 8e142d9..b26e5f5 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -1,23 +1,14 @@ -# Roadmap: SimpleFinanceDash UI Polish +# Roadmap: SimpleFinanceDash -## Overview +## Milestones -This milestone transforms a functional but visually generic finance dashboard into a cohesive, pastel-themed experience. The work follows a strict dependency order: establish the token system first so every subsequent change produces consistent results, then polish structural surfaces (login, sidebar, layout), then add interaction quality and empty states, then finalize charts which depend on all prior work. Skipping this order is the primary failure mode for visual polish projects. +- ✅ **v1.0 UI Polish** - Phases 1-4 (shipped 2026-03-12) +- 🚧 **v1.1 Usability and Templates** - Phases 5-8 (in progress) ## Phases -**Phase Numbering:** -- Integer phases (1, 2, 3): Planned milestone work -- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED) - -Decimal phases appear between their surrounding integers in numeric order. - -- [x] **Phase 1: Design Token Foundation** - Establish the pastel CSS variable system and semantic color tokens that all subsequent phases depend on (completed 2026-03-11) -- [ ] **Phase 2: Layout and Brand Identity** - Polish the surfaces users see on every page load — login, sidebar, card headers, typography -- [ ] **Phase 3: Interaction Quality and Completeness** - Add loading, empty, and error states plus inline edit affordances to eliminate the "unfinished" feeling -- [x] **Phase 4: Chart Polish and Bug Fixes** - Finalize chart styling with semantic colors, formatted tooltips, and fix the currency locale bug (completed 2026-03-12) - -## Phase Details +
+✅ v1.0 UI Polish (Phases 1-4) - SHIPPED 2026-03-12 ### Phase 1: Design Token Foundation **Goal**: The app has a live pastel color system where all shadcn components read from intentionally designed oklch tokens, category colors come from a single source of truth, and shared inline edit infrastructure is extracted before visual work diverges it further @@ -30,6 +21,7 @@ Decimal phases appear between their surrounding integers in numeric order. 4. Amount values across all tables and summaries show green for positive, destructive red for negative, and amber for over-budget — applied consistently 5. A single `lib/palette.ts` file exists as the source of truth for all category-to-color mappings; `InlineEditCell.tsx` is extracted as a shared component replacing three duplicated local definitions **Plans:** 2/2 plans complete + Plans: - [x] 01-01-PLAN.md — CSS token foundation, palette.ts module, and test infrastructure - [x] 01-02-PLAN.md — Component wiring, InlineEditCell extraction, and visual verification @@ -44,27 +36,29 @@ Plans: 3. The sidebar has a pastel background visually distinct from the main content area, with a branded typographic treatment for the app name 4. The active navigation item has a clearly visible color indicator — clicking a nav item produces a visible selected state 5. The sidebar can be collapsed via a toggle button, reducing screen space usage on smaller layouts -**Plans:** 2 plans +**Plans:** 2/2 plans complete + Plans: -- [ ] 02-01-PLAN.md — Auth screen branding (gradient background, wordmark, alert errors) -- [ ] 02-02-PLAN.md — Sidebar polish (wordmark, active indicator, collapse trigger) +- [x] 02-01-PLAN.md — Auth screen branding (gradient background, wordmark, alert errors) +- [x] 02-02-PLAN.md — Sidebar polish (wordmark, active indicator, collapse trigger) ### Phase 3: Interaction Quality and Completeness **Goal**: Every user action and app state has appropriate visual feedback — loading states, empty states, edit affordances, and delete confirmations — so the app feels complete and trustworthy **Depends on**: Phase 2 **Requirements**: IXTN-01, IXTN-02, IXTN-03, IXTN-05, STATE-01, STATE-02, STATE-03 **Success Criteria** (what must be TRUE): - 1. Submitting a login, register, budget create, or budget edit form shows a spinner on the button — the user knows the request is in flight (Note: Budget Edit form does not exist yet; spinner covers 3 existing forms — Login, Register, Budget Create) + 1. Submitting a login, register, or budget create form shows a spinner on the button — the user knows the request is in flight 2. Hovering over an inline-editable row reveals a pencil icon, making the edit affordance discoverable before clicking 3. After saving an inline edit, the row briefly flashes a confirmation color, confirming the save completed 4. Attempting to delete a category triggers a confirmation dialog before the deletion executes 5. A user with no budgets sees a designed empty state with a clear CTA on the dashboard; a user with no categories sees the same on the categories page; loading skeletons use pastel-tinted backgrounds matching their section -**Plans:** 4 plans +**Plans:** 4/4 plans complete + Plans: -- [ ] 03-00-PLAN.md — Wave 0 test stub files (BudgetSetup, CategoriesPage, DashboardPage, BillsTracker) -- [ ] 03-01-PLAN.md — InlineEditCell pencil icon + save callbacks, form submit spinners -- [ ] 03-02-PLAN.md — Delete confirmation dialog, empty states for Dashboard and Categories -- [ ] 03-03-PLAN.md — Row flash wiring in trackers, pastel-tinted loading skeletons +- [x] 03-00-PLAN.md — Wave 0 test stub files +- [x] 03-01-PLAN.md — InlineEditCell pencil icon + save callbacks, form submit spinners +- [x] 03-02-PLAN.md — Delete confirmation dialog, empty states for Dashboard and Categories +- [x] 03-03-PLAN.md — Row flash wiring in trackers, pastel-tinted loading skeletons ### Phase 4: Chart Polish and Bug Fixes **Goal**: Charts look polished and informative with semantic category colors, correctly formatted currency tooltips, and the currency locale bug fixed so values display in the user's preferred locale @@ -75,18 +69,91 @@ Plans: 2. Chart tooltips display values formatted with the budget's currency (e.g., "1,234.56" not "1234.56") 3. The `formatCurrency` function uses the user's locale preference from their settings instead of the hardcoded `de-DE` — an English-locale user sees their numbers formatted correctly **Plans:** 2/2 plans complete + Plans: -- [ ] 04-01-PLAN.md — TDD: formatCurrency locale parameter fix (FIX-01) -- [ ] 04-02-PLAN.md — Chart tooltip wiring and locale threading (IXTN-04) +- [x] 04-01-PLAN.md — TDD: formatCurrency locale parameter fix (FIX-01) +- [x] 04-02-PLAN.md — Chart tooltip wiring and locale threading (IXTN-04) + +
+ +--- + +### 🚧 v1.1 Usability and Templates (In Progress) + +**Milestone Goal:** Replace the blunt "copy from previous month" workflow with a smart template system that understands fixed, variable, and one-off expenses. Add a quick-add library for saved one-off categories. Rethink the dashboard layout for denser, spreadsheet-like data presentation. + +#### Phase 5: Template Data Model and API +**Goal**: The backend has a first-class template system — new DB tables, migrations, and REST endpoints — that lets the app store user templates, classify items by tier, and generate budgets from templates programmatically +**Depends on**: Phase 4 +**Requirements**: TMPL-01, TMPL-02, TMPL-04 +**Success Criteria** (what must be TRUE): + 1. A budget item can be tagged as fixed, variable, or one-off — the tag is stored in the database and returned by the existing budget item API + 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 + 4. The template API endpoints are documented and return correct data for all three item tiers +**Plans**: TBD + +Plans: +- [ ] 05-01: DB migration — add item_type column to budget_items, create templates and template_items tables +- [ ] 05-02: Go handlers — template CRUD endpoints and budget-from-template generation endpoint + +#### Phase 6: Template Frontend and Workflow Replacement +**Goal**: Users can manage their template on a dedicated page, navigate to any month and get a budget auto-generated from their template, and the old "copy from previous month" flow is gone +**Depends on**: Phase 5 +**Requirements**: TMPL-03, TMPL-05, TMPL-06 +**Success Criteria** (what must be TRUE): + 1. Navigating to a month with no budget automatically generates one from the user's template — fixed items appear with their amounts, variable items appear with blank amounts + 2. The template management page lets the user add, remove, and reorder fixed and variable items without leaving the page + 3. When adding a budget item (fixed or variable), the user can tag it inline as fixed, variable, or one-off + 4. The "copy from previous month" button is no longer visible anywhere in the app +**Plans**: TBD + +Plans: +- [ ] 06-01: Item type tagging UI — inline fixed/variable/one-off selector on add/edit forms +- [ ] 06-02: Template management page — add, remove, reorder items with live preview +- [ ] 06-03: Auto-generate budget on navigate — wire frontend to generation endpoint, remove copy-from-previous + +#### Phase 7: Quick-Add Library +**Goal**: Users can save frequently-used one-off expense categories to a personal library and insert them into any month's budget in one click, eliminating re-entry friction for recurring one-offs like pharmacy visits +**Depends on**: Phase 5 +**Requirements**: QADD-01, QADD-02, QADD-03 +**Success Criteria** (what must be TRUE): + 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: +- [ ] 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 + +#### 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 +**Depends on**: Phase 6 +**Requirements**: LYOT-01, LYOT-02, LYOT-03, LYOT-04, LYOT-05 +**Success Criteria** (what must be TRUE): + 1. Dashboard sections use flat, lightweight containers — heavy bordered card chrome is replaced by integrated section boundaries that recede visually + 2. Table rows have tighter padding — more rows are visible on a standard desktop viewport without scrolling compared to the current layout + 3. There is no top padding gap above colored section headers — the header color reaches the container edge + 4. The dashboard grid layout is optimized for desktop — the most important data is visible above the fold on a 1440px screen +**Plans**: TBD + +Plans: +- [ ] 08-01: Container and card chrome rework — flatten section containers, eliminate top padding above headers +- [ ] 08-02: Row density and grid layout — tighten table rows, optimize desktop grid proportions ## Progress **Execution Order:** -Phases execute in numeric order: 1 -> 2 -> 3 -> 4 +Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 -| Phase | Plans Complete | Status | Completed | -|-------|----------------|--------|-----------| -| 1. Design Token Foundation | 2/2 | Complete | 2026-03-11 | -| 2. Layout and Brand Identity | 0/2 | In progress | - | -| 3. Interaction Quality and Completeness | 0/4 | Not started | - | -| 4. Chart Polish and Bug Fixes | 2/2 | Complete | 2026-03-12 | +| Phase | Milestone | Plans Complete | Status | Completed | +|-------|-----------|----------------|--------|-----------| +| 1. Design Token Foundation | v1.0 | 2/2 | Complete | 2026-03-11 | +| 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 | +| 4. Chart Polish and Bug Fixes | v1.0 | 2/2 | Complete | 2026-03-12 | +| 5. Template Data Model and API | v1.1 | 0/2 | Not started | - | +| 6. Template Frontend and Workflow Replacement | v1.1 | 0/3 | Not started | - | +| 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/STATE.md b/.planning/STATE.md index 4f13b91..53951a7 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -5,11 +5,11 @@ milestone_name: usability-and-templates status: planning stopped_at: null last_updated: "2026-03-12" -last_activity: 2026-03-12 — Milestone v1.1 started +last_activity: 2026-03-12 — Roadmap created for v1.1 (Phases 5-8) progress: - total_phases: 0 + total_phases: 4 completed_phases: 0 - total_plans: 0 + total_plans: 9 completed_plans: 0 percent: 0 --- @@ -21,21 +21,21 @@ progress: See: .planning/PROJECT.md (updated 2026-03-12) **Core value:** Opening the app should feel like opening a beautifully designed personal spreadsheet — clean pastel colors, clear data layout, approachable and visually delightful. The UI IS the product. -**Current focus:** Defining requirements for v1.1 +**Current focus:** Phase 5 — Template Data Model and API (ready to plan) ## Current Position -Phase: Not started (defining requirements) +Phase: 5 of 8 (Template Data Model and API) Plan: — -Status: Defining requirements -Last activity: 2026-03-12 — Milestone v1.1 started +Status: Ready to plan +Last activity: 2026-03-12 — v1.1 roadmap created, Phases 5-8 defined Progress: [░░░░░░░░░░] 0% ## Performance Metrics **Velocity:** -- Total plans completed: 0 +- Total plans completed: 0 (v1.1) - Average duration: - - Total execution time: 0 hours @@ -50,16 +50,6 @@ Progress: [░░░░░░░░░░] 0% - Trend: - *Updated after each plan completion* -| Phase 01-design-token-foundation P01 | 4 | 3 tasks | 6 files | -| Phase 01-design-token-foundation P02 | 60 | 3 tasks | 8 files | -| Phase 02-layout-and-brand-identity P01 | 8 | 2 tasks | 5 files | -| Phase 02-layout-and-brand-identity P02 | 2 | 2 tasks | 2 files | -| Phase 03-interaction-quality-and-completeness P00 | 5 | 1 tasks | 4 files | -| Phase 03-interaction-quality-and-completeness P01 | 2m | 2 tasks | 5 files | -| Phase 03-interaction-quality-and-completeness P02 | 5 | 2 tasks | 3 files | -| Phase 03-interaction-quality-and-completeness P03 | 5 | 2 tasks | 4 files | -| Phase 04-chart-polish-and-bug-fixes P01 | 1 | 2 tasks | 2 files | -| Phase 04-chart-polish-and-bug-fixes P02 | 10 | 2 tasks | 4 files | ## Accumulated Context @@ -68,31 +58,11 @@ Progress: [░░░░░░░░░░] 0% Decisions are logged in PROJECT.md Key Decisions table. Recent decisions affecting current work: -- [Init]: Customize shadcn via CSS variables only — never edit `src/components/ui/` source files directly -- [Init]: `lib/palette.ts` as single source of truth for all category-to-color mappings — no hex values in component files -- [Init]: Extract `InlineEditCell.tsx` at start of Phase 1 before any visual work touches the three duplicated components -- [Phase 01-design-token-foundation]: oklch pastel tokens replace zero-chroma neutrals in :root; --card/--popover remain pure white (locked) -- [Phase 01-design-token-foundation]: --success and --warning semantic tokens added to :root and @theme inline; chart tokens synced with palette.ts base colors -- [Phase 01-design-token-foundation]: palette.ts is single source of truth for 7 category types x 3 shades; amountColorClass returns text-success/text-warning/text-destructive -- [Phase 01-design-token-foundation]: InlineEditCell wraps TableCell internally — callers own row structure, component owns display/edit state -- [Phase 01-design-token-foundation]: amountColorClass() is the only allowed way to color amount cells — raw text-green/text-red classes banned in dashboard components -- [Phase 01-design-token-foundation]: Chart Cell fills use palette[type].base keyed by categoryType — charts and card headers share the same color token -- [Phase 02-layout-and-brand-identity]: Gradient background uses palette.saving/bill/investment light shades at 135deg for subtle tinted-paper feel on auth screens -- [Phase 02-layout-and-brand-identity]: Alert destructive replaces plain error

— semantic role=alert improves a11y and enables test assertions -- [Phase 02-layout-and-brand-identity]: Gradient wordmark uses inline oklch style, active state overrides sidebar-primary, SidebarTrigger in SidebarInset header -- [Phase 03-interaction-quality-and-completeness]: onSaveSuccess/onSaveError are optional callbacks — callers opt in to row-flash behavior in downstream plans -- [Phase 03-interaction-quality-and-completeness]: Budget Edit spinner deferred — no BudgetEdit form component exists in codebase yet -- [Phase 03-interaction-quality-and-completeness]: Mock useBudgets hook in DashboardPage tests to control loading state directly -- [Phase 03-interaction-quality-and-completeness]: BillsTracker renders a full Card component — tests render it standalone, not inside a -- [Phase 03-interaction-quality-and-completeness]: EmptyState is a shared component with all content as props — icon, heading, subtext, and optional CTA -- [Phase 03-interaction-quality-and-completeness]: Delete dialog does not auto-close on error — user must read ON DELETE RESTRICT message before dismissing -- [Phase 03-interaction-quality-and-completeness]: CategoriesPage loading state initialized true, set false in finally block to prevent empty-state flash -- [Phase 03-interaction-quality-and-completeness]: triggerFlash uses two separate state vars (flashRowId/errorRowId) for flash feedback — no race conditions between success and error states -- [Phase 03-interaction-quality-and-completeness]: Empty tracker sections show tinted skeleton card (not null) — section always visible with palette-tinted placeholders when no items exist -- [Phase 04-chart-polish-and-bug-fixes]: formatCurrency third parameter defaults to 'en', replacing hardcoded 'de-DE' — all existing 2-arg call sites now produce English formatting (FIX-01) -- [Phase 04-chart-polish-and-bug-fixes]: Defensive locale || 'en' guard in formatCurrency prevents RangeError when empty string is passed -- [Phase 04-chart-polish-and-bug-fixes]: Custom Tooltip content renderer replicates ChartTooltipContent styling without importing shadcn source — aligned with project rule forbidding edits to src/components/ui/ -- [Phase 04-chart-polish-and-bug-fixes]: DashboardPage.test.tsx mocks useAuth to prevent i18n initReactI18next import error triggered by new useAuth dependency +- [Phase 04]: formatCurrency third parameter defaults to 'en', replacing hardcoded 'de-DE' +- [Phase 04]: Custom Tooltip content renderer replicates ChartTooltipContent styling without importing shadcn source +- [Phase 03]: triggerFlash uses two separate state vars (flashRowId/errorRowId) — no race conditions between success and error states +- [Phase 03]: EmptyState is a shared component with all content as props — icon, heading, subtext, and optional CTA +- [Init v1.1]: Three-tier item model (fixed/variable/one-off) matches how users think about recurring vs one-time expenses ### Pending Todos @@ -100,11 +70,11 @@ None yet. ### Blockers/Concerns -- [Phase 4]: Confirm `preferred_locale` field is available on the settings API response before implementing FIX-01 -- [Phase 3]: Verify backend delete cascade behavior for categories with associated budget items before writing confirmation dialog copy +- [Phase 5]: Need to confirm whether budget_items table already has any type/tag column before writing migration +- [Phase 5]: Template generation endpoint must handle the case where user has no template yet (return empty budget, not error) ## Session Continuity -Last session: 2026-03-12T08:28:10.883Z -Stopped at: Completed 04-02-PLAN.md +Last session: 2026-03-12 +Stopped at: v1.1 roadmap created — Phases 5-8 written to ROADMAP.md Resume file: None