mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-17 23:09:35 +00:00
- API routers, ACA modules, integrations (draft operators) - Docs, landing pages, scripts (launch readiness, scorecard) - Tests and CI workflow updates for Dealix Co-authored-by: Cursor <cursoragent@cursor.com>
75 lines
3.1 KiB
Python
75 lines
3.1 KiB
Python
"""Unified event types and field validation — no transport."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from enum import Enum
|
|
from typing import Any
|
|
|
|
|
|
class EventType(str, Enum):
|
|
"""Stable event type names for platform ingest and internal cards."""
|
|
|
|
LEAD_RECEIVED = "lead_received"
|
|
EXTERNAL_SEND_REQUESTED = "external_send_requested"
|
|
PAYMENT_INTENT = "payment_intent"
|
|
WHATSAPP_MESSAGE_REQUESTED = "whatsapp_message_requested"
|
|
REVIEW_REQUIRED = "review_required"
|
|
DRAFT_CREATED = "draft_created"
|
|
# Omni-channel extensions (dotted names) — backward compatible with existing types.
|
|
EMAIL_RECEIVED = "email.received"
|
|
CALENDAR_MEETING_SCHEDULED = "calendar.meeting_scheduled"
|
|
SOCIAL_COMMENT_RECEIVED = "social.comment_received"
|
|
SOCIAL_DM_RECEIVED = "social.dm_received"
|
|
LEAD_FORM_SUBMITTED = "lead.form_submitted"
|
|
PAYMENT_PAID = "payment.paid"
|
|
PAYMENT_FAILED = "payment.failed"
|
|
REVIEW_CREATED = "review.created"
|
|
PARTNER_SUGGESTED = "partner.suggested"
|
|
ACTION_APPROVED = "action.approved"
|
|
ACTION_BLOCKED = "action.blocked"
|
|
|
|
|
|
_REQUIRED: dict[EventType, tuple[str, ...]] = {
|
|
EventType.LEAD_RECEIVED: ("source", "channel_id"),
|
|
EventType.EXTERNAL_SEND_REQUESTED: ("channel_id", "action"),
|
|
EventType.PAYMENT_INTENT: ("amount_halalas", "currency"),
|
|
EventType.WHATSAPP_MESSAGE_REQUESTED: ("intent", "audience"),
|
|
EventType.REVIEW_REQUIRED: ("reason_code",),
|
|
EventType.DRAFT_CREATED: ("draft_kind",),
|
|
EventType.EMAIL_RECEIVED: ("channel_id", "subject_ar"),
|
|
EventType.CALENDAR_MEETING_SCHEDULED: ("channel_id", "title_ar"),
|
|
EventType.SOCIAL_COMMENT_RECEIVED: ("channel_id", "snippet_ar"),
|
|
EventType.SOCIAL_DM_RECEIVED: ("channel_id", "sender_hint"),
|
|
EventType.LEAD_FORM_SUBMITTED: ("source", "channel_id"),
|
|
EventType.PAYMENT_PAID: ("amount_halalas", "currency"),
|
|
EventType.PAYMENT_FAILED: ("amount_halalas", "reason_code"),
|
|
EventType.REVIEW_CREATED: ("channel_id", "rating"),
|
|
EventType.PARTNER_SUGGESTED: ("partner_name_ar", "sector"),
|
|
EventType.ACTION_APPROVED: ("action_id", "actor"),
|
|
EventType.ACTION_BLOCKED: ("action_id", "reason_code"),
|
|
}
|
|
|
|
|
|
def validate_event(payload: dict[str, Any]) -> dict[str, Any]:
|
|
"""
|
|
Validate ``event_type`` and required keys. Unknown types are rejected
|
|
(forces explicit extension rather than silent typos).
|
|
"""
|
|
errors: list[str] = []
|
|
raw_type = payload.get("event_type")
|
|
if not isinstance(raw_type, str) or not raw_type.strip():
|
|
return {"valid": False, "errors": ["event_type_required"], "normalized": None}
|
|
|
|
try:
|
|
et = EventType(raw_type.strip())
|
|
except ValueError:
|
|
return {"valid": False, "errors": [f"unknown_event_type:{raw_type}"], "normalized": None}
|
|
|
|
for key in _REQUIRED[et]:
|
|
if key not in payload or payload[key] in (None, ""):
|
|
errors.append(f"missing_field:{key}")
|
|
|
|
normalized = {"event_type": et.value, **{k: v for k, v in payload.items() if k != "event_type"}}
|
|
normalized["event_type"] = et.value
|
|
return {"valid": len(errors) == 0, "errors": errors, "normalized": normalized if not errors else None}
|