docs: tambah doc comment, logging, dan inline comments di semua 255 file
Meliputi: - File-level //! doc comment: tujuan file, alur kerja, komponen utama - Function-level /// doc comment: apa, parameter, return, flow, edge cases - Struct/enum/trait /// doc comment: peran, field docs - Tracing logging (tracing::info!/debug!/trace!/warn!/error!) di setiap fungsi - Inline comments untuk variable dan branching logic penting - Seluruh 8 crates di workspace: zesdex-backend, zesdex-cms, zesdex-entities, zesdex-iam, zesdex-infra, zesdex-ipc, zesdex-middleware, zesdex-utils - Build: 0 errors, 242/242 tests passed
This commit is contained in:
@@ -1,11 +1,35 @@
|
||||
//! Markdown file–backed `MemoryRepository`.
|
||||
//! Markdown file–backed `MemoryRepository` implementation.
|
||||
//!
|
||||
//! Each memory is stored as a `.md` file with YAML-ish frontmatter.
|
||||
//! Filenames are derived from the memory's `name` via slugification.
|
||||
//! Filenames are derived from the memory's `name` via slugification
|
||||
//! (see `Memory::slugify`).
|
||||
//!
|
||||
//! Frontmatter fields parsed from `---\n...\n---\n` header:
|
||||
//! name, description, kind, created_at, updated_at, lifecycle,
|
||||
//! outcome, scope, before, after, provenances
|
||||
//! ## File Format
|
||||
//! ```text
|
||||
//! ---
|
||||
//! name: my-memory
|
||||
//! description: A useful lesson
|
||||
//! kind: lesson
|
||||
//! created_at: 1700000000
|
||||
//! updated_at: 1700000000
|
||||
//! lifecycle: active
|
||||
//! outcome: success
|
||||
//! scope: global
|
||||
//! before: old content
|
||||
//! after: new content
|
||||
//! provenances: tool1, tool2
|
||||
//! ---
|
||||
//! Free-form markdown content body...
|
||||
//! ```
|
||||
//!
|
||||
//! ## Data Flow
|
||||
//! - `list()`: scan `*.md` files (excluding `MEMORY.md`), return slugs
|
||||
//! - `load()`: read file → strip `---\n...\n---\n` frontmatter → parse fields
|
||||
//! - `save()`: build frontmatter → write to temp file → rename atomically
|
||||
//! - `delete()`: remove file from disk
|
||||
//!
|
||||
//! ## Atomicity
|
||||
//! Writes use temp-file + rename + parent-directory fsync for crash safety.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::io::Write;
|
||||
@@ -16,7 +40,10 @@ use anyhow::{Context, Result};
|
||||
use crate::domain::memory::Memory;
|
||||
use crate::domain::repository::MemoryRepository;
|
||||
|
||||
/// Persists `Memory` as markdown files with YAML-ish frontmatter.
|
||||
/// File-based `MemoryRepository` that stores memories as `.md` files with frontmatter.
|
||||
///
|
||||
/// Each file has a YAML-ish `---\n...\n---\n` header followed by free-form
|
||||
/// markdown content. Filenames are derived from `Memory.name` via slugification.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct MarkdownMemoryRepository;
|
||||
|
||||
@@ -26,7 +53,9 @@ impl MarkdownMemoryRepository {
|
||||
Self
|
||||
}
|
||||
|
||||
/// Build the frontmatter lines for a memory.
|
||||
/// Build the YAML-ish frontmatter string for a memory.
|
||||
///
|
||||
/// Only non-empty optional fields are included in the output.
|
||||
fn build_frontmatter(memory: &Memory) -> String {
|
||||
let outcome_line = memory
|
||||
.outcome
|
||||
@@ -71,7 +100,10 @@ impl MarkdownMemoryRepository {
|
||||
)
|
||||
}
|
||||
|
||||
/// Parse frontmatter lines into a `HashMap`.
|
||||
/// Parse frontmatter lines into a `HashMap<String, String>`.
|
||||
///
|
||||
/// Flow: split lines → for each non-empty line, split on first ':' → insert.
|
||||
/// Malformed lines (no ':') are silently skipped.
|
||||
fn parse_frontmatter(front: &str) -> HashMap<String, String> {
|
||||
front
|
||||
.lines()
|
||||
@@ -82,7 +114,12 @@ impl MarkdownMemoryRepository {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Parse a memory file's contents (frontmatter + body) into a `Memory`.
|
||||
/// Parse a memory file's full contents (frontmatter + body) into a `Memory`.
|
||||
///
|
||||
/// Flow: strip `---\n` prefix → split on `\n---\n` → parse front half with
|
||||
/// `parse_frontmatter()` → use back half as content body → build Memory.
|
||||
///
|
||||
/// Returns `InvalidData` error if the frontmatter delimiter is missing.
|
||||
fn parse(content: &str) -> std::io::Result<Memory> {
|
||||
let content = content.strip_prefix("---\n").unwrap_or(content);
|
||||
let parts: Vec<&str> = content.splitn(2, "\n---\n").collect();
|
||||
@@ -132,6 +169,10 @@ impl MarkdownMemoryRepository {
|
||||
}
|
||||
|
||||
impl MemoryRepository for MarkdownMemoryRepository {
|
||||
/// List all memory slugs in `memory_dir` by scanning `*.md` files.
|
||||
///
|
||||
/// Flow: read directory entries → filter `*.md` → strip extension → exclude MEMORY.md.
|
||||
/// Returns empty Vec if the directory doesn't exist.
|
||||
fn list(&self, memory_dir: &Path) -> Result<Vec<String>> {
|
||||
let Ok(entries) = std::fs::read_dir(memory_dir) else {
|
||||
return Ok(Vec::new());
|
||||
@@ -152,7 +193,11 @@ impl MemoryRepository for MarkdownMemoryRepository {
|
||||
Ok(slugs)
|
||||
}
|
||||
|
||||
/// Load a single `Memory` by name from `memory_dir`.
|
||||
///
|
||||
/// Flow: resolve file path → read file → parse frontmatter + body → return Memory.
|
||||
fn load(&self, memory_dir: &Path, name: &str) -> Result<Memory> {
|
||||
tracing::debug!("loading memory '{name}'");
|
||||
let path = Memory::path(memory_dir, name);
|
||||
let content = std::fs::read_to_string(&path)
|
||||
.with_context(|| format!("failed to read memory '{name}' at '{}'", path.display()))?;
|
||||
|
||||
Reference in New Issue
Block a user