Files
Onyscribe-Admin/app/main.py
RubenRWU 7d8c226da2 Onyscribe Admin: Initialer Stand
Admin-Plattform für die Tenants von Onyscribe: Editor mit Live-Vorschau (echter Core in Sandbox), Versionen, KI-Agent (Cortecs),
OIDC-Abgleich über die Login-Developer-API, Deploy-Engine (Mittwald, gesperrt ohne DEPLOY_LIVE, Freigabe pro Tenant),
Core-Vertrag (Schema/Manifest), Core-Releases mit Kompatibilitätsprüfung, Canary-Rollout und Rollback, Zustandsabgleich.
Runbook: docs/RUNBOOK_PARALLELTEST.md

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 15:30:26 +02:00

43 lines
1.2 KiB
Python

from __future__ import annotations
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from app.db import init_db, session
from app import auth
from app.routers import api, pages
from sqlalchemy import func, select
from app.models import Tenant
from app.services import seed
from app.services.importer import seed_settings
from app.settings import ROOT
SEED_FILE = ROOT / "seed" / "tenants.seed.json.gz"
@asynccontextmanager
async def lifespan(_: FastAPI):
init_db()
with session() as db:
# Frische Instanz → mit den importierten Tenants starten (ohne Secret-Werte)
if SEED_FILE.exists() and not db.scalar(select(func.count()).select_from(Tenant)):
print(f"[seed] {seed.load(db, SEED_FILE)} Tenants aus {SEED_FILE.name} geladen")
seed_settings(db)
yield
app = FastAPI(title="Onyscribe Admin", lifespan=lifespan)
app.middleware("http")(auth.middleware)
app.include_router(auth.router)
app.mount("/static", StaticFiles(directory=str(ROOT / "app" / "static")), name="static")
app.include_router(api.router)
app.include_router(pages.router)
@app.get("/healthz")
def healthz():
return {"ok": True}