import enum import uuid from datetime import date from sqlalchemy import CheckConstraint, Date, ForeignKey, String, UniqueConstraint from sqlalchemy.dialects.postgresql import ENUM as PgEnum, UUID from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base class Qualifikationskategorie(str, enum.Enum): fuehrerschein = "fuehrerschein" lehrgang = "lehrgang" berechtigung = "berechtigung" qualifikationskategorie_pg = PgEnum( Qualifikationskategorie, name="qualifikationskategorie", create_type=False ) class Einheit(Base): """Roadmap-Erweiterung (Personal-Modul): Organisationseinheit (Zug/Gruppe), self-referenzierend für Hierarchie (analog Kategorie.ueberkategorie_id). Bewusst eigenständig statt an Standort gekoppelt - eine Einheit kann ortsübergreifend sein, ein Standort mehrere Einheiten beherbergen.""" __tablename__ = "einheit" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String, nullable=False) uebergeordnete_einheit_id: Mapped[int | None] = mapped_column(ForeignKey("einheit.id")) standort_id: Mapped[int | None] = mapped_column(ForeignKey("standort.id")) __table_args__ = ( CheckConstraint("uebergeordnete_einheit_id <> id", name="einheit_kein_selbstbezug"), ) class Qualifikationstyp(Base): """Führerschein/Lehrgang/Berechtigung als ein Stammdaten-Konzept, damit "welche Qualifikation braucht Objekttyp X" generisch bleibt (kein separates Führerschein-Feld am Fahrzeug nötig, Karte-Nachtrag Personal-Modul).""" __tablename__ = "qualifikationstyp" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String, nullable=False) kategorie: Mapped[Qualifikationskategorie] = mapped_column( qualifikationskategorie_pg, nullable=False ) # NULL = unbefristet (z.B. manche Berechtigungen), sonst Gültigkeitsdauer in # Monaten ab erworben_am - Ablauf wird nicht hier, sondern je # BenutzerQualifikation über gueltig_bis geführt (individuelles Datum je # Nachweis, nicht rein rechnerisch aus dem Typ abgeleitet). gueltigkeit_monate: Mapped[int | None] = mapped_column() class BenutzerQualifikation(Base): __tablename__ = "benutzer_qualifikation" id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) benutzer_id: Mapped[int] = mapped_column(ForeignKey("benutzer.id"), nullable=False) qualifikationstyp_id: Mapped[int] = mapped_column(ForeignKey("qualifikationstyp.id"), nullable=False) erworben_am: Mapped[date] = mapped_column(Date, nullable=False) gueltig_bis: Mapped[date | None] = mapped_column(Date) nachweis_nummer: Mapped[str | None] = mapped_column(String) __table_args__ = ( UniqueConstraint( "benutzer_id", "qualifikationstyp_id", "erworben_am", name="uq_benutzer_qualifikation" ), ) class ObjekttypQualifikationsanforderung(Base): """M:N: welche Qualifikationstypen braucht man, um Objekte dieses Objekttyps zu bedienen/fahren (Nutzer-Beispiel: "wer darf GW-San 01 fahren?").""" __tablename__ = "objekttyp_qualifikationsanforderung" objekttyp_id: Mapped[int] = mapped_column(ForeignKey("objekttyp.id"), primary_key=True) qualifikationstyp_id: Mapped[int] = mapped_column( ForeignKey("qualifikationstyp.id"), primary_key=True )