Grundgerüst für Certain Finance: - Backend: FastAPI + SQLAlchemy + SQLite, Alembic-Migrationen (Batch-Mode), argon2-Passwort-Hashing, server-seitige Sitzungen im Cookie, Erst-Admin, Benutzerverwaltung mit Temporär-Passwort, Einstellungen je Benutzer. - Ein Prozess, ein Port: uvicorn liefert API (/api) und gebautes SPA aus, inkl. SPA-Deeplink-Fallback. - Frontend: React 18 + Vite + JSX, Design-Tokens (Light/Dark), i18n DE/EN, Inline-SVG-Icons (keine Emojis), Login, Passwort-ändern, Dashboard-Platzhalter, Benutzer- und Einstellungsseiten. - Deploy: nativer LXC-Installer + Update-Skript (systemd), env-Vorlage, Doku. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
60 lines
2.8 KiB
Markdown
60 lines
2.8 KiB
Markdown
# Architektur
|
||
|
||
## Überblick
|
||
|
||
Ein einzelner Python-Prozess (uvicorn/FastAPI) liefert sowohl die JSON-API unter
|
||
`/api/*` als auch das gebaute Frontend (`web/dist`, mit SPA-Fallback) auf **einem**
|
||
Port aus. HTTPS terminiert extern der Nginx Proxy Manager; der Dienst lauscht nur
|
||
auf `127.0.0.1:<APP_PORT>`.
|
||
|
||
```
|
||
Browser ──HTTPS──> Nginx Proxy Manager ──HTTP──> 127.0.0.1:APP_PORT (uvicorn)
|
||
├── /api/* → FastAPI-Router
|
||
└── /* → web/dist (SPA)
|
||
```
|
||
|
||
## Verzeichnisse
|
||
|
||
```
|
||
backend/ app/ (config, database, security, deps, main, models, schemas, seed,
|
||
migrate, routers/*, services/*), migrations/ (Alembic), requirements.txt
|
||
web/ src/ (main.jsx, App.jsx, brand.js, api.js, auth.jsx, settings.jsx,
|
||
i18n.js, locales/, format.js, theme.js, styles.css, finance.css,
|
||
components/, pages/), package.json, vite.config.js
|
||
deploy/ certain-finance.service, install.sh, update.sh, env.example
|
||
docs/ ARCHITECTURE.md, ROADMAP.md
|
||
```
|
||
|
||
## Backend
|
||
|
||
- **Konfiguration** (`app/config.py`): Umgebungsvariablen mit Präfix `APP_`.
|
||
Standardwerte sind dev-freundlich; Produktivwerte kommen aus `/etc/certain-finance/env`.
|
||
- **Datenbank** (`app/database.py`): SQLite mit WAL, `foreign_keys=ON`, Busy-Timeout.
|
||
- **Migrationen**: Alembic (`migrations/`), `render_as_batch=True` (Pflicht für SQLite).
|
||
Werden beim App-Start automatisch angewandt (`app/migrate.py`) – und vom Install-/
|
||
Update-Skript.
|
||
- **Auth** (`app/security.py`, `app/services/sessions.py`, `app/deps.py`): argon2-
|
||
Passwort-Hashing; server-seitige Sitzungen (im Cookie nur das Klartext-Token,
|
||
in der DB nur dessen SHA-256-Hash). Erst-Admin beim ersten Start; weitere Nutzer
|
||
legt der Admin mit Temporär-Passwort an (Änderung beim ersten Login erzwungen).
|
||
- **Isolation**: Ab Phase 1 trägt jede fachliche Tabelle ein `owner_id`; jeder
|
||
Nutzer sieht ausschließlich seine eigenen Daten.
|
||
|
||
## Frontend
|
||
|
||
- React 18 + Vite + reines JSX, Router mit `Protected`-Wrapper (Login immer nötig).
|
||
- **Design-Tokens** in `styles.css` (aus der Vorlage übernommen), Ergänzungen in
|
||
`finance.css`. Volle Hell/Dunkel-Unterstützung (`prefers-color-scheme` + `data-theme`).
|
||
- **i18n** (react-i18next): Deutsch Standard, Englisch optional; Sprache aus der
|
||
Benutzer-Einstellung `locale`.
|
||
- **Icons**: ausschließlich Inline-SVG (`components/Icon.jsx`), niemals Emojis.
|
||
- **API-Client** (`api.js`): alles über `/api`, immer `credentials:"include"`
|
||
(Cookie-Sitzung), zentrales 401-Handling.
|
||
|
||
## Namensgebung
|
||
|
||
Der Anzeigename „Certain Finance" steht nur in `web/src/brand.js` und
|
||
`backend/app/branding.py`. Intern ist alles generisch (Paket `app`, Env-Präfix
|
||
`APP_`). Der Betriebs-Slug `certain-finance` (systemd-Dienst, Pfade) steht in den
|
||
Deploy-Skripten je einmal oben als Variable.
|