bifroest/app/hugin/models.py
2026-10-27 08:34:17 +01:00

86 lines
4.3 KiB
Python

"""Hugin-Anbindung (→ Konzept 7.9): Host der Plattform, Zugang je Workspace, Auswahl und festgeschriebene Pakete je Workspace.
Festgeschrieben wird wie in hugin.lock: Version und Prüfsumme aus Hugin, dazu das Paket im
Quellformat als ZIP und dessen SHA-256. Beim Laden für einen Run wird die Kopie geprüft.
"""
from datetime import datetime
from typing import Any
from sqlalchemy import JSON, Boolean, ForeignKey, LargeBinary, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.core.database import Base, now
class HuginHost(Base):
"""Die Hugin-Instanz der Plattform (genau eine Zeile, id 1); pflegt der Plattform-Admin."""
__tablename__ = "hugin_host"
id: Mapped[int] = mapped_column(primary_key=True)
url: Mapped[str] = mapped_column(String(500))
# new | ok | error, zuletzt geprüft über /readyz (ohne Key)
status: Mapped[str] = mapped_column(String(16), default="new")
status_message: Mapped[str] = mapped_column(Text, default="")
checked: Mapped[datetime | None] = mapped_column(nullable=True)
updated_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
updated: Mapped[datetime] = mapped_column(default=now)
class WorkspaceHugin(Base):
"""Zugang des Workspace: Integrations-Key (hi_…) seines Tenants; pflegt der Workspace-Admin.
Tenant und Key-Name meldet Hugin beim Testen (/status); Pflichtpakete kommen aus diesem Tenant."""
__tablename__ = "workspace_hugin"
workspace_id: Mapped[int] = mapped_column(ForeignKey("workspaces.id", ondelete="CASCADE"), primary_key=True)
secret: Mapped[str] = mapped_column(Text)
hint: Mapped[str] = mapped_column(String(8))
status: Mapped[str] = mapped_column(String(16), default="new")
status_message: Mapped[str] = mapped_column(Text, default="")
tenant: Mapped[str] = mapped_column(String(64), default="")
key_name: Mapped[str] = mapped_column(String(200), default="")
checked: Mapped[datetime | None] = mapped_column(nullable=True)
# Letzter Abgleich (Hintergrund oder Admin) und was er fand: Updates, veraltete Pakete, neue oder
# entfallene Pflichtpakete, neue Hauptversionen. Leer = alles aktuell.
synced: Mapped[datetime | None] = mapped_column(nullable=True)
findings: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict)
updated_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
updated: Mapped[datetime] = mapped_column(default=now)
class WorkspaceHuginPackage(Base):
"""Vom Workspace-Admin gewähltes Paket, wie eine Zeile in .hugin.yaml (z. B. pub-x@stable)."""
__tablename__ = "workspace_hugin_packages"
workspace_id: Mapped[int] = mapped_column(ForeignKey("workspaces.id", ondelete="CASCADE"), primary_key=True)
package_id: Mapped[str] = mapped_column(String(64), primary_key=True)
spec: Mapped[str] = mapped_column(String(32), default="stable")
added_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
added: Mapped[datetime] = mapped_column(default=now)
class WorkspaceHuginLock(Base):
"""Festgeschriebene Version eines Pakets (gewählt oder Pflicht)."""
__tablename__ = "workspace_hugin_locks"
workspace_id: Mapped[int] = mapped_column(ForeignKey("workspaces.id", ondelete="CASCADE"), primary_key=True)
package_id: Mapped[str] = mapped_column(String(64), primary_key=True)
kind: Mapped[str] = mapped_column(String(16))
version: Mapped[str] = mapped_column(String(32))
checksum: Mapped[str] = mapped_column(String(80)) # Prüfsumme der Version in Hugin
risk: Mapped[str] = mapped_column(String(16))
mandatory: Mapped[bool] = mapped_column(Boolean, default=False)
deprecated: Mapped[bool] = mapped_column(Boolean, default=False)
description: Mapped[str] = mapped_column(Text, default="")
arguments: Mapped[list[str]] = mapped_column(JSON, default=list)
# Paket im Quellformat (hugin.yaml und Dateien) und dessen SHA-256, beim Laden geprüft
archive: Mapped[bytes] = mapped_column(LargeBinary)
archive_sha256: Mapped[str] = mapped_column(String(64))
# Leer = wird angeboten; sonst der Grund, warum nicht (z. B. Skripte, Art nicht unterstützt)
unsupported: Mapped[str] = mapped_column(Text, default="")
locked_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
locked: Mapped[datetime] = mapped_column(default=now)