"""User ORM model and Pydantic schemas.""" from __future__ import annotations from datetime import datetime from typing import TYPE_CHECKING from pydantic import BaseModel, ConfigDict, EmailStr from sqlalchemy import Boolean, DateTime, Integer, String, func from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import Base if TYPE_CHECKING: # pragma: no cover - circular imports only for typing pass class User(Base): """SQLAlchemy model for application users.""" __tablename__ = "users" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) email: Mapped[str] = mapped_column(String(320), unique=True, index=True, nullable=False) hashed_password: Mapped[str] = mapped_column(String(255), nullable=False) name: Mapped[str] = mapped_column(String(255), nullable=False) is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False ) memberships = relationship("OrganizationMember", back_populates="user", cascade="all, delete-orphan") owned_contacts = relationship("Contact", back_populates="owner") owned_deals = relationship("Deal", back_populates="owner") activities = relationship("Activity", back_populates="author") class UserBase(BaseModel): """Shared user fields for Pydantic schemas.""" email: EmailStr name: str is_active: bool = True class UserCreate(UserBase): password: str class UserRead(UserBase): id: int created_at: datetime updated_at: datetime model_config = ConfigDict(from_attributes=True)