Files
site_aegisone/max_bot/app/models/models.py
T

351 lines
14 KiB
Python

from datetime import datetime
from sqlalchemy import (
Column, Integer, String, Boolean, Text, DateTime, BigInteger, SmallInteger, JSON, ForeignKey, CheckConstraint, text as sa_text
)
from sqlalchemy.orm import relationship, declarative_base
Base = declarative_base()
class BotUser(Base):
__tablename__ = "bot_users"
id = Column(Integer, primary_key=True, autoincrement=True)
max_user_id = Column(BigInteger, unique=True, nullable=False)
first_name = Column(String(255), default="")
last_name = Column(String(255), default="")
username = Column(String(255), default="")
phone = Column(String(50), default="")
email = Column(String(255), default="")
consent_given = Column(Boolean, nullable=False, default=False)
consent_timestamp = Column(DateTime, nullable=True)
consent_method = Column(String(50), default="")
created_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
last_active_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
conversations = relationship("BotConversation", back_populates="user")
consent_logs = relationship("BotConsentLog", back_populates="user")
notification_subscriptions = relationship("BotNotificationSubscription", back_populates="user", uselist=False)
class BotConversation(Base):
__tablename__ = "bot_conversations"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey("bot_users.id", ondelete="CASCADE"), nullable=False)
status = Column(String(20), nullable=False, default="open")
inquiry_type = Column(Integer, ForeignKey("bot_categories.id", ondelete="SET NULL"), nullable=True)
inquiry_text = Column(Text, default="")
priority = Column(String(20), default="normal")
created_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
closed_at = Column(DateTime, nullable=True)
assigned_to = Column(String(255), default="")
has_attachment = Column(Boolean, default=False)
attachment_type = Column(String(50), default="")
attachment_path = Column(String(500), default="")
__table_args__ = (
CheckConstraint("status IN ('open','closed','handoff','1c_sent','awaiting_rating')", name="ck_bot_conv_status"),
CheckConstraint("priority IN ('low','normal','high','urgent')", name="ck_bot_conv_priority"),
)
user = relationship("BotUser", back_populates="conversations")
category = relationship("BotCategory", back_populates="conversations")
messages = relationship("BotMessage", back_populates="conversation", order_by="BotMessage.timestamp")
sync_log = relationship("Bot1CSyncLog", back_populates="conversation")
class BotMessage(Base):
__tablename__ = "bot_messages"
id = Column(Integer, primary_key=True, autoincrement=True)
conversation_id = Column(Integer, ForeignKey("bot_conversations.id", ondelete="CASCADE"), nullable=False)
direction = Column(String(3), nullable=False)
text = Column(Text, default="")
has_attachment = Column(Boolean, default=False)
attachment_type = Column(String(50), default="")
attachment_path = Column(String(500), default="")
max_message_id = Column(BigInteger, nullable=True)
timestamp = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
__table_args__ = (
CheckConstraint("direction IN ('in','out')", name="ck_bot_msg_direction"),
)
conversation = relationship("BotConversation", back_populates="messages")
class BotConsentLog(Base):
__tablename__ = "bot_consent_logs"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey("bot_users.id", ondelete="CASCADE"), nullable=False)
action = Column(String(20), nullable=False)
timestamp = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
method = Column(String(50), default="")
ip_address = Column(String(45), default="")
__table_args__ = (
CheckConstraint("action IN ('given','revoked')", name="ck_bot_consent_action"),
)
user = relationship("BotUser", back_populates="consent_logs")
class Bot1CSyncLog(Base):
__tablename__ = "bot_1c_sync_log"
id = Column(Integer, primary_key=True, autoincrement=True)
conversation_id = Column(Integer, ForeignKey("bot_conversations.id", ondelete="CASCADE"), nullable=False)
status = Column(String(20), nullable=False, default="pending")
request_payload = Column(Text, default="")
response_payload = Column(Text, default="")
sent_at = Column(DateTime, nullable=True)
confirmed_at = Column(DateTime, nullable=True)
__table_args__ = (
CheckConstraint("status IN ('pending','sent','confirmed','error')", name="ck_bot_1c_status"),
)
conversation = relationship("BotConversation", back_populates="sync_log")
class BotKnowledgeBase(Base):
__tablename__ = "bot_knowledge_base"
id = Column(Integer, primary_key=True, autoincrement=True)
question = Column(String(500), nullable=False)
answer = Column(Text, nullable=False)
category = Column(String(100), default="")
keywords = Column(JSON, default=list)
active = Column(Boolean, nullable=False, default=True)
sort_order = Column(Integer, default=0)
class BotCategory(Base):
__tablename__ = "bot_categories"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(100), nullable=False)
description = Column(String(500), default="")
active = Column(Boolean, nullable=False, default=True)
sort_order = Column(Integer, default=0)
icon_emoji = Column(String(10), default="📋")
keywords = Column(JSON, default=list)
conversations = relationship("BotConversation", back_populates="category")
class BotSetting(Base):
__tablename__ = "bot_settings"
id = Column(Integer, primary_key=True, autoincrement=True)
key = Column(String(100), unique=True, nullable=False)
value = Column(Text, default="")
description = Column(String(500), default="")
class BotFeature(Base):
__tablename__ = "bot_features"
id = Column(Integer, primary_key=True, autoincrement=True)
feature_key = Column(String(100), unique=True, nullable=False)
name = Column(String(100), nullable=False)
description = Column(String(500), default="")
enabled = Column(Boolean, nullable=False, default=False)
sort_order = Column(Integer, default=0)
class BotResponseTemplate(Base):
__tablename__ = "bot_response_templates"
id = Column(Integer, primary_key=True, autoincrement=True)
template_key = Column(String(100), unique=True, nullable=False)
template_text = Column(Text, nullable=False)
description = Column(String(500), default="")
variables = Column(JSON, default=list)
class FileSyncQueue(Base):
__tablename__ = "file_sync_queue"
id = Column(Integer, primary_key=True, autoincrement=True)
local_path = Column(String(500), nullable=False)
remote_path = Column(String(500), default="")
entity_type = Column(String(50), nullable=False)
entity_id = Column(Integer, nullable=False)
status = Column(String(20), nullable=False, default="pending")
error = Column(Text, default="")
created_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
__table_args__ = (
CheckConstraint("status IN ('pending','uploading','synced','error')", name="ck_file_sync_status"),
)
class BotBroadcast(Base):
__tablename__ = "bot_broadcasts"
id = Column(Integer, primary_key=True, autoincrement=True)
text = Column(Text, nullable=False)
sent_at = Column(DateTime, nullable=True)
sent_by = Column(Integer, nullable=True)
recipient_count = Column(Integer, default=0)
recipient_ids = Column(JSON, default=list)
status = Column(String(20), default="draft")
__table_args__ = (
CheckConstraint("status IN ('draft','sent','failed')", name="ck_bot_broadcast_status"),
)
class BotNotification(Base):
__tablename__ = "bot_notifications"
id = Column(Integer, primary_key=True, autoincrement=True)
type = Column(String(50), nullable=False)
recipient_type = Column(String(20), nullable=False)
recipient_max_user_id = Column(BigInteger, nullable=True)
title = Column(String(255), default="")
body = Column(Text, default="")
related_type = Column(String(50), default="")
related_id = Column(Integer, nullable=True)
is_read = Column(Boolean, nullable=False, default=False)
created_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
__table_args__ = (
CheckConstraint("recipient_type IN ('operator','level2','client')", name="ck_bot_notif_recipient"),
)
class BotNotificationSubscription(Base):
__tablename__ = "bot_notification_subscriptions"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey("bot_users.id", ondelete="CASCADE"), nullable=False)
notify_on_status_change = Column(Boolean, nullable=False, default=False)
notify_on_reply = Column(Boolean, nullable=False, default=False)
notify_on_broadcast = Column(Boolean, nullable=False, default=False)
user = relationship("BotUser", back_populates="notification_subscriptions")
class Customer(Base):
__tablename__ = "customers"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(255), nullable=False)
contact_phone = Column(String(50), default="")
class Object(Base):
__tablename__ = "objects"
id = Column(Integer, primary_key=True, autoincrement=True)
customer_id = Column(Integer, ForeignKey("customers.id", ondelete="SET NULL"), nullable=True)
name = Column(String(255), nullable=False)
status = Column(String(20), nullable=False, default="active")
risk_score = Column(Integer, default=0)
class SLAContract(Base):
__tablename__ = "sla_contracts"
id = Column(Integer, primary_key=True, autoincrement=True)
object_id = Column(Integer, ForeignKey("objects.id", ondelete="CASCADE"), nullable=False)
status = Column(String(20), nullable=False, default="negotiation")
created_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
service_level = Column(String(20), default="start")
sla_price_monthly = Column(Integer, default=0)
class Task(Base):
__tablename__ = "tasks"
id = Column(Integer, primary_key=True, autoincrement=True)
object_id = Column(Integer, ForeignKey("objects.id", ondelete="CASCADE"), nullable=False)
status = Column(String(20), nullable=False, default="open")
class Incident(Base):
__tablename__ = "incidents"
id = Column(Integer, primary_key=True, autoincrement=True)
object_id = Column(Integer, ForeignKey("objects.id", ondelete="CASCADE"), nullable=False)
status = Column(String(20), nullable=False, default="open")
created_at = Column(DateTime, nullable=False, server_default="NOW()")
title = Column(String(500), default="")
description = Column(Text, default="")
severity = Column(String(4), nullable=False, default="P3")
reported_by = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, autoincrement=True)
login = Column(String(50), default="")
full_name = Column(String(255), default="")
role = Column(String(20), nullable=False, default="technician")
is_active = Column(Boolean, nullable=False, default=True)
max_user_id = Column(BigInteger, nullable=True)
class BotRiskQuestion(Base):
__tablename__ = "bot_risk_questions"
id = Column(Integer, primary_key=True, autoincrement=True)
question_key = Column(String(100), unique=True, nullable=False)
question = Column(String(500), nullable=False)
weight = Column(Integer, nullable=False, default=10)
sort_order = Column(Integer, default=0)
is_active = Column(Boolean, nullable=False, default=True)
class BotTicket(Base):
__tablename__ = "bot_tickets"
id = Column(Integer, primary_key=True, autoincrement=True)
ticket_number = Column(String(20), unique=True, nullable=False)
user_id = Column(Integer, ForeignKey("bot_users.id", ondelete="SET NULL"), nullable=True)
object_id = Column(Integer, nullable=True)
customer_id = Column(Integer, nullable=True)
title = Column(String(255), nullable=False)
description = Column(Text, default="")
priority = Column(String(20), default="normal")
status = Column(String(20), nullable=False, default="open")
created_by = Column(String(20), default="bot")
sla_contract_id = Column(Integer, nullable=True)
has_attachment = Column(Boolean, default=False)
attachment_type = Column(String(50), default="")
attachment_path = Column(String(500), default="")
created_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
updated_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
__table_args__ = (
CheckConstraint("priority IN ('low','normal','high','urgent')", name="ck_bot_ticket_priority"),
CheckConstraint("status IN ('open','in_progress','resolved','closed')", name="ck_bot_ticket_status"),
)
class BotTicketMessage(Base):
__tablename__ = "bot_ticket_messages"
id = Column(Integer, primary_key=True, autoincrement=True)
ticket_id = Column(Integer, ForeignKey("bot_tickets.id", ondelete="CASCADE"), nullable=False)
direction = Column(String(10), nullable=False)
text = Column(Text, default="")
sender = Column(String(50), default="")
created_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))
class BotTicketStatus(Base):
__tablename__ = "bot_ticket_statuses"
id = Column(Integer, primary_key=True, autoincrement=True)
ticket_id = Column(Integer, ForeignKey("bot_tickets.id", ondelete="CASCADE"), nullable=False)
old_status = Column(String(20), default="")
new_status = Column(String(20), nullable=False)
changed_by = Column(String(50), default="")
created_at = Column(DateTime, nullable=False, server_default=sa_text("CURRENT_TIMESTAMP"))