# ================================================================ # services/notification/app/models/whatsapp_messages.py # ================================================================ """ WhatsApp message tracking models for WhatsApp Business Cloud API """ from sqlalchemy import Column, String, Text, Boolean, DateTime, JSON, Enum, Integer from sqlalchemy.dialects.postgresql import UUID from datetime import datetime import uuid import enum from shared.database.base import Base class WhatsAppMessageStatus(enum.Enum): """WhatsApp message delivery status""" PENDING = "pending" SENT = "sent" DELIVERED = "delivered" READ = "read" FAILED = "failed" class WhatsAppMessageType(enum.Enum): """WhatsApp message types""" TEMPLATE = "template" TEXT = "text" IMAGE = "image" DOCUMENT = "document" INTERACTIVE = "interactive" class WhatsAppMessage(Base): """Track WhatsApp messages sent via Cloud API""" __tablename__ = "whatsapp_messages" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True) notification_id = Column(UUID(as_uuid=True), nullable=True, index=True) # Link to notification if exists # Message identification whatsapp_message_id = Column(String(255), nullable=True, index=True) # WhatsApp's message ID # Recipient details recipient_phone = Column(String(20), nullable=False, index=True) # E.164 format recipient_name = Column(String(255), nullable=True) # Message details message_type = Column(Enum(WhatsAppMessageType), nullable=False) status = Column(Enum(WhatsAppMessageStatus), default=WhatsAppMessageStatus.PENDING, index=True) # Template details (for template messages) template_name = Column(String(255), nullable=True) template_language = Column(String(10), default="es") template_parameters = Column(JSON, nullable=True) # Template variable values # Message content (for non-template messages) message_body = Column(Text, nullable=True) media_url = Column(String(512), nullable=True) # Delivery tracking sent_at = Column(DateTime, nullable=True) delivered_at = Column(DateTime, nullable=True) read_at = Column(DateTime, nullable=True) failed_at = Column(DateTime, nullable=True) # Error tracking error_code = Column(String(50), nullable=True) error_message = Column(Text, nullable=True) # Provider response provider_response = Column(JSON, nullable=True) # Additional data (renamed from metadata to avoid SQLAlchemy reserved word) additional_data = Column(JSON, nullable=True) # Additional context (PO number, order ID, etc.) # Conversation tracking conversation_id = Column(String(255), nullable=True, index=True) # WhatsApp conversation ID conversation_category = Column(String(50), nullable=True) # business_initiated, user_initiated # Timestamps created_at = Column(DateTime, default=datetime.utcnow, index=True) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class WhatsAppTemplate(Base): """Store WhatsApp message templates metadata""" __tablename__ = "whatsapp_templates" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), nullable=True, index=True) # Null for system templates # Template identification template_name = Column(String(255), nullable=False, index=True) # Name in WhatsApp template_key = Column(String(100), nullable=False, unique=True) # Internal key display_name = Column(String(255), nullable=False) description = Column(Text, nullable=True) category = Column(String(50), nullable=False) # MARKETING, UTILITY, AUTHENTICATION # Template configuration language = Column(String(10), default="es") status = Column(String(20), default="PENDING") # PENDING, APPROVED, REJECTED # Template structure header_type = Column(String(20), nullable=True) # TEXT, IMAGE, DOCUMENT, VIDEO header_text = Column(String(60), nullable=True) body_text = Column(Text, nullable=False) footer_text = Column(String(60), nullable=True) # Parameters parameters = Column(JSON, nullable=True) # List of parameter definitions parameter_count = Column(Integer, default=0) # Buttons (for interactive templates) buttons = Column(JSON, nullable=True) # Metadata is_active = Column(Boolean, default=True) is_system = Column(Boolean, default=False) # Usage tracking sent_count = Column(Integer, default=0) last_used_at = Column(DateTime, nullable=True) # WhatsApp metadata whatsapp_template_id = Column(String(255), nullable=True) approved_at = Column(DateTime, nullable=True) rejected_at = Column(DateTime, nullable=True) rejection_reason = Column(Text, nullable=True) # Timestamps created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)