brainos_backends/
scheduling.rs1#[derive(Clone)]
4pub struct DefaultSchedulingBackend {
5 pub db: storage::SqlitePool,
6 pub mode: brain_core::config::SchedulingMode,
7}
8
9#[async_trait::async_trait]
10impl cortex::actions::SchedulingBackend for DefaultSchedulingBackend {
11 async fn schedule(
12 &self,
13 description: &str,
14 cron: Option<&str>,
15 namespace: &str,
16 ) -> Result<cortex::actions::ScheduleOutcome, cortex::actions::ActionError> {
17 if self.mode != brain_core::config::SchedulingMode::PersistOnly {
18 return Err(cortex::actions::ActionError::InvalidArguments(format!(
19 "Unsupported scheduling mode: {:?}",
20 self.mode
21 )));
22 }
23
24 let metadata = serde_json::json!({
25 "source": "action_dispatcher",
26 "mode": "persist_only",
27 })
28 .to_string();
29
30 let schedule_id = self
31 .db
32 .insert_scheduled_intent(description, cron, namespace, Some(&metadata))
33 .map_err(|e| cortex::actions::ActionError::ExecutionFailed(e.to_string()))?;
34
35 Ok(cortex::actions::ScheduleOutcome {
36 schedule_id,
37 status: "scheduled".to_string(),
38 })
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[tokio::test]
47 async fn test_scheduling_backend_persists_intent() {
48 let db = storage::SqlitePool::open_memory().unwrap();
49 let backend = DefaultSchedulingBackend {
50 db: db.clone(),
51 mode: brain_core::config::SchedulingMode::PersistOnly,
52 };
53
54 let outcome = cortex::actions::SchedulingBackend::schedule(
55 &backend,
56 "ship release",
57 Some("0 9 * * 1-5"),
58 "work",
59 )
60 .await
61 .unwrap();
62
63 assert_eq!(outcome.status, "scheduled");
64 let intents = db.list_scheduled_intents(Some("work")).unwrap();
65 assert_eq!(intents.len(), 1);
66 assert_eq!(intents[0].id, outcome.schedule_id);
67 assert_eq!(intents[0].description, "ship release");
68 }
69}