""" User model for AegisLM SaaS Backend. Production-ready SQLAlchemy model with proper indexing, relationships, and audit fields. """ from datetime import datetime from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text from sqlalchemy.orm import relationship from sqlalchemy.sql import func from core.database import Base class User(Base): """User model for authentication and account management.""" __tablename__ = "users" # Primary key id = Column(Integer, primary_key=True, index=True) # Authentication fields email = Column(String(255), unique=True, index=True, nullable=False) password_hash = Column(String(255), nullable=False) # Profile fields full_name = Column(String(255), nullable=True) company = Column(String(255), nullable=True) # Status fields is_active = Column(Boolean, default=True, nullable=False) is_verified = Column(Boolean, default=False, nullable=False) is_superuser = Column(Boolean, default=False, nullable=False) # Superuser flag for admin access # Verification timestamp verified_at = Column(DateTime(timezone=True), nullable=True) # Audit fields created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) last_login_at = Column(DateTime(timezone=True), nullable=True) # Relationships api_keys = relationship("ApiKey", back_populates="user", cascade="all, delete-orphan") evaluations = relationship("Evaluation", back_populates="user", cascade="all, delete-orphan") roles = relationship("Role", secondary="user_roles", back_populates="users") def __repr__(self): return f"" def has_permission(self, permission_slug: str) -> bool: """Check if user has a specific permission through their roles.""" # Superusers have all permissions if self.is_superuser: return True # Check permissions through roles for role in self.roles: if role.has_permission(permission_slug): return True return False def has_role(self, role_slug: str) -> bool: """Check if user has a specific role.""" return any(role.slug == role_slug for role in self.roles) def get_highest_role_level(self) -> int: """Get highest privilege level from user's roles.""" if not self.roles: return 0 return max(role.level for role in self.roles) def to_dict(self): """Convert user to dictionary (excluding sensitive data).""" return { "id": self.id, "email": self.email, "full_name": self.full_name, "company": self.company, "is_active": self.is_active, "is_verified": self.is_verified, "is_superuser": self.is_superuser, "verified_at": self.verified_at.isoformat() if self.verified_at else None, "roles": [role.to_dict() for role in self.roles] if self.roles else [], "created_at": self.created_at.isoformat() if self.created_at else None, "updated_at": self.updated_at.isoformat() if self.updated_at else None, "last_login_at": self.last_login_at.isoformat() if self.last_login_at else None, }