2026-07-16 12:32:17 +07:00
|
|
|
//! Repository traits — pure abstraction boundaries for persistence.
|
|
|
|
|
//!
|
|
|
|
|
//! Each trait defines load / save / query operations that infrastructure
|
|
|
|
|
//! adapters implement. The domain and application layers depend only on
|
|
|
|
|
//! these traits, never on concrete persistence implementations.
|
|
|
|
|
|
|
|
|
|
#![allow(
|
|
|
|
|
clippy::cast_possible_truncation,
|
|
|
|
|
clippy::cast_sign_loss,
|
|
|
|
|
clippy::cast_precision_loss,
|
|
|
|
|
clippy::cast_possible_wrap
|
|
|
|
|
)]
|
|
|
|
|
|
|
|
|
|
use std::path::Path;
|
|
|
|
|
|
|
|
|
|
use anyhow::Result;
|
|
|
|
|
|
|
|
|
|
use super::app_config::AppConfig;
|
|
|
|
|
use super::conversation::Conversation;
|
|
|
|
|
use super::edit_log::{EditLog, EditLogEntry};
|
|
|
|
|
use super::memory::Memory;
|
|
|
|
|
use super::settings::Settings;
|
|
|
|
|
|
|
|
|
|
/// Persistence contract for `Settings`.
|
|
|
|
|
pub trait SettingsRepository {
|
|
|
|
|
/// Load settings from a base directory.
|
|
|
|
|
fn load(&self, base_dir: &Path) -> Result<Settings>;
|
|
|
|
|
|
|
|
|
|
/// Save settings to a base directory.
|
|
|
|
|
fn save(&self, base_dir: &Path, settings: &Settings) -> Result<()>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Persistence contract for `AppConfig`.
|
|
|
|
|
pub trait AppConfigRepository {
|
|
|
|
|
/// Load app config from a base directory.
|
|
|
|
|
fn load(&self, base_dir: &Path) -> Result<AppConfig>;
|
|
|
|
|
|
|
|
|
|
/// Save app config to a base directory.
|
|
|
|
|
fn save(&self, base_dir: &Path, config: &AppConfig) -> Result<()>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Persistence contract for `Conversation`.
|
|
|
|
|
pub trait ConversationRepository {
|
|
|
|
|
/// Load a conversation from a session directory.
|
|
|
|
|
fn load(&self, session_dir: &Path) -> Result<Conversation>;
|
|
|
|
|
|
|
|
|
|
/// Save a conversation to a session directory.
|
|
|
|
|
fn save(&self, session_dir: &Path, conversation: &Conversation) -> Result<()>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Persistence contract for `Memory`.
|
|
|
|
|
pub trait MemoryRepository {
|
|
|
|
|
/// List all memory slugs in a memory directory.
|
|
|
|
|
fn list(&self, memory_dir: &Path) -> Result<Vec<String>>;
|
|
|
|
|
|
|
|
|
|
/// Load a single memory by name.
|
|
|
|
|
fn load(&self, memory_dir: &Path, name: &str) -> Result<Memory>;
|
|
|
|
|
|
|
|
|
|
/// Save (create or update) a memory.
|
|
|
|
|
fn save(&self, memory_dir: &Path, memory: &Memory) -> Result<()>;
|
|
|
|
|
|
|
|
|
|
/// Delete a memory by name.
|
|
|
|
|
fn delete(&self, memory_dir: &Path, name: &str) -> Result<()>;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-17 04:21:18 +07:00
|
|
|
/// Repository for rewind-snapshot binary blobs, keyed by an arbitrary
|
|
|
|
|
/// caller-supplied key (e.g. a tool-call id) within a session.
|
|
|
|
|
pub trait RewindBlobRepository {
|
|
|
|
|
/// Store (or overwrite) a blob under `blob_key` for this session.
|
|
|
|
|
fn store_blob(&self, session_dir: &Path, blob_key: &str, data: &[u8], mime_type: Option<&str>) -> anyhow::Result<()>;
|
|
|
|
|
|
|
|
|
|
/// Retrieve a blob's bytes by key, or `None` if not found.
|
|
|
|
|
fn retrieve_blob(&self, session_dir: &Path, blob_key: &str) -> anyhow::Result<Option<Vec<u8>>>;
|
|
|
|
|
|
|
|
|
|
/// List all blob keys for this session, oldest first.
|
|
|
|
|
fn list_blob_keys(&self, session_dir: &Path) -> anyhow::Result<Vec<String>>;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-16 12:32:17 +07:00
|
|
|
/// Persistence contract for `EditLog`.
|
|
|
|
|
pub trait EditLogRepository {
|
|
|
|
|
/// Open (or start tracking) the edit log for a session directory.
|
|
|
|
|
fn open(&self, session_dir: &Path) -> Result<EditLog>;
|
|
|
|
|
|
|
|
|
|
/// Append one entry, persisting it immediately.
|
|
|
|
|
fn append(&self, session_dir: &Path, log: &mut EditLog, entry: EditLogEntry) -> Result<()>;
|
|
|
|
|
|
|
|
|
|
/// Return a reference to all in-memory entries.
|
|
|
|
|
fn entries(&self, log: &EditLog) -> Vec<EditLogEntry>;
|
|
|
|
|
}
|