| """ |
| 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" |
| |
| |
| id = Column(Integer, primary_key=True, index=True) |
| |
| |
| email = Column(String(255), unique=True, index=True, nullable=False) |
| password_hash = Column(String(255), nullable=False) |
| |
| |
| full_name = Column(String(255), nullable=True) |
| company = Column(String(255), nullable=True) |
| |
| |
| is_active = Column(Boolean, default=True, nullable=False) |
| is_verified = Column(Boolean, default=False, nullable=False) |
| is_superuser = Column(Boolean, default=False, nullable=False) |
| |
| |
| verified_at = Column(DateTime(timezone=True), nullable=True) |
| |
| |
| 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) |
| |
| |
| 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"<User(id={self.id}, email={self.email})>" |
| |
| def has_permission(self, permission_slug: str) -> bool: |
| """Check if user has a specific permission through their roles.""" |
| |
| if self.is_superuser: |
| return True |
| |
| |
| 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, |
| } |
|
|