This commit is contained in:
2026-03-06 19:42:15 +00:00
parent abcbe3e1e5
commit 04cbb846d1
99 changed files with 11724 additions and 0 deletions

319
PRD.md Normal file
View File

@@ -0,0 +1,319 @@
# 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