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>
2.8 KiB
2.8 KiB
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äfixAPP_. 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 infinance.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, immercredentials:"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.