Database Models
Notification
The main notification model representing a request for merchant admin input.
class Notification(Base):
__tablename__ = "notifications"
id: Mapped[int]
notification_type: Mapped[str] # NotificationType enum value
status: Mapped[str] # NotificationStatus enum value
created_at: Mapped[datetime]
updated_at: Mapped[datetime]
conversation_id: Mapped[int] # FK to conversations
context: Mapped[Dict] # JSON field with notification details
answer_model_json_schema: Mapped[Dict] # JSON schema for answer validation
answer: Mapped[Dict] # Deprecated - answers stored in context instead
Relationships:
- conversation: Many-to-one with Conversation
Field Details:
notification_type
Stored as string (enum value). Must be one of:
- "user_question_request": Customer question notification
- "user_support_request": Customer support ticket
- "driver_order_request": Driver delivery request (future use)
status
Current notification state:
- "requested": Sent to merchant admins, awaiting response
- "answered": Merchant admin has responded
context
JSON field containing notification-specific data. Common fields:
- allow_multiple_answers: bool - Whether notification can be answered multiple times
- notification_id: int - Self-reference for propagation to messages
- notification_id_prefixed: str - Prefixed ID (e.g., "NOTIF_123")
- merchant_user_conversation_user_ids: List[int] - Recipients for closure notifications
- lead_phone: str - Customer phone number
Type-Specific Context Fields:
user_question_request:
- question: str - Customer's question text
- document_id: int - Associated Document ID for Q&A storage
user_support_request:
- support_request_reason: str - Why customer needs support
- support_request_type: str - AI-classified type (Sales, Returns, Billing, etc.)
answer_model_json_schema
JSON schema defining expected answer structure. Generated from Pydantic models:
- UserQuestionAnswerSchema for questions
- UserSupportRequestAnswerSchema for support tickets
Used by AnswerNotificationTool to validate admin responses.
answer
Deprecated field. Answer data now stored in context instead to avoid redundancy.
Enums
NotificationType
class NotificationType(str, Enum):
user_question_request = "user_question_request"
user_support_request = "user_support_request"
driver_order_request = "driver_order_request" # Future use
Values:
user_question_request
Customer asked a question that Cosmo cannot answer from existing knowledge.
Trigger: RequestNotificationTool when knowledge base search fails
Target: Merchant admins
Expected Answer: Plain text answer to the question
user_support_request
Customer requested live agent support or escalated an issue.
Trigger: Customer explicitly requests agent or support flow determines escalation needed
Target: Merchant admins (classified by type: sales, support, returns, etc.)
Expected Answer: Response to customer + optional internal resolution notes
driver_order_request
Request for driver to accept delivery.
Status: Defined but not yet implemented
Future Use: Local delivery notifications
NotificationStatus
class NotificationStatus(str, Enum):
requested = "requested"
answered = "answered"
Values:
requested
Notification sent to merchant admins, awaiting response.
State: Initial state when notification created
Transitions to: answered when admin responds
answered
Merchant admin has responded to the notification.
State: Final state (currently no further transitions)
Behavior:
- If allow_multiple_answers=False, prevents additional answers
- Triggers closure notifications to other admins
Configuration Constants
NOTIFICATION_CONFIG
Defined in service.py, this dictionary maps each notification type to its configuration:
NOTIFICATION_CONFIG = {
NotificationType.<type>: {
"requested_fields": List[str],
"requested_campaign": CommerceDefaultCampaigns,
"requested_to": "merchant_user" | "conversation_user",
"answered_fields": List[str],
"answered_campaign": CommerceDefaultCampaigns,
"answered_to": "merchant_user" | "conversation_user",
"answer_schema": BaseModel,
"allow_multiple_answers": bool,
}
}
Field Descriptions:
requested_fields: Required fields in context when creating notificationrequested_campaign: Campaign template to send to recipients when requestingrequested_to: Whether to send request to merchant_user or conversation_useranswered_fields: Required fields in answer contextanswered_campaign: Campaign template to send when answering (>24h only)answered_to: Whether to send answer to merchant_user or conversation_useranswer_schema: Pydantic model for answer validationallow_multiple_answers: Whether notification can be answered multiple times
Related Models
Document (for user_question_request)
Questions create documents in the knowledge base:
document = Document(
merchant_id=merchant_id,
title=question, # Question text
content=answer, # Populated when answered
category=DocumentCategory.UserQuestion,
source_type=DocumentSource.FreeInput,
source="conversation_user"
)
See Document Models for details.
ConversationUser (for merchant routing)
Merchant admin phone numbers are converted to ConversationUser records to enable campaign delivery:
conversation_user = ConversationUser(
phone_number=merchant_user.phone_number
)
Created automatically if doesn't exist. See User Models for details.
Database Schema Notes
Indexes
conversation_id: Indexed for fast lookup by conversation- Primary key
id: Used withNOTIFICATION_PREFIXfor external references
Relationships
Conversation.notifications: One-to-many relationship- Cascading delete: Notifications deleted when conversation deleted
JSON Fields
Both context and answer_model_json_schema use PostgreSQL JSON type:
- Queryable via JSON operators (context['field'].astext)
- No schema enforcement at database level (handled by Pydantic)
- Default value {} for context
Timestamp Behavior
created_at: Set once at creation (default:datetime.utcnow)updated_at: Auto-updated on every modification (onupdate=datetime.utcnow)- Both are timezone-aware (
DateTime(timezone=True))
Migration Notes
The notification schema was added via Alembic migration a2e7d947fc09_add_notification_schema.py.
Key Changes:
- Added notifications table
- Added answer_model_json_schema field for dynamic validation
- Deprecated answer field in favor of storing answers in context