import uuid from datetime import datetime, timezone from sqlalchemy import DateTime, Float, ForeignKey, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column from db import Base def _utcnow() -> datetime: return datetime.now(timezone.utc) def _new_uuid() -> uuid.UUID: return uuid.uuid4() class User(Base): __tablename__ = "users" id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=_new_uuid) name: Mapped[str] = mapped_column(String(255)) email: Mapped[str] = mapped_column(String(255), unique=True, index=True) password_hash: Mapped[str] = mapped_column(Text) role: Mapped[str] = mapped_column(String(20), default="admin") created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow) last_login_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) class APIKey(Base): __tablename__ = "api_keys" id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=_new_uuid) key_prefix: Mapped[str] = mapped_column(String(12)) key_hash: Mapped[str] = mapped_column(Text) label: Mapped[str] = mapped_column(String(255)) created_by: Mapped[uuid.UUID] = mapped_column(ForeignKey("users.id", ondelete="CASCADE")) last_used_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) revoked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow) class RequestLog(Base): __tablename__ = "request_logs" id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=_new_uuid) method: Mapped[str] = mapped_column(String(16)) path: Mapped[str] = mapped_column(String(512)) status_code: Mapped[int] = mapped_column(Integer) latency_ms: Mapped[float] = mapped_column(Float) auth_type: Mapped[str] = mapped_column(String(32), default="none") created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow) class RefreshTokenJti(Base): __tablename__ = "refresh_token_jtis" jti: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=_new_uuid) user_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("users.id", ondelete="CASCADE")) expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True)) used_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_utcnow) class Settings(Base): __tablename__ = "settings" key: Mapped[str] = mapped_column(String(255), primary_key=True) value: Mapped[str] = mapped_column(Text) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=_utcnow, onupdate=_utcnow, )