from __future__ import annotations from datetime import datetime from sqlalchemy import Boolean, DateTime, ForeignKey, Index, String, func from sqlalchemy.orm import Mapped, mapped_column, relationship from src.db.base import Base class AppUser(Base): __tablename__ = "app_user" __table_args__ = ( Index( "ix_v4_app_user_active", "is_active", postgresql_where="is_active", ), Index("ix_v4_app_user_role", "role_id"), {"schema": "v3"}, ) id: Mapped[int] = mapped_column(primary_key=True) email: Mapped[str] = mapped_column(String) username: Mapped[str] = mapped_column(String) hashed_password: Mapped[str] = mapped_column(String) full_name: Mapped[str | None] = mapped_column(String) role_id: Mapped[int] = mapped_column(ForeignKey("v3.role.id")) is_active: Mapped[bool] = mapped_column(Boolean, default=True) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now() ) updated_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) # role: Mapped["Role"] = relationship("Role", back_populates="users") # type: ignore # created_budget_forms: Mapped[list["BudgetForm"]] = relationship( # type: ignore # "BudgetForm", back_populates="creator", foreign_keys="BudgetForm.created_by" # ) # updated_budget_forms: Mapped[list["BudgetForm"]] = relationship( # type: ignore # "BudgetForm", back_populates="updater", foreign_keys="BudgetForm.updated_by" # ) # created_rf_reports: Mapped[list["RfProjectReport"]] = relationship( # type: ignore # "RfProjectReport", # back_populates="creator", # foreign_keys="RfProjectReport.created_by", # ) # updated_rf_reports: Mapped[list["RfProjectReport"]] = relationship( # type: ignore # "RfProjectReport", # back_populates="updater", # foreign_keys="RfProjectReport.updated_by", # ) audit_logs: Mapped[list["AuditLog"]] = relationship( # type: ignore "AuditLog", back_populates="user" ) user_orgs: Mapped[list["UserOrg"]] = relationship("UserOrg", back_populates="user") org_units: Mapped[list["OrgUnit"]] = relationship("OrgUnit", secondary="v3.user_org", viewonly=True)