# SimpleFinanceDash - Product Requirements Document ## 1. Overview SimpleFinanceDash is a self-hosted personal budget dashboard web application. It replaces a manual spreadsheet-based budget tracker with a proper application, enabling future extensibility (sharing, automations, summaries). The application replicates a monthly budget tracking workflow with support for bills, variable expenses, debts, savings, and investments. ## 2. Goals - Provide a clean, pastel-themed budget dashboard that mirrors the existing spreadsheet workflow - Self-hosted, lightweight single-binary deployment - Support for German and English (i18n) - Solid foundation for future features (sharing, automation, customization) ## 3. Users - **MVP**: Single-user accounts, isolated data per user - **Future**: Shared/household budgets, multi-user collaboration ## 4. Tech Stack | Layer | Technology | |-------------|------------------------------------------------| | Frontend | React + Vite + TypeScript + Tailwind CSS + shadcn/ui | | Backend | Go (standard library + router of choice) | | Database | PostgreSQL | | Auth | Local username/password + OIDC (e.g. Authentik) | | Deployment | Single binary (embedded SPA) + Docker Compose | | API | REST (JSON) | ## 5. Architecture ### 5.1 Single Binary The Go backend embeds the built React SPA using `embed.FS`. A single Docker image contains everything. PostgreSQL runs as a separate service in `compose.yml`. ### 5.2 Project Structure (proposed) ``` SimpleFinanceDash/ backend/ cmd/server/ # main entrypoint internal/ api/ # HTTP handlers / routes auth/ # local auth + OIDC db/ # database access (queries, migrations) models/ # domain types i18n/ # translations migrations/ # SQL migration files frontend/ src/ components/ # React components (shadcn/ui based) pages/ # route-level pages hooks/ # custom hooks lib/ # utilities, API client i18n/ # translation files (de, en) compose.yml Dockerfile PRD.md ``` ## 6. Data Model ### 6.1 Core Entities **User** - id (UUID) - email - password_hash (nullable, empty for OIDC-only users) - oidc_subject (nullable) - display_name - preferred_locale (de | en) - created_at, updated_at **Category** - id (UUID) - user_id (FK) - name - type: enum(bill, variable_expense, debt, saving, investment, income) - icon (optional, for future use) - sort_order - created_at, updated_at Categories are global per user and reused across budget periods. **Budget** - id (UUID) - user_id (FK) - name (e.g. "Oktober 2025") - start_date - end_date - currency (default: EUR) - carryover_amount (manually set or pulled from previous budget) - created_at, updated_at **BudgetItem** - id (UUID) - budget_id (FK) - category_id (FK) - budgeted_amount (planned) - actual_amount (spent/received) - notes (optional) - created_at, updated_at Each BudgetItem represents one category's row within a monthly budget (e.g. "Strom & Heizung" with budget 65.00, actual 65.00). ### 6.2 Relationships ``` User 1--* Category User 1--* Budget Budget 1--* BudgetItem Category 1--* BudgetItem ``` ### 6.3 Derived Values (computed, not stored) - **Available amount** = carryover + sum(income actuals) - sum(bill actuals) - sum(expense actuals) - sum(debt actuals) - sum(saving actuals) - sum(investment actuals) - **Budget vs Actual per type** = aggregated from BudgetItems - **Remaining per category** = budgeted - actual ## 7. Features (MVP) ### 7.1 Authentication - **Local auth**: Email + password registration/login with bcrypt hashing - **OIDC**: Connect to external identity providers (e.g. Authentik). Strongly encouraged over local auth in the UI - **Session management**: HTTP-only cookies with JWT or server-side sessions ### 7.2 Budget Setup - Create a new monthly budget period (start date, end date, currency, carryover) - Option to copy categories/budgeted amounts from a previous month - Edit or delete existing budgets ### 7.3 Dashboard View Replicates the spreadsheet layout as a single-page dashboard for the selected budget: **Top Section - Financial Overview** - Carryover, Income, Bills, Expenses, Debts, Savings, Investments - Budget vs Actual columns - Available balance with donut chart **Bills Tracker** - Table of bill categories with Budget and Actual columns - Inline editing of actual amounts **Variable Expenses Summary** - Table with Budget, Actual, Remaining columns - Bar chart: Budget vs Actual per category **Expense Breakdown** - Pie chart showing distribution across expense categories **Debt Tracker** - Table of debt categories with Budget and Actual columns ### 7.4 Category Management - CRUD for categories per user - Category types: bill, variable_expense, debt, saving, investment, income - Categories persist across budgets ### 7.5 Internationalization (i18n) - German (de) and English (en) - User preference stored in profile - All UI labels, messages, and formatting (date, currency) localized ### 7.6 Charts - **Donut chart**: Available balance vs spent - **Bar chart**: Budget vs Actual per variable expense category - **Pie chart**: Expense breakdown by category - Library: Recharts or similar React-compatible charting library ## 8. UI / Design ### 8.1 Color Scheme Pastel color palette inspired by the reference screenshots: - Soft blues, pinks, yellows, greens, lavenders - Light backgrounds with subtle section dividers - shadcn/ui components with custom pastel theme tokens ### 8.2 Layout - Left sidebar or top nav for navigation (Dashboard, Categories, Settings) - Main content area with the dashboard sections stacked vertically - Responsive but desktop-first (primary use case) ### 8.3 Future: Customization - Architecture should support theming (CSS variables / Tailwind config) - Not implemented in MVP, but color tokens should be centralized for easy swapping later ## 9. API Endpoints (MVP) ### Auth | Method | Path | Description | |--------|-----------------------|--------------------------| | POST | /api/auth/register | Local registration | | POST | /api/auth/login | Local login | | POST | /api/auth/logout | Logout | | GET | /api/auth/oidc | Initiate OIDC flow | | GET | /api/auth/oidc/callback | OIDC callback | | GET | /api/auth/me | Get current user | ### Categories | Method | Path | Description | |--------|----------------------------|-----------------------| | GET | /api/categories | List user categories | | POST | /api/categories | Create category | | PUT | /api/categories/:id | Update category | | DELETE | /api/categories/:id | Delete category | ### Budgets | Method | Path | Description | |--------|-----------------------------------|--------------------------------| | GET | /api/budgets | List user budgets | | POST | /api/budgets | Create budget | | GET | /api/budgets/:id | Get budget with items + totals | | PUT | /api/budgets/:id | Update budget | | DELETE | /api/budgets/:id | Delete budget | | POST | /api/budgets/:id/copy-from/:srcId | Copy items from another budget | ### Budget Items | Method | Path | Description | |--------|-----------------------------------|---------------------| | POST | /api/budgets/:id/items | Create budget item | | PUT | /api/budgets/:id/items/:itemId | Update budget item | | DELETE | /api/budgets/:id/items/:itemId | Delete budget item | ### User Settings | Method | Path | Description | |--------|-----------------------|-----------------------| | GET | /api/settings | Get user settings | | PUT | /api/settings | Update user settings | ## 10. Deployment ### compose.yml ```yaml services: app: build: . ports: - "8080:8080" environment: - DATABASE_URL=postgres://user:pass@db:5432/simplefinancedash?sslmode=disable - OIDC_ISSUER=https://auth.example.com - OIDC_CLIENT_ID=simplefinancedash - OIDC_CLIENT_SECRET=secret - SESSION_SECRET=change-me depends_on: db: condition: service_healthy db: image: postgres:16-alpine volumes: - pgdata:/var/lib/postgresql/data environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=simplefinancedash healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d simplefinancedash"] interval: 5s timeout: 5s retries: 5 volumes: pgdata: ``` ### Dockerfile Multi-stage build: 1. Node stage: build React SPA 2. Go stage: embed SPA, compile binary 3. Final stage: minimal image (distroless or alpine) with single binary ## 11. Testing ### Backend (Go) - Unit tests for business logic and handlers - Integration tests against a test PostgreSQL instance (testcontainers) - API endpoint tests with httptest ### Frontend (React) - Component tests with Vitest + React Testing Library - Page-level integration tests ### E2E - Playwright for critical user flows (login, create budget, edit items, view dashboard) ## 12. Non-Goals (MVP) These are explicitly out of scope for v1 but should be kept in mind architecturally: - CSV / bank import - Recurring / automated transactions - Shared / household budgets - Custom themes / color picker - GraphQL API - PDF / CSV export - Weekly / yearly views - Mobile app ## 13. Future Considerations - **Customization engine**: User-defined colors, layout preferences, category icons - **Sharing**: Invite users to a shared budget (household mode) - **Automations**: Recurring transactions, auto-carryover between months - **Summaries**: Monthly/yearly reports with trends - **GraphQL**: For flexible dashboard queries and aggregations - **Import/Export**: CSV import from banks, PDF/CSV export of reports