File size: 3,606 Bytes
0e84a1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from datetime import datetime, timezone
from enum import Enum
from typing import Any
from sqlmodel import SQLModel, Field, Column
from sqlalchemy import JSON

def utcnow() -> datetime:
    return datetime.now(timezone.utc)

class PageContext(str, Enum):
    healthcare = "healthcare"
    civic = "civic"

class Channel(str, Enum):
    messenger = "messenger"
    comment = "comment"
    page_post = "page_post"
    reel = "reel"
    lead = "lead"
    unknown = "unknown"

class DraftStatus(str, Enum):
    draft = "draft"
    needs_review = "needs_review"
    approved = "approved"
    rejected = "rejected"
    sent = "sent"
    published = "published"
    scheduled = "scheduled"
    failed = "failed"

class PublishMode(str, Enum):
    now = "now"
    scheduled = "scheduled"
    validation_only = "validation_only"

class RiskLevel(str, Enum):
    low = "low"
    medium = "medium"
    high = "high"
    blocked = "blocked"

class InboundEvent(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    page_context: PageContext = Field(index=True)
    platform_page_id: str = Field(index=True)
    channel: Channel = Field(index=True)
    event_type: str = Field(index=True)
    sender_id_hash: str | None = Field(default=None, index=True)
    object_id: str | None = Field(default=None, index=True)
    parent_id: str | None = Field(default=None, index=True)
    permalink_url: str | None = None
    message_text: str | None = None
    raw_payload: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    normalized_payload: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    forwarded_at: datetime | None = None
    forward_error: str | None = None
    created_at: datetime = Field(default_factory=utcnow, index=True)

class Draft(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    page_context: PageContext = Field(index=True)
    source_event_id: int | None = Field(default=None, foreign_key="inboundevent.id")
    channel: Channel = Field(index=True)
    target_object_id: str | None = Field(default=None, index=True)
    recipient_psid: str | None = Field(default=None, index=True)
    draft_text: str
    sources: list[str] = Field(default_factory=list, sa_column=Column(JSON))
    media_attachments: list[dict[str, Any]] = Field(default_factory=list, sa_column=Column(JSON))
    media_required: bool = Field(default=False, index=True)
    publish_mode: PublishMode = Field(default=PublishMode.now, index=True)
    scheduled_publish_time: datetime | None = Field(default=None, index=True)
    risk_level: RiskLevel = Field(default=RiskLevel.medium, index=True)
    status: DraftStatus = Field(default=DraftStatus.needs_review, index=True)
    created_by: str = "openclaw"
    approved_by: str | None = None
    rejection_reason: str | None = None
    meta_response: dict[str, Any] | None = Field(default=None, sa_column=Column(JSON))
    created_at: datetime = Field(default_factory=utcnow, index=True)
    approved_at: datetime | None = None
    published_at: datetime | None = None

class AuditLog(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    page_context: PageContext | None = Field(default=None, index=True)
    actor: str = Field(index=True)
    action: str = Field(index=True)
    draft_id: int | None = Field(default=None, index=True)
    event_id: int | None = Field(default=None, index=True)
    details: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
    created_at: datetime = Field(default_factory=utcnow, index=True)