Files
Claude AI de48f0177a fix(api-gateway): corregir errores de SQLAlchemy y dependencias
- 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>
2026-01-29 23:18:28 +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)
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")