refactor: migrate monolithic crate to Cargo Workspace with Clean Architecture
Transform the single binary crate into a 9-crate workspace monorepo: - Root Cargo.toml as [workspace] manager with resolver = "2" - zesdex-entities: Domain entity types (session, settings, store, message, etc.) - zesdex-utils: Pure utility functions (error, logger, pagination, slug, clipboard) - zesdex-dto: Data Transfer Objects for LLM provider API communication - zesdex-ipc: Unix-socket IPC layer (client/server/framing/protocol) - zesdex-iam: Identity & Access Management (Clean Architecture: domain/application/infrastructure) - zesdex-cms: Content Management (Clean Architecture: domain/application/infrastructure) - zesdex-middleware: HTTP middleware (Auth, CORS, Rate Limiting) - zesdex-libs: Composition root (AppContext, DB init, JWT, Argon2) - zesdex-backend: Main binary entry point + seed/migrate binaries - DevOps: Dockerfile, docker-compose, Nix (flake/shell/default), CI/CD updates - Remove dead root src/ and src-misc/ directories All crate re-exports maintain backward compatibility with original crate::model::*, crate::dto::*, crate::ipc::* module paths. Feature crates enforce strict layer separation: domain -> application -> infrastructure with generic trait-based dependency injection.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
//! Shallow state diffing — records opaque "modified" markers so the TUI
|
||||
//! knows to re-render without computing fine-grained deltas.
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A collection of changes tracking which parts of app state have been
|
||||
/// modified since the last render sweep.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct StateDiff {
|
||||
changes: Vec<Change>,
|
||||
}
|
||||
|
||||
/// A single named change — currently always carries a flat `"."` path
|
||||
/// and `"modified"` kind because the system does not track granular diffs.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Change {
|
||||
pub path: String,
|
||||
pub kind: String,
|
||||
}
|
||||
|
||||
impl StateDiff {
|
||||
/// Create an empty diff.
|
||||
pub fn new() -> Self {
|
||||
StateDiff { changes: Vec::new() }
|
||||
}
|
||||
|
||||
/// Record a change at `path` of the given `kind`.
|
||||
pub fn add_change(&mut self, path: String, kind: String) {
|
||||
self.changes.push(Change { path, kind });
|
||||
}
|
||||
|
||||
/// Return true if no changes have been recorded.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.changes.is_empty()
|
||||
}
|
||||
|
||||
/// Remove all recorded changes.
|
||||
pub fn clear(&mut self) {
|
||||
self.changes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute a shallow diff between two serialised state values.
|
||||
///
|
||||
/// Flow: compare with `==`, return an empty vec if equal, otherwise
|
||||
/// return a single `Change { ".", "modified" }`.
|
||||
///
|
||||
/// Why: a placeholder — the current rendering model re-validates the
|
||||
/// whole viewport every frame, so fine-grained diffs are unnecessary.
|
||||
///
|
||||
/// Return: the list of changes (always 0 or 1 entry).
|
||||
pub fn compute_diff(before: &serde_json::Value, after: &serde_json::Value) -> Vec<Change> {
|
||||
if before == after {
|
||||
return Vec::new();
|
||||
}
|
||||
vec![Change {
|
||||
path: ".".to_string(),
|
||||
kind: "modified".to_string(),
|
||||
}]
|
||||
}
|
||||
Reference in New Issue
Block a user