320 lines
10 KiB
Markdown
320 lines
10 KiB
Markdown
# 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
|