diff --git a/hive-c0re/src/loose_ends.rs b/hive-c0re/src/loose_ends.rs index 78e8689d..b4803b37 100644 --- a/hive-c0re/src/loose_ends.rs +++ b/hive-c0re/src/loose_ends.rs @@ -106,6 +106,10 @@ pub fn for_agent(coord: &Coordinator, agent: &str) -> Result> { /// This agent's dynamic todos as `LooseEnd::Todo` rows, optionally /// filtered to one `subsystem`. Shared by [`for_agent`] and the /// `ListTodos` handler so the row-mapping lives in one place. +/// +/// # Errors +/// +/// Propagates the todo-store query failure. pub fn todos_for( coord: &Coordinator, agent: &str, diff --git a/hive-c0re/src/stores/todos.rs b/hive-c0re/src/stores/todos.rs index e8038451..8effdd65 100644 --- a/hive-c0re/src/stores/todos.rs +++ b/hive-c0re/src/stores/todos.rs @@ -79,6 +79,11 @@ pub struct Todos { } impl Todos { + /// Open (creating if needed) the todo store at `path`. + /// + /// # Errors + /// + /// Propagates sqlite open / schema-apply / migration failures. pub fn open(path: &Path) -> Result { let conn = crate::db::open(path, "todos")?; conn.execute_batch(SCHEMA).context("apply todos schema")?; @@ -97,6 +102,14 @@ impl Todos { /// new OR its `summary`/`source` actually differed — the caller uses /// this to decide whether to coalesce a wake (re-pushing an identical /// keyed todo is a no-op and must not re-wake). + /// + /// # Errors + /// + /// Propagates sqlite query / execute failures. + /// + /// # Panics + /// + /// Panics if the connection mutex is poisoned. pub fn upsert( &self, agent: &str, @@ -138,8 +151,20 @@ impl Todos { Ok((conn.last_insert_rowid(), true)) } - /// Clear a producer-resolved todo, keyed by `(agent, subsystem, key)`. - /// Returns the number of rows deleted (0 when nothing matched). + /// Clear producer-resolved todo(s) by `(agent, subsystem, key)`. + /// `key = Some(k)` targets the one keyed row; `key = None` matches + /// `subsystem_key IS NULL`, i.e. **all** keyless todos for that + /// subsystem (keyless rows have no distinguishing key — clear a + /// specific one via [`Todos::mark_done`] by id instead). Returns the + /// number of rows deleted (0 when nothing matched). + /// + /// # Errors + /// + /// Propagates the sqlite delete failure. + /// + /// # Panics + /// + /// Panics if the connection mutex is poisoned. pub fn clear(&self, agent: &str, subsystem: &str, key: Option<&str>) -> Result { let conn = self.conn.lock().unwrap(); let n = conn.execute( @@ -152,6 +177,14 @@ impl Todos { /// Clear every todo `agent`'s `subsystem` owns — used by a producer /// that rebuilds its whole set on restart (cancel-and-recreate). /// Returns the number of rows deleted. + /// + /// # Errors + /// + /// Propagates the sqlite delete failure. + /// + /// # Panics + /// + /// Panics if the connection mutex is poisoned. pub fn clear_subsystem(&self, agent: &str, subsystem: &str) -> Result { let conn = self.conn.lock().unwrap(); let n = conn.execute( @@ -164,6 +197,14 @@ impl Todos { /// The agent marks one of *its own* todos done, by id. Scoped to /// `agent` so one agent can't clear another's. Returns the number of /// rows deleted (0 when the id was unknown / not owned / already gone). + /// + /// # Errors + /// + /// Propagates the sqlite delete failure. + /// + /// # Panics + /// + /// Panics if the connection mutex is poisoned. pub fn mark_done(&self, agent: &str, id: i64) -> Result { let conn = self.conn.lock().unwrap(); let n = conn.execute( @@ -176,6 +217,14 @@ impl Todos { /// List `agent`'s todos, newest-updated first. `subsystem = Some(..)` /// filters to one producer's set (so a producer can enumerate + /// reconcile only its own); `None` returns all of the agent's. + /// + /// # Errors + /// + /// Propagates the sqlite prepare / query failures. + /// + /// # Panics + /// + /// Panics if the connection mutex is poisoned. pub fn list(&self, agent: &str, subsystem: Option<&str>) -> Result> { let conn = self.conn.lock().unwrap(); let mut stmt = conn.prepare( diff --git a/hive-sh4re/src/lib.rs b/hive-sh4re/src/lib.rs index 439d2096..73180185 100644 --- a/hive-sh4re/src/lib.rs +++ b/hive-sh4re/src/lib.rs @@ -453,9 +453,12 @@ pub enum Request { #[serde(default, skip_serializing_if = "Option::is_none")] source: Option, }, - /// Clear a producer-resolved todo by `(subsystem, key)`. `key = None` - /// targets the keyless one-off; `all = true` wipes the producer's - /// whole set (cancel-and-recreate on daemon restart). + /// Clear producer-resolved todo(s) by `(subsystem, key)`. `key = + /// Some(k)` clears the one keyed row; `key = None` clears **all** of + /// the subsystem's keyless todos (rows with no key can't be told + /// apart — clear a specific one via `MarkTodoDone` by id). `all = + /// true` wipes the producer's whole set (cancel-and-recreate on + /// daemon restart). ClearTodo { subsystem: String, #[serde(default, skip_serializing_if = "Option::is_none")]