Files
WhatsAppCentralizado/services/api-gateway/app/models/whatsapp.py
2026-01-29 10:54:13 +00:00

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)
metadata = 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)
metadata = 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")