import uuid from datetime import datetime from sqlalchemy import Boolean, ForeignKey, String from sqlalchemy.dialects.postgresql import TIMESTAMP, UUID from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base class ApiToken(Base): """FOUND-016: langlebiges Token für Entwicklungs-/Tooling-Zugriff auf die API (kein Nutzer-Login-Flow) - `benutzer_id` zeigt auf einen begleitenden Dienstkonto-Benutzer (`Benutzer.ist_dienstkonto=True`), der die dem Token zugewiesenen Rollen trägt. Nur `token_hash` wird gespeichert (SHA-256, kein bcrypt nötig - hochentropisches Zufallstoken statt Passwort mit Wörterbuch-/Brute-Force-Risiko, siehe app/core/security.py), der Klartext wird ausschließlich einmalig bei der Erzeugung zurückgegeben.""" __tablename__ = "api_token" id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name: Mapped[str] = mapped_column(String, nullable=False) token_hash: Mapped[str] = mapped_column(String, unique=True, nullable=False) benutzer_id: Mapped[int] = mapped_column(ForeignKey("benutzer.id"), nullable=False, unique=True) aktiv: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) erstellt_am: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True), nullable=False) erstellt_von_benutzer_id: Mapped[int] = mapped_column(ForeignKey("benutzer.id"), nullable=False) letzte_verwendung_am: Mapped[datetime | None] = mapped_column(TIMESTAMP(timezone=True))