codetether_agent/tui/chat/sync/
batch_upload.rs1use std::path::PathBuf;
4
5use anyhow::Result;
6use minio::s3::builders::ObjectContent;
7
8use super::archive_reader::read_chat_archive_batch;
9use super::config_types::ChatSyncConfig;
10use super::minio_client::ensure_minio_bucket;
11
12pub struct ChatSyncBatch {
13 pub bytes: u64,
14 pub records: usize,
15 pub object_key: String,
16 pub next_offset: u64,
17}
18
19pub async fn sync_batch(
20 client: &minio::s3::Client,
21 archive_path: &PathBuf,
22 config: &ChatSyncConfig,
23 host_tag: &str,
24 offset: u64,
25) -> Result<Option<ChatSyncBatch>> {
26 if !archive_path.exists() {
27 return Ok(None);
28 }
29 ensure_minio_bucket(client, &config.bucket).await?;
30 let (payload, next_offset, records) = read_chat_archive_batch(archive_path, offset)?;
31 if payload.is_empty() {
32 return Ok(None);
33 }
34 let ts = chrono::Utc::now().format("%Y%m%dT%H%M%SZ");
35 let pfx = config.prefix.trim_matches('/');
36 let key = if pfx.is_empty() {
37 format!("{host_tag}/{ts}-chat-evts-{offset:020}-{next_offset:020}.jsonl")
38 } else {
39 format!("{pfx}/{host_tag}/{ts}-chat-evts-{offset:020}-{next_offset:020}.jsonl")
40 };
41 let bytes = payload.len() as u64;
42 client
43 .put_object_content(&config.bucket, &key, ObjectContent::from(payload))
44 .send()
45 .await?;
46 Ok(Some(ChatSyncBatch {
47 bytes,
48 records,
49 object_key: key,
50 next_offset,
51 }))
52}