Initial commit - production deployment
This commit is contained in:
109
services/pos/app/models/pos_webhook.py
Normal file
109
services/pos/app/models/pos_webhook.py
Normal file
@@ -0,0 +1,109 @@
|
||||
# services/pos/app/models/pos_webhook.py
|
||||
"""
|
||||
POS Webhook Log Model
|
||||
Tracks webhook events from POS systems
|
||||
"""
|
||||
|
||||
from sqlalchemy import Column, String, DateTime, Boolean, Integer, Text, JSON, Index
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.sql import func
|
||||
import uuid
|
||||
|
||||
from shared.database.base import Base
|
||||
|
||||
|
||||
class POSWebhookLog(Base):
|
||||
"""
|
||||
Log of webhook events received from POS systems
|
||||
"""
|
||||
__tablename__ = "pos_webhook_logs"
|
||||
|
||||
# Primary identifiers
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, index=True)
|
||||
tenant_id = Column(UUID(as_uuid=True), nullable=True, index=True) # May be null until parsed
|
||||
|
||||
# POS Provider Information
|
||||
pos_system = Column(String(50), nullable=False, index=True) # square, toast, lightspeed
|
||||
webhook_type = Column(String(100), nullable=False, index=True) # payment.created, order.updated, etc.
|
||||
|
||||
# Request Information
|
||||
method = Column(String(10), nullable=False) # POST, PUT, etc.
|
||||
url_path = Column(String(500), nullable=False)
|
||||
query_params = Column(JSON, nullable=True)
|
||||
headers = Column(JSON, nullable=True)
|
||||
|
||||
# Payload
|
||||
raw_payload = Column(Text, nullable=False) # Raw webhook payload
|
||||
payload_size = Column(Integer, nullable=False, default=0)
|
||||
content_type = Column(String(100), nullable=True)
|
||||
|
||||
# Security
|
||||
signature = Column(String(500), nullable=True) # Webhook signature for verification
|
||||
is_signature_valid = Column(Boolean, nullable=True) # null = not checked, true/false = verified
|
||||
source_ip = Column(String(45), nullable=True) # IPv4 or IPv6
|
||||
|
||||
# Processing Status
|
||||
status = Column(String(50), nullable=False, default="received", index=True) # received, processing, processed, failed
|
||||
processing_started_at = Column(DateTime(timezone=True), nullable=True)
|
||||
processing_completed_at = Column(DateTime(timezone=True), nullable=True)
|
||||
processing_duration_ms = Column(Integer, nullable=True)
|
||||
|
||||
# Error Handling
|
||||
error_message = Column(Text, nullable=True)
|
||||
error_code = Column(String(50), nullable=True)
|
||||
retry_count = Column(Integer, default=0, nullable=False)
|
||||
max_retries = Column(Integer, default=3, nullable=False)
|
||||
|
||||
# Response Information
|
||||
response_status_code = Column(Integer, nullable=True)
|
||||
response_body = Column(Text, nullable=True)
|
||||
response_sent_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# Event Metadata
|
||||
event_id = Column(String(255), nullable=True, index=True) # POS system's event ID
|
||||
event_timestamp = Column(DateTime(timezone=True), nullable=True) # When event occurred in POS
|
||||
sequence_number = Column(Integer, nullable=True) # For ordered events
|
||||
|
||||
# Business Data References
|
||||
transaction_id = Column(String(255), nullable=True, index=True) # Referenced transaction
|
||||
order_id = Column(String(255), nullable=True, index=True) # Referenced order
|
||||
customer_id = Column(String(255), nullable=True) # Referenced customer
|
||||
|
||||
# Internal References
|
||||
created_transaction_id = Column(UUID(as_uuid=True), nullable=True) # Created POSTransaction record
|
||||
updated_transaction_id = Column(UUID(as_uuid=True), nullable=True) # Updated POSTransaction record
|
||||
|
||||
# Duplicate Detection
|
||||
is_duplicate = Column(Boolean, default=False, nullable=False, index=True)
|
||||
duplicate_of = Column(UUID(as_uuid=True), nullable=True)
|
||||
|
||||
# Processing Priority
|
||||
priority = Column(String(20), default="normal", nullable=False) # low, normal, high, urgent
|
||||
|
||||
# Debugging Information
|
||||
user_agent = Column(String(500), nullable=True)
|
||||
forwarded_for = Column(String(200), nullable=True) # X-Forwarded-For header
|
||||
request_id = Column(String(100), nullable=True) # For request tracing
|
||||
|
||||
# Timestamps
|
||||
received_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False, index=True)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
|
||||
|
||||
# Indexes for performance
|
||||
__table_args__ = (
|
||||
Index('idx_webhook_pos_system_type', 'pos_system', 'webhook_type'),
|
||||
Index('idx_webhook_status', 'status'),
|
||||
Index('idx_webhook_event_id', 'event_id'),
|
||||
Index('idx_webhook_received_at', 'received_at'),
|
||||
Index('idx_webhook_tenant_received', 'tenant_id', 'received_at'),
|
||||
Index('idx_webhook_transaction_id', 'transaction_id'),
|
||||
Index('idx_webhook_order_id', 'order_id'),
|
||||
Index('idx_webhook_duplicate', 'is_duplicate'),
|
||||
Index('idx_webhook_priority', 'priority'),
|
||||
Index('idx_webhook_retry', 'retry_count'),
|
||||
Index('idx_webhook_signature_valid', 'is_signature_valid'),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<POSWebhookLog(id={self.id}, pos_system='{self.pos_system}', type='{self.webhook_type}', status='{self.status}')>"
|
||||
Reference in New Issue
Block a user