""" This model has been updated since iteration 2. The full name attribute has been split into first and surname. I did this in order to render first names on in the GUI in order to make the application more engaging for the user. This demonstrates a user focussed approach to design. """ from enum import Enum from ..db.db_connect import Base from sqlalchemy import ( Column, Integer, UUID, String, Boolean, DateTime, func, Enum as SAEnum, ) # Enumerate user role types class UserRole(str, Enum): ADMIN = "admin" END_USER = "end_user" IT_AGENT = "it_agent" IT_MANAGER = "it_manager" class User(Base): __tablename__ = "users" # ID attribute needs to transition from integer to UUID in future iterations id = Column(Integer, primary_key=True, index=True ) email = Column(String(255), unique=True, nullable=False, index=True ) hashed_password = Column(String(255), nullable=False) #full name attribute change to first and surname first_name = Column(String(255), nullable=True) surname = Column(String(255), nullable=True) role = Column(SAEnum(UserRole, name="user_role"), nullable=False, default=UserRole.END_USER ) is_active = Column(Boolean, nullable=False, default=True ) created_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now() ) updated_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now() ) # merge first and surname into full name property @property def full_name(self) -> str: fn = (self.first_name or "").strip() sn = (self.surname or "").strip() return (f"{fn} {sn}").strip() or None # I split full name into first and surname on set for data migration @full_name.setter def full_name(self, value: str | None) -> None: if not value: self.first_name = None self.surname = None return parts = str(value).strip().split() if not parts: self.first_name = None self.surname = None elif len(parts) == 1: self.first_name = parts[0] self.surname = None else: self.first_name = parts[0] self.surname = " ".join(parts[1:]) def __repr__(self) -> str: return f""