"""Contact and CompanyContact (N:M join) models.""" from __future__ import annotations import uuid from sqlalchemy import ( Boolean, ForeignKey, Index, String, Text, UniqueConstraint, ) from sqlalchemy.dialects.postgresql import UUID as PGUUID from sqlalchemy.orm import Mapped, mapped_column from app.core.db import Base, TenantMixin class Contact(Base, TenantMixin): """Contact person entity — can be linked to multiple companies via CompanyContact.""" __tablename__ = "contacts" __table_args__ = ( Index("ix_contacts_tenant_deleted", "tenant_id", "deleted_at"), Index("ix_contacts_tenant_name", "tenant_id", "last_name", "first_name"), Index("ix_contacts_email", "email"), ) id: Mapped[uuid.UUID] = mapped_column( PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) first_name: Mapped[str] = mapped_column(String(100), nullable=False) last_name: Mapped[str] = mapped_column(String(100), nullable=False) email: Mapped[str | None] = mapped_column(String(255), nullable=True) phone: Mapped[str | None] = mapped_column(String(30), nullable=True) mobile: Mapped[str | None] = mapped_column(String(30), nullable=True) position: Mapped[str | None] = mapped_column(String(100), nullable=True) department: Mapped[str | None] = mapped_column(String(100), nullable=True) linkedin_url: Mapped[str | None] = mapped_column(String(500), nullable=True) notes: Mapped[str | None] = mapped_column(Text, nullable=True) created_by: Mapped[uuid.UUID | None] = mapped_column( PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True ) updated_by: Mapped[uuid.UUID | None] = mapped_column( PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True ) class CompanyContact(Base, TenantMixin): """N:M join table between Company and Contact.""" __tablename__ = "company_contacts" __table_args__ = ( UniqueConstraint("company_id", "contact_id", "tenant_id", name="uq_company_contact_tenant"), Index("ix_cc_company", "company_id"), Index("ix_cc_contact", "contact_id"), ) id: Mapped[uuid.UUID] = mapped_column( PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) company_id: Mapped[uuid.UUID] = mapped_column( PGUUID(as_uuid=True), ForeignKey("companies.id", ondelete="CASCADE"), nullable=False ) contact_id: Mapped[uuid.UUID] = mapped_column( PGUUID(as_uuid=True), ForeignKey("contacts.id", ondelete="CASCADE"), nullable=False ) role_at_company: Mapped[str | None] = mapped_column(String(100), nullable=True) is_primary: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)