Architektur Übersicht aktualisiert
@@ -1,122 +1,122 @@
|
|||||||
# Architektur-Übersicht
|
# Architektur-Übersicht
|
||||||
|
|
||||||
## Stack
|
## Stack
|
||||||
|
|
||||||
| Schicht | Technologie |
|
| Schicht | Technologie |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Frontend | Angular 21, Standalone Components, Signals |
|
| Frontend | Angular 21, Standalone Components, Signals |
|
||||||
| Styling | Tailwind CSS v4, Flowbite Design System |
|
| Styling | Tailwind CSS v4, Flowbite Design System |
|
||||||
| Charts | ApexCharts 3.46 |
|
| Charts | ApexCharts 3.46 |
|
||||||
| i18n | ngx-translate (DE, FR, IT, EN) |
|
| i18n | ngx-translate (DE, FR, IT, EN) |
|
||||||
| Backend | Django REST Framework, Python 3.12 |
|
| Backend | Django REST Framework, Python 3.12 |
|
||||||
| Auth | SimpleJWT (Access 60min, Refresh 7d, Rotation + Blacklist) |
|
| Auth | SimpleJWT (Access 60min, Refresh 7d, Rotation + Blacklist) |
|
||||||
| Datenbank | PostgreSQL |
|
| Datenbank | PostgreSQL |
|
||||||
| E-Mail | Brevo SMTP (`smtp-relay.brevo.com:587`) |
|
| E-Mail | Brevo SMTP (`smtp-relay.brevo.com:587`) |
|
||||||
| Server | Hetzner Ubuntu 24.04, Gunicorn + Nginx, Certbot (HTTPS) |
|
| Server | Hetzner Ubuntu 24.04, Gunicorn + Nginx, Certbot (HTTPS) |
|
||||||
| Font | Roboto via `@fontsource/roboto` (selbst-gehostet, DSGVO-konform) |
|
| Font | Roboto via `@fontsource/roboto` (selbst-gehostet, DSGVO-konform) |
|
||||||
|
|
||||||
## Verzeichnisstruktur
|
## Verzeichnisstruktur
|
||||||
|
|
||||||
```
|
```
|
||||||
armarium-suite/
|
armarium-suite/
|
||||||
├── backend/
|
├── backend/
|
||||||
│ ├── core/ # Django-Projektkonfiguration (settings, urls)
|
│ ├── core/ # Django-Projektkonfiguration (settings, urls)
|
||||||
│ ├── finance/ # Haupt-App (Models, Views, Serializers)
|
│ ├── finance/ # Haupt-App (Models, Views, Serializers)
|
||||||
│ │ ├── migrations/
|
│ │ ├── migrations/
|
||||||
│ │ ├── models.py
|
│ │ ├── models.py
|
||||||
│ │ ├── views.py
|
│ │ ├── views.py
|
||||||
│ │ ├── serializers.py
|
│ │ ├── serializers.py
|
||||||
│ │ ├── email.py # send_email() Helper
|
│ │ ├── email.py # send_email() Helper
|
||||||
│ │ └── backends.py # EmailAuthBackend
|
│ │ └── backends.py # EmailAuthBackend
|
||||||
│ ├── templates/emails/ # HTML + Plaintext E-Mail-Templates
|
│ ├── templates/emails/ # HTML + Plaintext E-Mail-Templates
|
||||||
│ ├── requirements.txt
|
│ ├── requirements.txt
|
||||||
│ └── .env # Nicht im Repo
|
│ └── .env # Nicht im Repo
|
||||||
└── frontend/
|
└── frontend/
|
||||||
├── src/app/
|
├── src/app/
|
||||||
│ ├── auth/ # Login, Register, ForgotPassword, ResetPassword, VerifyEmail
|
│ ├── auth/ # Login, Register, ForgotPassword, ResetPassword, VerifyEmail
|
||||||
│ ├── dashboard/
|
│ ├── dashboard/
|
||||||
│ ├── services/ # ApiService, AuthService, FinancialYearService, ...
|
│ ├── services/ # ApiService, AuthService, FinancialYearService, ...
|
||||||
│ ├── layout/ # Shell, Navbar, Sidebar
|
│ ├── layout/ # Shell, Navbar, Sidebar
|
||||||
│ └── ...
|
│ └── ...
|
||||||
├── src/assets/i18n/ # de.json, en.json, fr.json, it.json
|
├── src/assets/i18n/ # de.json, en.json, fr.json, it.json
|
||||||
└── src/budget-app-theme.css # Tailwind v4 Custom Theme (Violet Primary)
|
└── src/budget-app-theme.css # Tailwind v4 Custom Theme (Violet Primary)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Datenmodelle
|
## Datenmodelle
|
||||||
|
|
||||||
| Modell | Beschreibung |
|
| Modell | Beschreibung |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `Profile` | Erweitertes User-Profil (Avatar, Kanton, 2FA, Tokens, Prefs) |
|
| `Profile` | Erweitertes User-Profil (Avatar, Kanton, 2FA, Tokens, Prefs) |
|
||||||
| `Account` | Konten (asset, expense, revenue) |
|
| `Account` | Konten (asset, expense, revenue) |
|
||||||
| `Transaction` | Doppelte Buchführung (source + destination Account) |
|
| `Transaction` | Doppelte Buchführung (source + destination Account) |
|
||||||
| `Budget` | Budgetkategorien (7 Kategorien) |
|
| `Budget` | Budgetkategorien (7 Kategorien) |
|
||||||
| `Expense` | Ausgaben mit Fälligkeitsdatum |
|
| `Expense` | Ausgaben mit Fälligkeitsdatum |
|
||||||
| `Deadline` | Termine (Steuern, Versicherung, Rechnung, etc.) |
|
| `Deadline` | Termine (Steuern, Versicherung, Rechnung, etc.) |
|
||||||
| `UserSession` | Aktive Sessions mit Gerätename, IP, JWT-JTI |
|
| `UserSession` | Aktive Sessions mit Gerätename, IP, JWT-JTI |
|
||||||
| `BackupCode` | 2FA-Backup-Codes (SHA-256-Hash) |
|
| `BackupCode` | 2FA-Backup-Codes (SHA-256-Hash) |
|
||||||
| `FinancialYear` | Jahresplanung (User oder Haushalt) |
|
| `FinancialYear` | Jahresplanung (User oder Haushalt) |
|
||||||
| `YearlyIncome` | Einnahmen pro Jahr |
|
| `YearlyIncome` | Einnahmen pro Jahr |
|
||||||
| `YearlyBudgetItem` | Fixkosten pro Jahr |
|
| `YearlyBudgetItem` | Fixkosten pro Jahr |
|
||||||
| `Household` | Gemeinsamer Haushalt |
|
| `Household` | Gemeinsamer Haushalt |
|
||||||
| `HouseholdMembership` | Haushalt-Mitgliedschaft mit Rolle und Status |
|
| `HouseholdMembership` | Haushalt-Mitgliedschaft mit Rolle und Status |
|
||||||
|
|
||||||
## API-Endpunkte (Übersicht)
|
## API-Endpunkte (Übersicht)
|
||||||
|
|
||||||
### Auth
|
### Auth
|
||||||
| Methode | Endpunkt | Beschreibung |
|
| Methode | Endpunkt | Beschreibung |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| POST | `/api/auth/register/` | Registrierung (sendet Bestätigungsmail) |
|
| POST | `/api/auth/register/` | Registrierung (sendet Bestätigungsmail) |
|
||||||
| POST | `/api/auth/verify-email/` | E-Mail bestätigen |
|
| POST | `/api/auth/verify-email/` | E-Mail bestätigen |
|
||||||
| POST | `/api/auth/token/` | Login |
|
| POST | `/api/auth/token/` | Login |
|
||||||
| POST | `/api/auth/token/refresh/` | JWT erneuern |
|
| POST | `/api/auth/token/refresh/` | JWT erneuern |
|
||||||
| POST | `/api/auth/logout/` | Logout + Blacklist |
|
| POST | `/api/auth/logout/` | Logout + Blacklist |
|
||||||
| POST | `/api/auth/password/` | Passwort ändern |
|
| POST | `/api/auth/password/` | Passwort ändern |
|
||||||
| POST | `/api/auth/password-reset/` | Reset anfordern |
|
| POST | `/api/auth/password-reset/` | Reset anfordern |
|
||||||
| POST | `/api/auth/password-reset/confirm/` | Neues Passwort setzen |
|
| POST | `/api/auth/password-reset/confirm/` | Neues Passwort setzen |
|
||||||
| POST | `/api/auth/2fa/login/` | TOTP-Verifikation |
|
| POST | `/api/auth/2fa/login/` | TOTP-Verifikation |
|
||||||
| POST | `/api/auth/2fa/setup/` | 2FA einrichten |
|
| POST | `/api/auth/2fa/setup/` | 2FA einrichten |
|
||||||
| POST | `/api/auth/2fa/enable/` | 2FA aktivieren |
|
| POST | `/api/auth/2fa/enable/` | 2FA aktivieren |
|
||||||
| POST | `/api/auth/2fa/disable/` | 2FA deaktivieren |
|
| POST | `/api/auth/2fa/disable/` | 2FA deaktivieren |
|
||||||
| POST | `/api/auth/2fa/recover/` | Recovery-Code anfordern |
|
| POST | `/api/auth/2fa/recover/` | Recovery-Code anfordern |
|
||||||
| POST | `/api/auth/2fa/recover/confirm/` | Recovery bestätigen |
|
| POST | `/api/auth/2fa/recover/confirm/` | Recovery bestätigen |
|
||||||
| GET | `/api/auth/sessions/` | Session-Liste |
|
| GET | `/api/auth/sessions/` | Session-Liste |
|
||||||
| DELETE | `/api/auth/sessions/<key>/` | Session widerrufen |
|
| DELETE | `/api/auth/sessions/<key>/` | Session widerrufen |
|
||||||
| DELETE | `/api/auth/sessions/revoke-all/` | Alle anderen Sessions widerrufen |
|
| DELETE | `/api/auth/sessions/revoke-all/` | Alle anderen Sessions widerrufen |
|
||||||
|
|
||||||
### Daten
|
### Daten
|
||||||
| Methode | Endpunkt | Beschreibung |
|
| Methode | Endpunkt | Beschreibung |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| GET/PUT | `/api/profile/` | Profil lesen/aktualisieren |
|
| GET/PUT | `/api/profile/` | Profil lesen/aktualisieren |
|
||||||
| GET/POST/PUT/DELETE | `/api/accounts/` | Konten |
|
| GET/POST/PUT/DELETE | `/api/accounts/` | Konten |
|
||||||
| GET/POST/PUT/DELETE | `/api/transactions/` | Transaktionen |
|
| GET/POST/PUT/DELETE | `/api/transactions/` | Transaktionen |
|
||||||
| GET/POST/PUT/DELETE | `/api/budgets/` | Budgets |
|
| GET/POST/PUT/DELETE | `/api/budgets/` | Budgets |
|
||||||
| GET/POST/PUT/DELETE | `/api/expenses/` | Ausgaben |
|
| GET/POST/PUT/DELETE | `/api/expenses/` | Ausgaben |
|
||||||
| GET/POST/PUT/DELETE | `/api/deadlines/` | Termine |
|
| GET/POST/PUT/DELETE | `/api/deadlines/` | Termine |
|
||||||
| GET | `/api/export/` | ZIP-Export (6 PDFs) |
|
| GET | `/api/export/` | ZIP-Export (6 PDFs) |
|
||||||
| GET | `/api/search/` | Globale Suche |
|
| GET | `/api/search/` | Globale Suche |
|
||||||
| GET | `/api/notifications/` | Benachrichtigungen |
|
| GET | `/api/notifications/` | Benachrichtigungen |
|
||||||
| PATCH | `/api/notifications/prefs/` | Benachrichtigungs-Prefs |
|
| PATCH | `/api/notifications/prefs/` | Benachrichtigungs-Prefs |
|
||||||
|
|
||||||
### Jahresplanung
|
### Jahresplanung
|
||||||
| Methode | Endpunkt | Beschreibung |
|
| Methode | Endpunkt | Beschreibung |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| GET/POST | `/api/financial-years/` | Jahre auflisten / erstellen |
|
| GET/POST | `/api/financial-years/` | Jahre auflisten / erstellen |
|
||||||
| GET/PATCH/DELETE | `/api/financial-years/<year>/` | Jahr-Detail |
|
| GET/PATCH/DELETE | `/api/financial-years/<year>/` | Jahr-Detail |
|
||||||
| POST | `/api/financial-years/<year>/copy-from/<source>/` | Jahr kopieren |
|
| POST | `/api/financial-years/<year>/copy-from/<source>/` | Jahr kopieren |
|
||||||
| GET/POST | `/api/financial-years/<year>/incomes/` | Einnahmen |
|
| GET/POST | `/api/financial-years/<year>/incomes/` | Einnahmen |
|
||||||
| GET/POST | `/api/financial-years/<year>/budget-items/` | Fixkosten |
|
| GET/POST | `/api/financial-years/<year>/budget-items/` | Fixkosten |
|
||||||
| GET/POST | `/api/households/` | Haushalte |
|
| GET/POST | `/api/households/` | Haushalte |
|
||||||
| POST | `/api/households/<pk>/invite/` | Mitglied einladen |
|
| POST | `/api/households/<pk>/invite/` | Mitglied einladen |
|
||||||
| POST | `/api/households/<pk>/accept/` | Einladung annehmen |
|
| POST | `/api/households/<pk>/accept/` | Einladung annehmen |
|
||||||
| POST | `/api/households/<pk>/leave/` | Haushalt verlassen |
|
| POST | `/api/households/<pk>/leave/` | Haushalt verlassen |
|
||||||
|
|
||||||
## Sicherheits-Architektur
|
## Sicherheits-Architektur
|
||||||
|
|
||||||
- **JWT**: Access-Token 60min, Refresh-Token 7 Tage, Rotation + Blacklist
|
- **JWT**: Access-Token 60min, Refresh-Token 7 Tage, Rotation + Blacklist
|
||||||
- **2FA**: TOTP (pyotp), HMAC-signierter Temp-Token (5min), Replay-Schutz, 8 Backup-Codes (SHA-256)
|
- **2FA**: TOTP (pyotp), HMAC-signierter Temp-Token (5min), Replay-Schutz, 8 Backup-Codes (SHA-256)
|
||||||
- **Passwort-Reset**: Token als SHA-256-Hash in DB, 15min TTL, anti-enumeration Response
|
- **Passwort-Reset**: Token als SHA-256-Hash in DB, 15min TTL, anti-enumeration Response
|
||||||
- **E-Mail-Verifikation**: Token als SHA-256-Hash, 24h TTL
|
- **E-Mail-Verifikation**: Token als SHA-256-Hash, 24h TTL
|
||||||
- **Rate-Limiting**: 5/min Auth, 200/min User, 20/min Anon
|
- **Rate-Limiting**: 5/min Auth, 200/min User, 20/min Anon
|
||||||
- **Sessions**: Alle Sessions werden bei Passwortänderung/-reset invalidiert
|
- **Sessions**: Alle Sessions werden bei Passwortänderung/-reset invalidiert
|
||||||
- **Produktion**: HTTPS-Redirect, HSTS (1 Jahr), Secure Cookies, Content-Type-Nosniff
|
- **Produktion**: HTTPS-Redirect, HSTS (1 Jahr), Secure Cookies, Content-Type-Nosniff
|
||||||
- **CAPTCHA**: Cloudflare Turnstile auf Login + Register
|
- **CAPTCHA**: Cloudflare Turnstile auf Login + Register
|
||||||
Reference in New Issue
Block a user