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

51 lines
2.6 KiB
Python

"""Workspaces und Mitgliedschaften (→ Konzept 6)."""
from datetime import datetime
from typing import Any
from sqlalchemy import JSON, ForeignKey, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.core.database import Base, now
# admin: verwaltet den Workspace und entscheidet Anträge; approver (Freigeber): entscheidet Anträge
ROLES = ("admin", "approver", "member")
APPROVER_ROLES = ("admin", "approver")
ROLE_LABELS = {"admin": "Admin", "approver": "Freigeber", "member": "Mitglied"}
# Freigabemodus (→ Konzept 10.3): risikobasiert oder jede Schreibaktion nach außen
APPROVAL_MODES = ("risk", "all_writes")
class Workspace(Base):
__tablename__ = "workspaces"
id: Mapped[int] = mapped_column(primary_key=True)
# Jeder Workspace gehört genau einem Team (→ Konzept 5.4)
team_id: Mapped[int] = mapped_column(ForeignKey("teams.id"), index=True)
name: Mapped[str] = mapped_column(String(200))
description: Mapped[str] = mapped_column(Text, default="")
approval_mode: Mapped[str] = mapped_column(String(20), default="risk")
# Spätere Anbindungen (→ Konzept 7.6, 7.9); hier nur Referenzen
munin_key_ref: Mapped[str | None] = mapped_column(String(200))
hugin_project: Mapped[str | None] = mapped_column(String(64))
# Leer = Standardmodell der Plattform (→ Konzept 8.1)
model_id: Mapped[int | None] = mapped_column(ForeignKey("models.id", ondelete="SET NULL"))
settings: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict)
created_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
created: Mapped[datetime] = mapped_column(default=now)
# Webhook für Benachrichtigungen (Teams/Slack), verschlüsselt; Hint = Host zur Anzeige
webhook: Mapped[str | None] = mapped_column(Text)
webhook_hint: Mapped[str] = mapped_column(String(40), default="", server_default="")
# Papierkorb: gesetzt = gelöscht, aber noch wiederherstellbar bis zur endgültigen Löschung
# Speicherkontingent für Uploads in MB; leer = AIW_WORKSPACE_STORAGE_MB
storage_limit_mb: Mapped[int | None]
deleted: Mapped[datetime | None] = mapped_column(index=True)
deleted_by: Mapped[int | None] = mapped_column(ForeignKey("users.id"))
class WorkspaceMembership(Base):
__tablename__ = "workspace_memberships"
workspace_id: Mapped[int] = mapped_column(ForeignKey("workspaces.id", ondelete="CASCADE"), primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), primary_key=True, index=True)
role: Mapped[str] = mapped_column(String(20), default="member")