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>
This commit is contained in:
39
scripts/verify_import.py
Normal file
39
scripts/verify_import.py
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Beweis für den Cut-over: Bundle aus der DB == Git-Ordner (Hash-Vergleich, ohne deploy-Block)."""
|
||||
import hashlib
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from app.db import session # noqa: E402
|
||||
from app.models import Tenant # noqa: E402
|
||||
from app.services import store # noqa: E402
|
||||
from app.settings import LEGACY_PLATFORM # noqa: E402
|
||||
from sqlalchemy import select # noqa: E402
|
||||
|
||||
root = Path(sys.argv[1]) if len(sys.argv) > 1 else LEGACY_PLATFORM
|
||||
bad = 0
|
||||
with session() as db:
|
||||
for t in db.scalars(select(Tenant).order_by(Tenant.id)):
|
||||
tdir = root / "tenants" / t.id
|
||||
cfg, files = store.content(db, t, "current")
|
||||
git_cfg = json.loads((tdir / "tenant.json").read_text(encoding="utf-8"))
|
||||
git_cfg.pop("deploy", None)
|
||||
problems = []
|
||||
if json.dumps(git_cfg, sort_keys=True) != json.dumps(cfg, sort_keys=True):
|
||||
problems.append("tenant.json weicht ab")
|
||||
for path, sha in files.items():
|
||||
p = tdir / path
|
||||
if not p.exists():
|
||||
problems.append(f"{path}: fehlt in Git")
|
||||
elif hashlib.sha256(p.read_bytes()).hexdigest() != sha:
|
||||
problems.append(f"{path}: Hash weicht ab")
|
||||
for p in tdir.rglob("*"):
|
||||
rel = p.relative_to(tdir).as_posix()
|
||||
if p.is_file() and rel not in files and rel not in ("tenant.json", "secrets.enc.yaml") and "__pycache__" not in rel:
|
||||
problems.append(f"{rel}: fehlt in DB")
|
||||
print(("✔" if not problems else "✘"), t.id, "; ".join(problems))
|
||||
bad += bool(problems)
|
||||
sys.exit(1 if bad else 0)
|
||||
Reference in New Issue
Block a user