Files
call-center/services/shared/sql_models.py
T
didar d2438b6954
deploy / deploy (push) Successful in 30s
feat: canonical intent taxonomy for AI operator (kb_answer -> intent_code)
Centralizes fixed control intents and adds a data-driven intent_code
field on kb_articles so many phrasings of the same FAQ question
resolve to one stable code (e.g. VOUCHER_ACTIVATION) instead of a
free-form, unvalidated string the LLM invented on the fly.

- services/shared/intents.py: CONTROL_INTENTS + normalize_intent()
- kb_articles.intent_code column (ORM + dev/sqlite runtime compat +
  migrations/sql/0034_* for postgres/sqlite)
- kb_service CRUD exposes intent_code
- orchestrator surfaces intent_code to the LLM and validates its
  intent output against control intents + the KB codes shown that turn
- voice.py: _voice_early_intent_bucket renamed to _voice_ack_topic_bucket
  to stop it being conflated with the canonical FAQ intent
2026-08-31 00:17:51 +05:00

878 lines
47 KiB
Python

from __future__ import annotations
from sqlalchemy import Boolean, Float, Index, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class AuthUser(Base):
__tablename__ = "auth_users"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
user_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
username: Mapped[str] = mapped_column(String(128), unique=True, index=True)
password: Mapped[str] = mapped_column(String(256))
full_name: Mapped[str] = mapped_column(String(256))
role: Mapped[str] = mapped_column(String(32), index=True)
created_at: Mapped[str] = mapped_column(String(64))
class AuthExternalIdentity(Base):
__tablename__ = "auth_external_identities"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
provider: Mapped[str] = mapped_column(String(64), index=True)
external_subject: Mapped[str] = mapped_column(String(256), index=True)
username: Mapped[str] = mapped_column(String(128), index=True)
email: Mapped[str | None] = mapped_column(String(256), nullable=True, index=True)
full_name: Mapped[str | None] = mapped_column(String(256), nullable=True)
role: Mapped[str] = mapped_column(String(32), index=True)
linked_user_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
last_login_at: Mapped[str] = mapped_column(String(64), index=True)
class AuthOIDCState(Base):
__tablename__ = "auth_oidc_states"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
state: Mapped[str] = mapped_column(String(128), unique=True, index=True)
nonce: Mapped[str] = mapped_column(String(128))
code_verifier: Mapped[str] = mapped_column(String(256))
redirect_uri: Mapped[str] = mapped_column(String(512))
return_mode: Mapped[str] = mapped_column(String(32), default="popup")
created_at: Mapped[str] = mapped_column(String(64), index=True)
expires_at: Mapped[str] = mapped_column(String(64), index=True)
consumed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
class Tenant(Base):
__tablename__ = "tenants"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
tenant_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
name: Mapped[str] = mapped_column(String(256), index=True)
business_type: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
industry: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
country: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
city: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
timezone: Mapped[str] = mapped_column(String(64), default="Asia/Almaty")
language_preferences_json: Mapped[str] = mapped_column(Text, default='["ru"]')
default_currency: Mapped[str] = mapped_column(String(16), default="KZT", index=True)
subscription_plan: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class Customer(Base):
__tablename__ = "customers"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
customer_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
display_name: Mapped[str] = mapped_column(String(256), index=True)
phones_json: Mapped[str] = mapped_column(Text, default="[]")
preferred_phone: Mapped[str | None] = mapped_column(String(64), nullable=True)
tags_json: Mapped[str] = mapped_column(Text, default="[]")
created_at: Mapped[str] = mapped_column(String(64))
class CustomerExternalIdentity(Base):
__tablename__ = "customer_external_identities"
__table_args__ = (
Index(
"ix_customer_external_identities_channel_subject_unique",
"channel",
"external_subject",
unique=True,
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
identity_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
customer_id: Mapped[str] = mapped_column(String(64), index=True)
channel: Mapped[str] = mapped_column(String(32), index=True)
external_subject: Mapped[str] = mapped_column(String(256), index=True)
display_name_snapshot: Mapped[str | None] = mapped_column(String(256), nullable=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class Interaction(Base):
__tablename__ = "interactions"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
interaction_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
channel: Mapped[str] = mapped_column(String(32), index=True)
subject: Mapped[str] = mapped_column(String(512))
customer_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
priority: Mapped[int] = mapped_column(Integer, default=3, index=True)
status: Mapped[str] = mapped_column(String(32), index=True)
assigned_to: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
created_at: Mapped[str] = mapped_column(String(64))
updated_at: Mapped[str] = mapped_column(String(64))
class InteractionTimeline(Base):
__tablename__ = "interaction_timelines"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
interaction_id: Mapped[str] = mapped_column(String(64), index=True)
timestamp: Mapped[str] = mapped_column(String(64), index=True)
action: Mapped[str] = mapped_column(String(128))
metadata_json: Mapped[str] = mapped_column(Text, default="{}")
class Queue(Base):
__tablename__ = "queues"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
queue_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
name: Mapped[str] = mapped_column(String(256), index=True)
description: Mapped[str] = mapped_column(Text, default="")
rules_json: Mapped[str] = mapped_column(Text, default="[]")
created_at: Mapped[str] = mapped_column(String(64))
class VoiceNameCollectionSettingsRow(Base):
__tablename__ = "voice_name_collection_settings"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
settings_key: Mapped[str] = mapped_column(String(64), unique=True, index=True)
config_json: Mapped[str] = mapped_column(Text, default="{}")
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class VoiceTTSSettingsRow(Base):
__tablename__ = "voice_tts_settings"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
settings_key: Mapped[str] = mapped_column(String(64), unique=True, index=True)
config_json: Mapped[str] = mapped_column(Text, default="{}")
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class AIOperatorSettingsRow(Base):
__tablename__ = "ai_operator_settings"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
settings_key: Mapped[str] = mapped_column(String(64), unique=True, index=True)
config_json: Mapped[str] = mapped_column(Text, default="{}")
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class RoutingCounter(Base):
__tablename__ = "routing_counters"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
channel: Mapped[str] = mapped_column(String(32), unique=True, index=True)
counter: Mapped[int] = mapped_column(Integer, default=0)
class AuditEventRow(Base):
__tablename__ = "audit_events"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
event_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
actor: Mapped[str] = mapped_column(String(128), index=True)
action: Mapped[str] = mapped_column(String(128), index=True)
entity: Mapped[str] = mapped_column(String(128), index=True)
metadata_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class EventOutboxRow(Base):
__tablename__ = "event_outbox"
__table_args__ = (
Index("idx_event_outbox_status_available_at_id", "status", "available_at", "id"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
event_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
event_type: Mapped[str] = mapped_column(String(128), index=True)
event_version: Mapped[int] = mapped_column(Integer, default=1)
producer_service: Mapped[str] = mapped_column(String(128), index=True)
entity_type: Mapped[str] = mapped_column(String(128), index=True)
entity_id: Mapped[str] = mapped_column(String(128), index=True)
correlation_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
routing_key: Mapped[str] = mapped_column(String(128), index=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
status: Mapped[str] = mapped_column(String(32), index=True)
attempt_count: Mapped[int] = mapped_column(Integer, default=0)
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
available_at: Mapped[str] = mapped_column(String(64), index=True)
published_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class EventInboxRow(Base):
__tablename__ = "event_inbox"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
consumer_name: Mapped[str] = mapped_column(String(128), index=True)
event_id: Mapped[str] = mapped_column(String(64), index=True)
event_type: Mapped[str] = mapped_column(String(128), index=True)
processed_at: Mapped[str] = mapped_column(String(64), index=True)
status: Mapped[str] = mapped_column(String(32), index=True)
notes: Mapped[str | None] = mapped_column(Text, nullable=True)
class AsteriskEventLogRow(Base):
__tablename__ = "asterisk_event_log"
__table_args__ = (
Index(
"idx_asterisk_event_log_name_call_status_id",
"ami_event_name",
"call_id",
"forward_status",
"id",
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
bridge_event_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
ami_event_name: Mapped[str] = mapped_column(String(128), index=True)
call_id: Mapped[str] = mapped_column(String(128), index=True)
linked_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
recording_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
forward_status: Mapped[str] = mapped_column(String(32), index=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class AsteriskCallLinkRow(Base):
__tablename__ = "asterisk_call_links"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
call_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
linked_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
queue_code: Mapped[str] = mapped_column(String(64), index=True)
queue_id: Mapped[str] = mapped_column(String(64), index=True)
interaction_id: Mapped[str] = mapped_column(String(64), index=True)
caller_number: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
caller_name: Mapped[str | None] = mapped_column(String(128), nullable=True)
status: Mapped[str] = mapped_column(String(32), index=True)
telephony_status: Mapped[str] = mapped_column(String(32), index=True, default="ringing")
claimed_by_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
claimed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
operator_extension: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
channel_name: Mapped[str | None] = mapped_column(String(256), nullable=True, index=True)
voice_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ai_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ai_state: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
ai_handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
ai_last_model_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
voice_start_language: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
customer_name_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
customer_name_value: Mapped[str | None] = mapped_column(String(256), nullable=True)
customer_name_source: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
customer_name_resolved_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
started_at: Mapped[str] = mapped_column(String(64), index=True)
connected_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ended_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
tenant_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
current_level: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
required_skills_json: Mapped[str] = mapped_column(Text, default="[]")
priority: Mapped[int] = mapped_column(Integer, default=3)
class AsteriskCallActionLogRow(Base):
__tablename__ = "asterisk_call_action_log"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
action_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
call_id: Mapped[str] = mapped_column(String(128), index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
action_type: Mapped[str] = mapped_column(String(64), index=True)
actor_user: Mapped[str] = mapped_column(String(128), index=True)
actor_role: Mapped[str] = mapped_column(String(32), index=True)
request_json: Mapped[str] = mapped_column(Text, default="{}")
result_status: Mapped[str] = mapped_column(String(32), index=True)
ami_action_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
error: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
class VoiceEventRow(Base):
__tablename__ = "voice_events"
__table_args__ = (
Index(
"ix_voice_events_source_event_id",
"source_event_id",
unique=True,
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
event_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
event_type: Mapped[str] = mapped_column(String(64), index=True)
call_id: Mapped[str] = mapped_column(String(128), index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
source_event_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class CallRecordingRow(Base):
__tablename__ = "call_recordings"
__table_args__ = (
Index(
"ix_call_recordings_source_event_id",
"source_event_id",
unique=True,
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
recording_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
channel: Mapped[str] = mapped_column(String(32), index=True)
call_id: Mapped[str] = mapped_column(String(128), index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
source_event_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
file_name: Mapped[str] = mapped_column(String(256))
storage_backend: Mapped[str] = mapped_column(String(32), index=True)
storage_path: Mapped[str] = mapped_column(Text)
mime_type: Mapped[str] = mapped_column(String(128))
size_bytes: Mapped[int] = mapped_column(Integer)
duration_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
checksum_sha256: Mapped[str] = mapped_column(String(64), index=True)
status: Mapped[str] = mapped_column(String(32), index=True)
recorded_at: Mapped[str] = mapped_column(String(64), index=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
archived_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
class IvrFlowRow(Base):
__tablename__ = "ivr_flows"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
flow_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
name: Mapped[str] = mapped_column(String(256), index=True)
description: Mapped[str] = mapped_column(Text, default="")
channel: Mapped[str] = mapped_column(String(32), index=True)
queue_id: Mapped[str] = mapped_column(String(64), index=True)
version: Mapped[int] = mapped_column(Integer, default=1)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
entry_node_id: Mapped[str] = mapped_column(String(64))
flow_json: Mapped[str] = mapped_column(Text)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class IvrSessionRow(Base):
__tablename__ = "ivr_sessions"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
session_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
call_id: Mapped[str] = mapped_column(String(128), index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
flow_id: Mapped[str] = mapped_column(String(64), index=True)
queue_id: Mapped[str] = mapped_column(String(64), index=True)
current_node_id: Mapped[str] = mapped_column(String(64))
entered_digits_json: Mapped[str] = mapped_column(Text, default="[]")
status: Mapped[str] = mapped_column(String(32), index=True)
outcome_code: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
resolved_queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
resolved_queue_code: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
completed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class AISessionRow(Base):
__tablename__ = "ai_sessions"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
session_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
channel: Mapped[str] = mapped_column(String(32), index=True)
call_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
thread_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
customer_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
agent_profile: Mapped[str] = mapped_column(String(64), index=True, default="telegram_support")
language: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
status: Mapped[str] = mapped_column(String(32), index=True, default="active")
summary_text: Mapped[str] = mapped_column(Text, default="")
context_summary_json: Mapped[str] = mapped_column(Text, default="{}")
context_summary_updated_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_user_message_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_ai_message_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
closed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
class AIJobRow(Base):
__tablename__ = "ai_jobs"
__table_args__ = (
Index("idx_ai_jobs_thread_status_id", "thread_id", "status", "id"),
Index("idx_ai_jobs_thread_trigger_id", "thread_id", "trigger_message_id", "id"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
job_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
session_id: Mapped[str] = mapped_column(String(64), index=True)
thread_id: Mapped[str] = mapped_column(String(64), index=True)
trigger_message_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
status: Mapped[str] = mapped_column(String(32), index=True, default="pending")
attempts: Mapped[int] = mapped_column(Integer, default=0)
next_attempt_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
locked_until: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class VoiceAISessionRow(Base):
__tablename__ = "voice_ai_sessions"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
session_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
call_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
linked_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
customer_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ai_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
agent_profile: Mapped[str] = mapped_column(String(64), index=True, default="voice_support")
language: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
asr_provider: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
tts_provider: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
status: Mapped[str] = mapped_column(String(32), index=True, default="queued")
handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
handoff_target_queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
voice_start_language: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
customer_name_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
customer_name_value: Mapped[str | None] = mapped_column(String(256), nullable=True)
customer_name_source: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
customer_name_resolved_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
media_uuid: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
media_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
media_connected_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
media_ended_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_media_frame_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
disclosure_played_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_user_utterance_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_ai_reply_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
started_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
ended_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
class AITurnRow(Base):
__tablename__ = "ai_turns"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
turn_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
session_id: Mapped[str] = mapped_column(String(64), index=True)
thread_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
role: Mapped[str] = mapped_column(String(32), index=True)
source_type: Mapped[str] = mapped_column(String(32), index=True)
text: Mapped[str] = mapped_column(Text)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
model: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
finish_reason: Mapped[str | None] = mapped_column(String(64), nullable=True)
latency_ms: Mapped[int | None] = mapped_column(Integer, nullable=True)
created_at: Mapped[str] = mapped_column(String(64), index=True)
class VoiceTranscriptSegmentRow(Base):
__tablename__ = "voice_transcript_segments"
__table_args__ = (
UniqueConstraint(
"session_id",
"sequence_no",
name="uq_voice_transcript_segments_session_sequence",
),
Index(
"idx_voice_transcript_segments_session_speaker_final_id",
"session_id",
"speaker",
"is_final",
"id",
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
segment_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
session_id: Mapped[str] = mapped_column(String(64), index=True)
call_id: Mapped[str] = mapped_column(String(128), index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
speaker: Mapped[str] = mapped_column(String(32), index=True)
source_type: Mapped[str] = mapped_column(String(32), index=True)
sequence_no: Mapped[int] = mapped_column(Integer, index=True)
text: Mapped[str] = mapped_column(Text)
confidence: Mapped[float | None] = mapped_column(Float, nullable=True)
is_final: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
barge_in_interrupted: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class TelegramMessageRow(Base):
__tablename__ = "telegram_messages"
__table_args__ = (
Index(
"ix_telegram_messages_chat_external_unique",
"chat_id",
"telegram_message_id_external",
unique=True,
),
Index(
"idx_telegram_messages_thread_direction_author_created_id",
"thread_id",
"direction",
"author_type",
"created_at",
"id",
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
message_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
thread_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
chat_id: Mapped[str] = mapped_column(String(128), index=True)
text: Mapped[str] = mapped_column(Text)
customer_external_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
direction: Mapped[str] = mapped_column(String(16), index=True, default="inbound")
telegram_message_id_external: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
operator_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
author_type: Mapped[str] = mapped_column(String(32), index=True, default="customer")
author_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
delivery_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
delivery_attempts: Mapped[int] = mapped_column(Integer, default=0)
next_delivery_attempt_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
delivery_locked_until: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_delivery_error: Mapped[str | None] = mapped_column(Text, nullable=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class TelegramThreadRow(Base):
__tablename__ = "telegram_threads"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
thread_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
chat_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
interaction_id: Mapped[str] = mapped_column(String(64), index=True)
telegram_user_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
username: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
display_name: Mapped[str | None] = mapped_column(String(256), nullable=True, index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
status: Mapped[str] = mapped_column(String(32), index=True)
claimed_by_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
claimed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ai_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ai_state: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
ai_handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
ai_last_model_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_message_at: Mapped[str] = mapped_column(String(64), index=True)
last_message_preview: Mapped[str] = mapped_column(Text, default="")
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class WhatsAppMessageRow(Base):
__tablename__ = "whatsapp_messages"
__table_args__ = (
Index(
"ix_whatsapp_messages_chat_external_unique",
"chat_id",
"whatsapp_message_id_external",
unique=True,
),
Index(
"idx_whatsapp_messages_thread_direction_author_created_id",
"thread_id",
"direction",
"author_type",
"created_at",
"id",
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
message_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
thread_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
chat_id: Mapped[str] = mapped_column(String(128), index=True)
text: Mapped[str] = mapped_column(Text)
customer_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
direction: Mapped[str] = mapped_column(String(16), index=True, default="inbound")
whatsapp_message_id_external: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
operator_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
author_type: Mapped[str] = mapped_column(String(32), index=True, default="customer")
author_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
delivery_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
delivery_attempts: Mapped[int] = mapped_column(Integer, default=0)
next_delivery_attempt_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
delivery_locked_until: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_delivery_error: Mapped[str | None] = mapped_column(Text, nullable=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class WhatsAppThreadRow(Base):
__tablename__ = "whatsapp_threads"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
thread_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
chat_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
interaction_id: Mapped[str] = mapped_column(String(64), index=True)
whatsapp_user_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
phone_number: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
display_name: Mapped[str | None] = mapped_column(String(256), nullable=True, index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
is_group: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
status: Mapped[str] = mapped_column(String(32), index=True)
claimed_by_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
claimed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ai_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
ai_state: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
ai_handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
ai_last_model_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
last_message_at: Mapped[str] = mapped_column(String(64), index=True)
last_message_preview: Mapped[str] = mapped_column(Text, default="")
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class WebchatMessageRow(Base):
__tablename__ = "webchat_messages"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
message_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
session_id: Mapped[str] = mapped_column(String(128), index=True)
text: Mapped[str] = mapped_column(Text)
visitor_name: Mapped[str | None] = mapped_column(String(256), nullable=True)
customer_external_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
priority: Mapped[int] = mapped_column(Integer, default=3, index=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class EmailMessageRow(Base):
__tablename__ = "email_messages"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
message_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
from_email: Mapped[str] = mapped_column(String(256), index=True)
subject: Mapped[str] = mapped_column(String(512), index=True)
body: Mapped[str] = mapped_column(Text)
customer_external_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
priority: Mapped[int] = mapped_column(Integer, default=3, index=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class KBCategoryRow(Base):
__tablename__ = "kb_categories"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
category_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
name: Mapped[str] = mapped_column(String(256), index=True)
description: Mapped[str] = mapped_column(Text, default="")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class KBArticleRow(Base):
__tablename__ = "kb_articles"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
article_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
category_id: Mapped[str] = mapped_column(String(64), index=True)
article_group_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
intent_code: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
language: Mapped[str] = mapped_column(String(8), index=True, default="ru")
title: Mapped[str] = mapped_column(String(512), index=True)
body: Mapped[str] = mapped_column(Text)
tags_json: Mapped[str] = mapped_column(Text, default="[]")
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class ReportingEventRow(Base):
__tablename__ = "reporting_events"
__table_args__ = (
Index("idx_reporting_events_queue_channel_created_at", "queue_id", "channel", "created_at"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
queue_id: Mapped[str] = mapped_column(String(64), index=True)
channel: Mapped[str] = mapped_column(String(32), index=True, default="voice")
agent_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
answered: Mapped[bool] = mapped_column(Boolean, default=False)
wait_seconds: Mapped[int] = mapped_column(Integer, default=0)
handle_seconds: Mapped[int] = mapped_column(Integer, default=0)
abandoned: Mapped[bool] = mapped_column(Boolean, default=False)
resolved_first_contact: Mapped[bool] = mapped_column(Boolean, default=False)
created_at: Mapped[str] = mapped_column(String(64), index=True)
class ReportingEventLogRow(Base):
__tablename__ = "reporting_event_log"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
event_id: Mapped[str] = mapped_column(String(64), index=True)
event_type: Mapped[str] = mapped_column(String(128), index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
channel: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
class ReportingInteractionFactRow(Base):
__tablename__ = "reporting_interaction_facts"
__table_args__ = (
UniqueConstraint("interaction_id", name="uq_reporting_interaction_facts_interaction_id"),
Index(
"idx_reporting_interaction_facts_created_queue_channel",
"created_at",
"queue_id",
"channel",
),
Index(
"idx_reporting_interaction_facts_status_agent",
"status",
"agent_id",
),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
interaction_id: Mapped[str] = mapped_column(String(64), index=True)
channel: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
agent_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
created_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
closed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
answered: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
abandoned: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
wait_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
handle_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
resolved_first_contact: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
source: Mapped[str] = mapped_column(String(64), index=True, default="unknown")
class ReportingSavedViewRow(Base):
__tablename__ = "reporting_saved_views"
__table_args__ = (
UniqueConstraint("owner_user", "view_id", name="uq_reporting_saved_views_owner_view"),
Index("idx_reporting_saved_views_owner_updated", "owner_user", "updated_at"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
owner_user: Mapped[str] = mapped_column(String(128), index=True)
owner_role: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
view_id: Mapped[str] = mapped_column(String(64), index=True)
name: Mapped[str] = mapped_column(String(160))
snapshot_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[str] = mapped_column(String(64), index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class SupervisorAgentStateRow(Base):
__tablename__ = "supervisor_agent_states"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
agent_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
state: Mapped[str] = mapped_column(String(32), index=True)
queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class SupervisorQueueSnapshotRow(Base):
__tablename__ = "supervisor_queue_snapshots"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
queue_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
in_queue: Mapped[int] = mapped_column(Integer, default=0)
avg_wait_seconds: Mapped[int] = mapped_column(Integer, default=0)
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class AgentRow(Base):
__tablename__ = "agents"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
agent_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
tenant_ids_json: Mapped[str] = mapped_column(Text, default="[]")
extension: Mapped[str] = mapped_column(String(64), index=True)
endpoint: Mapped[str | None] = mapped_column(String(128), nullable=True)
display_name: Mapped[str] = mapped_column(String(256))
level: Mapped[str] = mapped_column(String(16), index=True)
skills_json: Mapped[str] = mapped_column(Text, default="[]")
status: Mapped[str] = mapped_column(String(32), index=True, default="OFFLINE")
current_call_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
max_concurrent_calls: Mapped[int] = mapped_column(Integer, default=1)
enabled: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
calls_handled_count: Mapped[int] = mapped_column(Integer, default=0)
created_at: Mapped[str] = mapped_column(String(64))
updated_at: Mapped[str] = mapped_column(String(64), index=True)
class EscalationRow(Base):
__tablename__ = "escalations"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
escalation_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
call_id: Mapped[str] = mapped_column(String(128), index=True)
tenant_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
from_level: Mapped[str] = mapped_column(String(16), index=True)
to_level: Mapped[str] = mapped_column(String(16), index=True)
reason_code: Mapped[str] = mapped_column(String(64), index=True)
required_skills_json: Mapped[str] = mapped_column(Text, default="[]")
priority: Mapped[int] = mapped_column(Integer, default=3)
topic: Mapped[str | None] = mapped_column(String(256), nullable=True)
summary: Mapped[str | None] = mapped_column(Text, nullable=True)
status: Mapped[str] = mapped_column(String(32), index=True, default="requested")
assigned_agent_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
real_agent_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
attempted_agent_ids_json: Mapped[str] = mapped_column(Text, default="[]")
attempt_count: Mapped[int] = mapped_column(Integer, default=0)
requested_at: Mapped[str] = mapped_column(String(64), index=True)
connected_at: Mapped[str | None] = mapped_column(String(64), nullable=True)
completed_at: Mapped[str | None] = mapped_column(String(64), nullable=True)
__table_args__ = (
Index(
"idx_escalations_call_id_status",
"call_id",
"status",
),
)
class RoutingRuleRow(Base):
__tablename__ = "routing_rules"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
rule_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
from_level: Mapped[str] = mapped_column(String(16), index=True)
to_level: Mapped[str] = mapped_column(String(16), index=True)
reason_code: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
enabled: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
priority: Mapped[int] = mapped_column(Integer, default=3)
created_at: Mapped[str] = mapped_column(String(64))
updated_at: Mapped[str] = mapped_column(String(64))