10 KiB
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)
- 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
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:
- Node stage: build React SPA
- Go stage: embed SPA, compile binary
- 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