cellstate/entity/
tenant.rs1use anyhow::{anyhow, Result};
6use clap::{Arg, ArgMatches, Command};
7
8use cellstate_core::api_types::{ListTenantsResponse, TenantInfo, UpdateTenantRequest};
9
10use super::client::ApiClient;
11use super::output::OutputConfig;
12
13const BASE: &str = "/api/v1/tenants";
14
15pub fn build_command() -> Command {
16 Command::new("tenant")
17 .about("Manage tenants")
18 .subcommand_required(true)
19 .subcommand(Command::new("list").about("List tenants"))
20 .subcommand(
21 Command::new("get")
22 .about("Get tenant details")
23 .arg(Arg::new("id").required(true).help("Tenant ID")),
24 )
25 .subcommand(
26 Command::new("update")
27 .about("Update a tenant")
28 .arg(Arg::new("id").required(true).help("Tenant ID"))
29 .arg(Arg::new("name").long("name").help("New name"))
30 .arg(Arg::new("domain").long("domain").help("New email domain"))
31 .arg(
32 Arg::new("status")
33 .long("status")
34 .help("New status (active, suspended, archived)"),
35 )
36 .arg(
37 Arg::new("settings")
38 .long("settings")
39 .help("Tenant settings as JSON string"),
40 ),
41 )
42}
43
44pub async fn dispatch(
45 matches: &ArgMatches,
46 client: &ApiClient,
47 output: &OutputConfig,
48 _session: &crate::session::CliSession,
49) -> Result<()> {
50 match matches.subcommand() {
51 Some(("list", _sub)) => {
52 let resp: ListTenantsResponse = client.get(BASE).await?;
53 output.print_list(&resp.tenants, resp.tenants.len() as i64);
54 }
55 Some(("get", sub)) => {
56 let id = sub.get_one::<String>("id").unwrap();
57 let resp: TenantInfo = client.get(&format!("{BASE}/{id}")).await?;
58 output.print(&resp);
59 }
60 Some(("update", sub)) => {
61 let id = sub.get_one::<String>("id").unwrap();
62 let req = UpdateTenantRequest {
63 name: sub.get_one::<String>("name").cloned(),
64 domain: sub.get_one::<String>("domain").cloned(),
65 status: sub
66 .get_one::<String>("status")
67 .map(|s| s.parse().map_err(|e: String| anyhow!(e)))
68 .transpose()?,
69 settings: sub
70 .get_one::<String>("settings")
71 .map(|s| serde_json::from_str(s))
72 .transpose()?,
73 };
74 let resp: TenantInfo = client.patch(&format!("{BASE}/{id}"), &req).await?;
75 output.print(&resp);
76 }
77 _ => unreachable!("subcommand_required(true) prevents this"),
78 }
79 Ok(())
80}