first commit
This commit is contained in:
commit
efa5080897
127 changed files with 18610 additions and 0 deletions
493
backend/app/models.py
Normal file
493
backend/app/models.py
Normal file
|
|
@ -0,0 +1,493 @@
|
|||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import Boolean, DateTime, ForeignKey, Numeric, String, UniqueConstraint, func
|
||||
from sqlalchemy.dialects.postgresql import JSON, UUID
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from .database import Base
|
||||
|
||||
|
||||
class Organization(Base):
|
||||
__tablename__ = "organizations"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
name: Mapped[str] = mapped_column(String(160), nullable=False)
|
||||
slug: Mapped[str] = mapped_column(String(100), unique=True, index=True)
|
||||
home_region: Mapped[str] = mapped_column(String(32), default="ap-south-1")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
projects: Mapped[list["Project"]] = relationship(back_populates="organization")
|
||||
|
||||
|
||||
class Project(Base):
|
||||
__tablename__ = "projects"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
organization_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("organizations.id"))
|
||||
name: Mapped[str] = mapped_column(String(160), nullable=False)
|
||||
environment: Mapped[str] = mapped_column(String(24), default="test")
|
||||
status: Mapped[str] = mapped_column(String(24), default="active")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
organization: Mapped[Organization] = relationship(back_populates="projects")
|
||||
|
||||
|
||||
class ActivityEvent(Base):
|
||||
__tablename__ = "activity_events"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
project_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("projects.id"), index=True)
|
||||
event_type: Mapped[str] = mapped_column(String(80), index=True)
|
||||
title: Mapped[str] = mapped_column(String(200))
|
||||
detail: Mapped[str] = mapped_column(String(500), default="")
|
||||
status: Mapped[str] = mapped_column(String(24), default="success")
|
||||
occurred_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), index=True)
|
||||
|
||||
|
||||
class UserAccount(Base):
|
||||
"""Canonical person record, independent of any login provider."""
|
||||
|
||||
__tablename__ = "user_accounts"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
email: Mapped[str] = mapped_column(String(320), unique=True, index=True)
|
||||
display_name: Mapped[str] = mapped_column(String(160))
|
||||
avatar_url: Mapped[str | None] = mapped_column(String(1000), nullable=True)
|
||||
email_verified: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
status: Mapped[str] = mapped_column(String(24), default="active")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
password_credential: Mapped["PasswordCredential | None"] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan", uselist=False
|
||||
)
|
||||
oidc_identities: Mapped[list["OidcIdentity"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
kyc_application: Mapped["KycApplication | None"] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan", uselist=False
|
||||
)
|
||||
dlt_application: Mapped["DltApplication | None"] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan", uselist=False
|
||||
)
|
||||
sender_configs: Mapped[list["SenderConfig"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
template_configs: Mapped[list["TemplateConfig"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
api_keys: Mapped[list["ApiKey"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
urmiotp_projects: Mapped[list["UrmiOtpProject"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
campaigns: Mapped[list["Campaign"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
phone_numbers: Mapped[list["PhoneNumber"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
voice_calls: Mapped[list["VoiceCall"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
sms_message_logs: Mapped[list["SmsMessageLog"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
otp_message_logs: Mapped[list["OtpMessageLog"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
voice_socket_endpoints: Mapped[list["VoiceSocketEndpoint"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
sms_delivery_webhooks: Mapped[list["SmsDeliveryWebhook"]] = relationship(
|
||||
back_populates="user", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class PasswordCredential(Base):
|
||||
"""First-party credential kept separate from the canonical user."""
|
||||
|
||||
__tablename__ = "password_credentials"
|
||||
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), primary_key=True
|
||||
)
|
||||
password_hash: Mapped[str] = mapped_column(String(500))
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="password_credential")
|
||||
|
||||
|
||||
class OidcIdentity(Base):
|
||||
"""Provider identity; no provider claims are stored on the user table."""
|
||||
|
||||
__tablename__ = "oidc_identities"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("issuer", "subject", name="uq_oidc_issuer_subject"),
|
||||
UniqueConstraint("user_id", "issuer", name="uq_oidc_user_issuer"),
|
||||
)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
issuer: Mapped[str] = mapped_column(String(500))
|
||||
subject: Mapped[str] = mapped_column(String(500))
|
||||
provider_email: Mapped[str] = mapped_column(String(320))
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
last_login_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
user: Mapped[UserAccount] = relationship(back_populates="oidc_identities")
|
||||
|
||||
|
||||
class KycApplication(Base):
|
||||
__tablename__ = "kyc_applications"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), unique=True, index=True
|
||||
)
|
||||
pan_number: Mapped[str | None] = mapped_column(String(10), nullable=True)
|
||||
gst_number: Mapped[str | None] = mapped_column(String(15), nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(24), default="not_started", index=True)
|
||||
submitted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
approved_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="kyc_application")
|
||||
documents: Mapped[list["KycDocument"]] = relationship(
|
||||
back_populates="application", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class KycDocument(Base):
|
||||
__tablename__ = "kyc_documents"
|
||||
__table_args__ = (UniqueConstraint("application_id", "document_type", name="uq_kyc_app_doc_type"),)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
application_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("kyc_applications.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
document_type: Mapped[str] = mapped_column(String(40))
|
||||
original_filename: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
||||
stored_path: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(24), default="missing")
|
||||
review_note: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
uploaded_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
application: Mapped[KycApplication] = relationship(back_populates="documents")
|
||||
|
||||
|
||||
class DltApplication(Base):
|
||||
__tablename__ = "dlt_applications"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), unique=True, index=True
|
||||
)
|
||||
status: Mapped[str] = mapped_column(String(24), default="not_started", index=True)
|
||||
submitted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
approved_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="dlt_application")
|
||||
documents: Mapped[list["DltDocument"]] = relationship(
|
||||
back_populates="application", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class DltDocument(Base):
|
||||
__tablename__ = "dlt_documents"
|
||||
__table_args__ = (UniqueConstraint("application_id", "document_type", name="uq_dlt_app_doc_type"),)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
application_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("dlt_applications.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
document_type: Mapped[str] = mapped_column(String(40))
|
||||
original_filename: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
||||
stored_path: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(24), default="missing")
|
||||
review_note: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
uploaded_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
application: Mapped[DltApplication] = relationship(back_populates="documents")
|
||||
|
||||
|
||||
class SenderConfig(Base):
|
||||
__tablename__ = "sender_configs"
|
||||
__table_args__ = (UniqueConstraint("user_id", "sender_id", name="uq_sender_user_sender_id"),)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
sender_id: Mapped[str] = mapped_column(String(11), index=True)
|
||||
sender_type: Mapped[str] = mapped_column(String(20))
|
||||
purpose: Mapped[str] = mapped_column(String(500))
|
||||
dlt_entity_id: Mapped[str] = mapped_column(String(50))
|
||||
status: Mapped[str] = mapped_column(String(24), default="pending", index=True)
|
||||
review_note: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="sender_configs")
|
||||
templates: Mapped[list["TemplateConfig"]] = relationship(
|
||||
back_populates="sender_config", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class TemplateConfig(Base):
|
||||
__tablename__ = "template_configs"
|
||||
__table_args__ = (UniqueConstraint("user_id", "template_name", name="uq_template_user_name"),)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
sender_config_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("sender_configs.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
template_name: Mapped[str] = mapped_column(String(40), index=True)
|
||||
template_text: Mapped[str] = mapped_column(String(1000))
|
||||
dlt_template_id: Mapped[str] = mapped_column(String(50))
|
||||
status: Mapped[str] = mapped_column(String(24), default="pending", index=True)
|
||||
review_note: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="template_configs")
|
||||
sender_config: Mapped[SenderConfig] = relationship(back_populates="templates")
|
||||
|
||||
|
||||
class ApiKey(Base):
|
||||
__tablename__ = "api_keys"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
name: Mapped[str] = mapped_column(String(60))
|
||||
key_prefix: Mapped[str] = mapped_column(String(24))
|
||||
key_hash: Mapped[str] = mapped_column(String(500))
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
last_used_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
revoked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="api_keys")
|
||||
|
||||
|
||||
class UrmiOtpProject(Base):
|
||||
__tablename__ = "urmiotp_projects"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
project_name: Mapped[str] = mapped_column(String(30), unique=True, index=True)
|
||||
message_label: Mapped[str] = mapped_column(String(20), server_default="URMI")
|
||||
app_type: Mapped[str] = mapped_column(String(16))
|
||||
app_url: Mapped[str] = mapped_column(String(1000))
|
||||
purpose: Mapped[str] = mapped_column(String(1000))
|
||||
terms_accepted_at: Mapped[datetime] = mapped_column(DateTime(timezone=True))
|
||||
status: Mapped[str] = mapped_column(String(24), default="pending", index=True)
|
||||
review_note: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="urmiotp_projects")
|
||||
|
||||
|
||||
class Campaign(Base):
|
||||
__tablename__ = "campaigns"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
name: Mapped[str] = mapped_column(String(80))
|
||||
sender_config_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("sender_configs.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
template_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("template_configs.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
number_column: Mapped[str] = mapped_column(String(80))
|
||||
variable_columns: Mapped[list] = mapped_column(JSON)
|
||||
run_mode: Mapped[str] = mapped_column(String(20), index=True)
|
||||
scheduled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(24), default="active", index=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="campaigns")
|
||||
sender_config: Mapped["SenderConfig"] = relationship()
|
||||
template: Mapped["TemplateConfig"] = relationship()
|
||||
csv_uploads: Mapped[list["CampaignCsvUpload"]] = relationship(
|
||||
back_populates="campaign", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class CampaignCsvUpload(Base):
|
||||
__tablename__ = "campaign_csv_uploads"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
campaign_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("campaigns.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
original_filename: Mapped[str] = mapped_column(String(255))
|
||||
stored_path: Mapped[str] = mapped_column(String(500))
|
||||
total_rows: Mapped[int] = mapped_column(default=0)
|
||||
status: Mapped[str] = mapped_column(String(24), default="validated", index=True)
|
||||
run_started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
run_completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
campaign: Mapped[Campaign] = relationship(back_populates="csv_uploads")
|
||||
|
||||
|
||||
class PhoneNumber(Base):
|
||||
__tablename__ = "phone_numbers"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
phone_number: Mapped[str] = mapped_column(String(20), unique=True, index=True)
|
||||
user_id: Mapped[uuid.UUID | None] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="SET NULL"), index=True, nullable=True
|
||||
)
|
||||
inbound_price: Mapped[float] = mapped_column(Numeric(10, 4))
|
||||
outbound_price: Mapped[float] = mapped_column(Numeric(10, 4))
|
||||
monthly_number_price: Mapped[float] = mapped_column(Numeric(10, 2), server_default="0")
|
||||
currency: Mapped[str] = mapped_column(String(8), default="INR")
|
||||
status: Mapped[str] = mapped_column(String(20), default="available", index=True)
|
||||
acquisition_type: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
||||
assigned_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
user: Mapped[UserAccount | None] = relationship(back_populates="phone_numbers")
|
||||
voice_calls: Mapped[list["VoiceCall"]] = relationship(back_populates="phone_number")
|
||||
voice_socket_endpoint: Mapped["VoiceSocketEndpoint | None"] = relationship(
|
||||
back_populates="phone_number", cascade="all, delete-orphan", uselist=False
|
||||
)
|
||||
sms_delivery_webhooks: Mapped[list["SmsDeliveryWebhook"]] = relationship(
|
||||
back_populates="phone_number", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class VoiceSocketEndpoint(Base):
|
||||
"""Customer WebSocket destination associated with one owned phone number."""
|
||||
|
||||
__tablename__ = "voice_socket_endpoints"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("phone_number_id", name="uq_voice_socket_phone_number"),
|
||||
UniqueConstraint("user_id", "name", name="uq_voice_socket_user_name"),
|
||||
)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
phone_number_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("phone_numbers.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
name: Mapped[str] = mapped_column(String(120))
|
||||
url: Mapped[str] = mapped_column(String(500))
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="voice_socket_endpoints")
|
||||
phone_number: Mapped[PhoneNumber] = relationship(back_populates="voice_socket_endpoint")
|
||||
|
||||
|
||||
class SmsDeliveryWebhook(Base):
|
||||
"""Named SMS delivery-report destination associated with an owned number."""
|
||||
|
||||
__tablename__ = "sms_delivery_webhooks"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("user_id", "name", name="uq_sms_webhook_user_name"),
|
||||
)
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
phone_number_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("phone_numbers.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
name: Mapped[str] = mapped_column(String(120))
|
||||
url: Mapped[str] = mapped_column(String(500))
|
||||
description: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="sms_delivery_webhooks")
|
||||
phone_number: Mapped[PhoneNumber] = relationship(back_populates="sms_delivery_webhooks")
|
||||
|
||||
|
||||
class VoiceCall(Base):
|
||||
__tablename__ = "voice_calls"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
phone_number_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("phone_numbers.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
direction: Mapped[str] = mapped_column(String(16), index=True)
|
||||
from_did: Mapped[str] = mapped_column(String(20))
|
||||
to_number: Mapped[str] = mapped_column(String(20))
|
||||
status: Mapped[str] = mapped_column(String(24), default="initiated", index=True)
|
||||
provider_event_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
session_token: Mapped[str] = mapped_column(String(64), unique=True, index=True)
|
||||
stream_id: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
||||
call_id: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
||||
bridge_mode: Mapped[str] = mapped_column(String(16), default="console")
|
||||
upstream_ws: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
error_message: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
answered_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
ended_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
user: Mapped[UserAccount] = relationship(back_populates="voice_calls")
|
||||
phone_number: Mapped[PhoneNumber] = relationship(back_populates="voice_calls")
|
||||
|
||||
|
||||
class SmsMessageLog(Base):
|
||||
__tablename__ = "sms_message_logs"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
sender_id: Mapped[str] = mapped_column(String(11), index=True)
|
||||
to_number: Mapped[str] = mapped_column(String(20), index=True)
|
||||
template_name: Mapped[str] = mapped_column(String(40))
|
||||
template_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(24), default="sent", index=True)
|
||||
job_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
message_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
error_message: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), index=True)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="sms_message_logs")
|
||||
|
||||
|
||||
class OtpMessageLog(Base):
|
||||
__tablename__ = "otp_message_logs"
|
||||
|
||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("user_accounts.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
project_name: Mapped[str] = mapped_column(String(30), index=True)
|
||||
template_type: Mapped[str] = mapped_column(String(40), index=True)
|
||||
to_number: Mapped[str] = mapped_column(String(20), index=True)
|
||||
status: Mapped[str] = mapped_column(String(24), default="sent", index=True)
|
||||
job_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
message_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
error_message: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), index=True)
|
||||
user: Mapped[UserAccount] = relationship(back_populates="otp_message_logs")
|
||||
Loading…
Add table
Add a link
Reference in a new issue