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>
51 lines
1.3 KiB
Python
51 lines
1.3 KiB
Python
"""Alembic-Umgebung.
|
||
|
||
Nutzt die Engine und die Metadaten der Anwendung (SQLite), damit Migrationen und
|
||
Laufzeit garantiert dieselbe Datenbank/dasselbe Schema verwenden. ``render_as_batch``
|
||
ist für SQLite Pflicht, damit ALTER-TABLE über Tabellen-Kopien läuft.
|
||
"""
|
||
|
||
from logging.config import fileConfig
|
||
|
||
from alembic import context
|
||
|
||
from app.database import Base, engine
|
||
from app import models # noqa: F401 – registriert alle Tabellen an Base.metadata
|
||
|
||
config = context.config
|
||
if config.config_file_name is not None:
|
||
fileConfig(config.config_file_name)
|
||
|
||
target_metadata = Base.metadata
|
||
|
||
|
||
def run_migrations_offline() -> None:
|
||
context.configure(
|
||
url=str(engine.url),
|
||
target_metadata=target_metadata,
|
||
literal_binds=True,
|
||
dialect_opts={"paramstyle": "named"},
|
||
render_as_batch=True,
|
||
compare_type=True,
|
||
)
|
||
with context.begin_transaction():
|
||
context.run_migrations()
|
||
|
||
|
||
def run_migrations_online() -> None:
|
||
with engine.connect() as connection:
|
||
context.configure(
|
||
connection=connection,
|
||
target_metadata=target_metadata,
|
||
render_as_batch=True,
|
||
compare_type=True,
|
||
)
|
||
with context.begin_transaction():
|
||
context.run_migrations()
|
||
|
||
|
||
if context.is_offline_mode():
|
||
run_migrations_offline()
|
||
else:
|
||
run_migrations_online()
|