from __future__ import annotations import uuid from typing import TYPE_CHECKING from sqlalchemy import JSON, Enum, ForeignKey, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from app.db.base import Base, TimestampMixin, UUIDPrimaryKeyMixin from app.models.enums import CompanyStatus if TYPE_CHECKING: from app.models.company_enrichment import CompanyEnrichment from app.models.monitor_configuration import MonitorConfiguration from app.models.notification_destination import NotificationDestinationCompany class Company(Base, UUIDPrimaryKeyMixin, TimestampMixin): __tablename__ = "companies" user_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), index=True ) name: Mapped[str] = mapped_column(String(200)) slug: Mapped[str] = mapped_column(String(220), index=True) official_website: Mapped[str | None] = mapped_column(String(500), nullable=True) description: Mapped[str | None] = mapped_column(Text, nullable=True) monitoring_focus: Mapped[str | None] = mapped_column(Text, nullable=True) industry: Mapped[str | None] = mapped_column(String(120), nullable=True) country: Mapped[str | None] = mapped_column(String(120), nullable=True) region: Mapped[str | None] = mapped_column(String(120), nullable=True) headquarters: Mapped[str | None] = mapped_column(String(200), nullable=True) # Best-effort discovered identifiers, e.g. {"ticker": "ACME", "linkedin_url": "..."} # - see app/prompts/company_profile.py. Empty dict, never fabricated. public_identifiers: Mapped[dict[str, str]] = mapped_column(JSON, default=dict) status: Mapped[CompanyStatus] = mapped_column( Enum(CompanyStatus, native_enum=False, length=20), default=CompanyStatus.ACTIVE ) aliases: Mapped[list[CompanyAlias]] = relationship( back_populates="company", cascade="all, delete-orphan" ) competitors: Mapped[list[Competitor]] = relationship( back_populates="company", cascade="all, delete-orphan" ) monitor_configuration: Mapped[MonitorConfiguration | None] = relationship( back_populates="company", cascade="all, delete-orphan", uselist=False ) enrichment: Mapped[CompanyEnrichment | None] = relationship( back_populates="company", cascade="all, delete-orphan", uselist=False ) notification_links: Mapped[list[NotificationDestinationCompany]] = relationship( cascade="all, delete-orphan" ) class CompanyAlias(Base, UUIDPrimaryKeyMixin, TimestampMixin): __tablename__ = "company_aliases" company_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("companies.id", ondelete="CASCADE"), index=True ) alias: Mapped[str] = mapped_column(String(200)) company: Mapped[Company] = relationship(back_populates="aliases") class Competitor(Base, UUIDPrimaryKeyMixin, TimestampMixin): __tablename__ = "competitors" company_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("companies.id", ondelete="CASCADE"), index=True ) name: Mapped[str] = mapped_column(String(200)) company: Mapped[Company] = relationship(back_populates="competitors")