Skip to main content

kaizen/shell/
cases.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2use crate::core_loop::{CaseStatus, cases, time};
3use crate::shell::cli::workspace_path;
4use crate::store::Store;
5use anyhow::{Result, anyhow};
6use std::path::Path;
7
8pub fn cmd_cases_mine(workspace: Option<&Path>, since: Option<&str>, json: bool) -> Result<()> {
9    let store = open(workspace)?;
10    let rows = cases::mine(&store, time::parse_window(since, 7)?, time::now_ms())?;
11    output(&rows, json)
12}
13
14pub fn cmd_cases_create(
15    workspace: Option<&Path>,
16    session_id: &str,
17    reason: &str,
18    label: Option<String>,
19    json: bool,
20) -> Result<()> {
21    let store = open(workspace)?;
22    let s = store
23        .get_session(session_id)?
24        .ok_or_else(|| anyhow!("session not found"))?;
25    let key = format!("manual:{session_id}:{reason}");
26    let row = cases::create_case(&store, &s, &key, reason, label, time::now_ms())?;
27    output(&[row], json)
28}
29
30pub fn cmd_cases_list(workspace: Option<&Path>, status: Option<String>, json: bool) -> Result<()> {
31    output(
32        &cases::list(&open(workspace)?, parse_status(status.as_deref()))?,
33        json,
34    )
35}
36
37pub fn cmd_cases_show(workspace: Option<&Path>, id: &str, json: bool) -> Result<()> {
38    let store = open(workspace)?;
39    let row = cases::get(&store, id)?;
40    if json {
41        println!("{}", serde_json::to_string_pretty(&row)?);
42    } else {
43        println!(
44            "{} session={} reason={} status={}",
45            row.id,
46            row.session_id,
47            row.reason,
48            row.status.as_str()
49        );
50    }
51    Ok(())
52}
53
54pub fn cmd_cases_archive(workspace: Option<&Path>, id: &str) -> Result<()> {
55    cases::archive(&open(workspace)?, id)?;
56    println!("archived case {id}");
57    Ok(())
58}
59
60fn open(workspace: Option<&Path>) -> Result<Store> {
61    let ws = workspace_path(workspace)?;
62    Store::open(&crate::core::workspace::db_path(&ws)?)
63}
64
65fn output(rows: &[crate::core_loop::CaseRecord], json: bool) -> Result<()> {
66    if json {
67        println!("{}", serde_json::to_string_pretty(rows)?);
68    } else {
69        rows.iter().for_each(|r| {
70            println!(
71                "{} session={} reason={} status={}",
72                r.id,
73                r.session_id,
74                r.reason,
75                r.status.as_str()
76            )
77        });
78    }
79    Ok(())
80}
81
82fn parse_status(raw: Option<&str>) -> Option<CaseStatus> {
83    raw.map(|s| {
84        if s == "archived" {
85            CaseStatus::Archived
86        } else {
87            CaseStatus::Open
88        }
89    })
90}