use mini_chat_sdk::UsageEvent;
use modkit_db::secure::DBRunner;
use modkit_macros::domain_model;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use uuid::Uuid;
use crate::domain::error::DomainError;
use crate::domain::model::audit_envelope::AuditEnvelope;
#[domain_model]
#[derive(Debug, Clone, Serialize)]
pub struct AttachmentCleanupEvent {
pub event_type: String,
pub tenant_id: Uuid,
pub chat_id: Uuid,
pub attachment_id: Uuid,
pub provider_file_id: Option<String>,
pub vector_store_id: Option<String>,
pub storage_backend: String,
pub attachment_kind: String,
pub deleted_at: OffsetDateTime,
}
#[domain_model]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum CleanupReason {
ChatSoftDelete,
}
#[domain_model]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CleanupOutcome {
StillPending,
TerminalFailure,
AlreadyTerminal,
}
#[domain_model]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatCleanupEvent {
pub reason: CleanupReason,
pub tenant_id: Uuid,
pub chat_id: Uuid,
pub system_request_id: Uuid,
#[serde(with = "time::serde::rfc3339")]
pub chat_deleted_at: OffsetDateTime,
}
#[domain_model]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThreadSummaryTaskPayload {
pub tenant_id: Uuid,
pub chat_id: Uuid,
pub system_request_id: Uuid,
pub system_task_type: String,
#[serde(default, with = "time::serde::rfc3339::option")]
pub base_frontier_created_at: Option<OffsetDateTime>,
pub base_frontier_message_id: Option<Uuid>,
#[serde(with = "time::serde::rfc3339")]
pub frozen_target_created_at: OffsetDateTime,
pub frozen_target_message_id: Uuid,
}
#[async_trait::async_trait]
pub trait OutboxEnqueuer: Send + Sync {
async fn enqueue_usage_event(
&self,
runner: &(dyn DBRunner + Sync),
event: UsageEvent,
) -> Result<(), DomainError>;
async fn enqueue_attachment_cleanup(
&self,
runner: &(dyn DBRunner + Sync),
event: AttachmentCleanupEvent,
) -> Result<(), DomainError>;
async fn enqueue_chat_cleanup(
&self,
runner: &(dyn DBRunner + Sync),
event: ChatCleanupEvent,
) -> Result<(), DomainError>;
async fn enqueue_audit_event(
&self,
runner: &(dyn DBRunner + Sync),
event: AuditEnvelope,
) -> Result<(), DomainError>;
async fn enqueue_thread_summary(
&self,
runner: &(dyn DBRunner + Sync),
payload: ThreadSummaryTaskPayload,
) -> Result<(), DomainError>;
fn flush(&self);
}