1use crate::core_loop::{AlertSeverity, RuleAction, rules, time};
3use crate::shell::cli::workspace_path;
4use crate::store::Store;
5use anyhow::{Result, anyhow};
6use std::path::Path;
7
8pub fn cmd_rules_create(
9 workspace: Option<&Path>,
10 name: &str,
11 filter: &str,
12 action: &str,
13 message: Option<String>,
14) -> Result<()> {
15 let rule = rules::create(
16 &open(workspace)?,
17 name,
18 filter,
19 parse_action(action, message)?,
20 time::now_ms(),
21 )?;
22 println!("created rule {} ยท {}", rule.id, rule.name);
23 Ok(())
24}
25
26pub fn cmd_rules_list(workspace: Option<&Path>, json: bool) -> Result<()> {
27 let rows = rules::list(&open(workspace)?)?;
28 if json {
29 println!("{}", serde_json::to_string_pretty(&rows)?);
30 } else {
31 rows.iter()
32 .for_each(|r| println!("{} enabled={} {}", r.id, r.enabled, r.name));
33 }
34 Ok(())
35}
36
37pub fn cmd_rules_run(
38 workspace: Option<&Path>,
39 since: Option<&str>,
40 dry_run: bool,
41 json: bool,
42) -> Result<()> {
43 let ws = workspace_path(workspace)?;
44 let store = Store::open(&crate::core::workspace::db_path(&ws)?)?;
45 let rows = rules::run_enabled(
46 &store,
47 &ws.to_string_lossy(),
48 time::parse_window(since, 7)?,
49 time::now_ms(),
50 dry_run,
51 )?;
52 if json {
53 println!("{}", serde_json::to_string_pretty(&rows)?);
54 } else {
55 rows.iter()
56 .for_each(|r| println!("{} hits={} actions={}", r.rule_id, r.hits, r.actions));
57 }
58 Ok(())
59}
60
61pub fn cmd_rules_enable(workspace: Option<&Path>, id: &str, enabled: bool) -> Result<()> {
62 rules::set_enabled(&open(workspace)?, id, enabled)?;
63 println!("{} rule {id}", if enabled { "enabled" } else { "disabled" });
64 Ok(())
65}
66
67fn open(workspace: Option<&Path>) -> Result<Store> {
68 let ws = workspace_path(workspace)?;
69 Store::open(&crate::core::workspace::db_path(&ws)?)
70}
71
72fn parse_action(raw: &str, message: Option<String>) -> Result<RuleAction> {
73 Ok(match raw {
74 "create_case" => RuleAction::CreateCase { label: message },
75 "queue_review" => RuleAction::QueueReview { title: message },
76 "emit_alert" => RuleAction::EmitAlert {
77 severity: AlertSeverity::Warning,
78 },
79 _ => {
80 return Err(anyhow!(
81 "action must be create_case, queue_review, or emit_alert"
82 ));
83 }
84 })
85}