- Renombrar campo 'metadata' a 'extra_data' (palabra reservada SQLAlchemy) - Agregar email-validator para pydantic[email] Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
120 lines
4.5 KiB
Python
120 lines
4.5 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
from sqlalchemy import Column, String, Boolean, DateTime, Text, Integer, ForeignKey, Enum as SQLEnum
|
|
from sqlalchemy.dialects.postgresql import UUID, JSONB, ARRAY
|
|
from sqlalchemy.orm import relationship
|
|
import enum
|
|
from app.core.database import Base
|
|
|
|
|
|
class AccountStatus(str, enum.Enum):
|
|
CONNECTING = "connecting"
|
|
CONNECTED = "connected"
|
|
DISCONNECTED = "disconnected"
|
|
|
|
|
|
class ConversationStatus(str, enum.Enum):
|
|
BOT = "bot"
|
|
WAITING = "waiting"
|
|
ACTIVE = "active"
|
|
RESOLVED = "resolved"
|
|
|
|
|
|
class MessageDirection(str, enum.Enum):
|
|
INBOUND = "inbound"
|
|
OUTBOUND = "outbound"
|
|
|
|
|
|
class MessageType(str, enum.Enum):
|
|
TEXT = "text"
|
|
IMAGE = "image"
|
|
AUDIO = "audio"
|
|
VIDEO = "video"
|
|
DOCUMENT = "document"
|
|
LOCATION = "location"
|
|
CONTACT = "contact"
|
|
STICKER = "sticker"
|
|
BUTTONS = "buttons"
|
|
LIST = "list"
|
|
|
|
|
|
class MessageStatus(str, enum.Enum):
|
|
PENDING = "pending"
|
|
SENT = "sent"
|
|
DELIVERED = "delivered"
|
|
READ = "read"
|
|
FAILED = "failed"
|
|
|
|
|
|
class WhatsAppAccount(Base):
|
|
__tablename__ = "whatsapp_accounts"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
phone_number = Column(String(20), nullable=True)
|
|
name = Column(String(100), nullable=False)
|
|
status = Column(SQLEnum(AccountStatus), default=AccountStatus.DISCONNECTED, nullable=False)
|
|
session_data = Column(JSONB, nullable=True)
|
|
qr_code = Column(Text, nullable=True)
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
|
|
|
conversations = relationship("Conversation", back_populates="whatsapp_account")
|
|
|
|
|
|
class Contact(Base):
|
|
__tablename__ = "contacts"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
phone_number = Column(String(20), unique=True, nullable=False, index=True)
|
|
name = Column(String(100), nullable=True)
|
|
email = Column(String(255), nullable=True)
|
|
company = Column(String(100), nullable=True)
|
|
extra_data = Column(JSONB, default=dict)
|
|
tags = Column(ARRAY(String), default=list)
|
|
odoo_partner_id = Column(Integer, nullable=True)
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
|
|
|
conversations = relationship("Conversation", back_populates="contact")
|
|
|
|
|
|
class Conversation(Base):
|
|
__tablename__ = "conversations"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
whatsapp_account_id = Column(UUID(as_uuid=True), ForeignKey("whatsapp_accounts.id"), nullable=False)
|
|
contact_id = Column(UUID(as_uuid=True), ForeignKey("contacts.id"), nullable=False)
|
|
assigned_to = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
|
|
status = Column(SQLEnum(ConversationStatus), default=ConversationStatus.BOT, nullable=False)
|
|
last_message_at = Column(DateTime, nullable=True)
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
|
queue_id = Column(UUID(as_uuid=True), ForeignKey("queues.id"), nullable=True)
|
|
priority = Column(String(20), default="normal", nullable=False)
|
|
sla_first_response_at = Column(DateTime, nullable=True)
|
|
sla_first_response_met = Column(Boolean, nullable=True)
|
|
resolved_at = Column(DateTime, nullable=True)
|
|
csat_score = Column(Integer, nullable=True)
|
|
csat_feedback = Column(String(500), nullable=True)
|
|
|
|
whatsapp_account = relationship("WhatsAppAccount", back_populates="conversations")
|
|
contact = relationship("Contact", back_populates="conversations")
|
|
messages = relationship("Message", back_populates="conversation", order_by="Message.created_at")
|
|
queue = relationship("Queue", back_populates="conversations")
|
|
|
|
|
|
class Message(Base):
|
|
__tablename__ = "messages"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
conversation_id = Column(UUID(as_uuid=True), ForeignKey("conversations.id"), nullable=False)
|
|
whatsapp_message_id = Column(String(100), nullable=True)
|
|
direction = Column(SQLEnum(MessageDirection), nullable=False)
|
|
type = Column(SQLEnum(MessageType), default=MessageType.TEXT, nullable=False)
|
|
content = Column(Text, nullable=True)
|
|
media_url = Column(String(500), nullable=True)
|
|
extra_data = Column(JSONB, default=dict)
|
|
sent_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
|
|
is_internal_note = Column(Boolean, default=False, nullable=False)
|
|
status = Column(SQLEnum(MessageStatus), default=MessageStatus.PENDING, nullable=False)
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
|
|
|
conversation = relationship("Conversation", back_populates="messages")
|