Init
This commit is contained in:
319
PRD.md
Normal file
319
PRD.md
Normal 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
|
||||
Reference in New Issue
Block a user