use std::collections::HashMap;
use async_trait::async_trait;
use modkit_db::secure::DBRunner;
use modkit_macros::domain_model;
use modkit_security::AccessScope;
use uuid::Uuid;
use crate::domain::error::DomainError;
use crate::domain::llm::AttachmentRef;
use crate::infra::db::entity::attachment::Model as AttachmentModel;
#[domain_model]
pub struct InsertAttachmentParams {
pub id: Uuid,
pub tenant_id: Uuid,
pub chat_id: Uuid,
pub uploaded_by_user_id: Uuid,
pub filename: String,
pub content_type: String,
pub size_bytes: i64,
pub storage_backend: String,
pub attachment_kind: String,
pub for_file_search: bool,
pub for_code_interpreter: bool,
}
#[domain_model]
pub struct SetUploadedParams {
pub id: Uuid,
pub provider_file_id: String,
pub size_bytes: i64,
}
#[domain_model]
pub struct SetReadyParams {
pub id: Uuid,
pub img_thumbnail: Option<Vec<u8>>,
pub img_thumbnail_width: Option<i32>,
pub img_thumbnail_height: Option<i32>,
}
#[domain_model]
pub struct SetFailedParams {
pub id: Uuid,
pub error_code: String,
pub from_status: String,
}
#[async_trait]
#[allow(dead_code, clippy::too_many_arguments)]
pub trait AttachmentRepository: Send + Sync {
async fn insert<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
params: InsertAttachmentParams,
) -> Result<AttachmentModel, DomainError>;
async fn cas_set_uploaded<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
params: SetUploadedParams,
) -> Result<u64, DomainError>;
async fn cas_set_ready<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
params: SetReadyParams,
) -> Result<u64, DomainError>;
async fn cas_set_failed<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
params: SetFailedParams,
) -> Result<u64, DomainError>;
async fn get<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
id: Uuid,
) -> Result<Option<AttachmentModel>, DomainError>;
async fn get_batch<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
ids: &[Uuid],
) -> Result<Vec<AttachmentModel>, DomainError>;
async fn soft_delete<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
id: Uuid,
) -> Result<u64, DomainError>;
async fn count_ready_documents<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
chat_id: Uuid,
) -> Result<i64, DomainError>;
async fn count_documents<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
chat_id: Uuid,
) -> Result<i64, DomainError>;
async fn sum_size_bytes<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
chat_id: Uuid,
) -> Result<i64, DomainError>;
async fn build_provider_file_id_map<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
chat_id: Uuid,
) -> Result<HashMap<String, AttachmentRef>, DomainError>;
async fn get_code_interpreter_file_ids<C: DBRunner>(
&self,
runner: &C,
scope: &AccessScope,
chat_id: Uuid,
) -> Result<Vec<String>, DomainError>;
async fn find_pending_cleanup_by_chat<C: DBRunner>(
&self,
runner: &C,
chat_id: Uuid,
) -> Result<Vec<AttachmentModel>, DomainError>;
async fn mark_cleanup_done<C: DBRunner>(
&self,
runner: &C,
attachment_id: Uuid,
) -> Result<u64, DomainError>;
async fn record_cleanup_attempt<C: DBRunner>(
&self,
runner: &C,
attachment_id: Uuid,
error: &str,
max_attempts: u32,
) -> Result<crate::domain::repos::CleanupOutcome, DomainError>;
async fn mark_attachments_pending_for_chat<C: DBRunner>(
&self,
runner: &C,
chat_id: Uuid,
) -> Result<u64, DomainError>;
async fn count_failed_cleanup_by_chat<C: DBRunner>(
&self,
runner: &C,
chat_id: Uuid,
) -> Result<u64, DomainError>;
}