Add models for CRM entities: Activity, Contact, Deal, Organization, OrganizationMember, Task; update User model

This commit is contained in:
k1nq
2025-11-22 14:09:45 +05:00
parent 74330b292f
commit 95a9961549
8 changed files with 375 additions and 4 deletions
+62
View File
@@ -0,0 +1,62 @@
"""Activity timeline ORM model and schemas."""
from __future__ import annotations
from datetime import datetime
from enum import StrEnum
from typing import Any
from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy import DateTime, Enum as SqlEnum, ForeignKey, Integer, func, text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.models.base import Base
class ActivityType(StrEnum):
COMMENT = "comment"
STATUS_CHANGED = "status_changed"
TASK_CREATED = "task_created"
SYSTEM = "system"
class Activity(Base):
"""Represents a timeline event for a deal."""
__tablename__ = "activities"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
deal_id: Mapped[int] = mapped_column(ForeignKey("deals.id", ondelete="CASCADE"))
author_id: Mapped[int | None] = mapped_column(
ForeignKey("users.id", ondelete="SET NULL"), nullable=True
)
type: Mapped[ActivityType] = mapped_column(SqlEnum(ActivityType, name="activity_type"), nullable=False)
payload: Mapped[dict[str, Any]] = mapped_column(
JSONB,
nullable=False,
server_default=text("'{}'::jsonb"),
)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), nullable=False
)
deal = relationship("Deal", back_populates="activities")
author = relationship("User", back_populates="activities")
class ActivityBase(BaseModel):
deal_id: int
author_id: int | None = None
type: ActivityType
payload: dict[str, Any] = Field(default_factory=dict)
class ActivityCreate(ActivityBase):
pass
class ActivityRead(ActivityBase):
id: int
created_at: datetime
model_config = ConfigDict(from_attributes=True)