Skip to main content

systemprompt_cli/commands/admin/users/
mod.rs

1//! User administration command tree.
2//!
3//! [`UsersCommands`] groups the user CRUD, search, export, stats, merge, and
4//! the `bulk`, `role`, `session`, `ban`, and `webauthn` subcommand trees.
5//! [`execute`] runs against a full profile; [`execute_with_db`] serves the
6//! read-only subset that needs only a database pool and rejects write
7//! operations.
8
9mod ban;
10mod bulk;
11mod count;
12mod create;
13pub(crate) mod delete;
14mod export;
15mod list;
16mod merge;
17mod role;
18mod search;
19mod session;
20mod show;
21mod stats;
22mod types;
23mod update;
24mod webauthn;
25
26use crate::cli_settings::CliConfig;
27use crate::shared::render_result;
28use anyhow::{Result, bail};
29use clap::Subcommand;
30use systemprompt_runtime::DatabaseContext;
31
32pub use types::*;
33
34#[derive(Debug, Subcommand)]
35pub enum UsersCommands {
36    #[command(about = "List users with pagination and filtering")]
37    List(list::ListArgs),
38
39    #[command(about = "Show detailed user information")]
40    Show(show::ShowArgs),
41
42    #[command(about = "Search users by name, email, or full name")]
43    Search(search::SearchArgs),
44
45    #[command(about = "Create a new user")]
46    Create(create::CreateArgs),
47
48    #[command(about = "Update user fields")]
49    Update(update::UpdateArgs),
50
51    #[command(about = "Delete a user")]
52    Delete(delete::DeleteArgs),
53
54    #[command(about = "Get total user count")]
55    Count(count::CountArgs),
56
57    #[command(about = "Export users to JSON")]
58    Export(export::ExportArgs),
59
60    #[command(about = "Show user statistics dashboard")]
61    Stats,
62
63    #[command(about = "Merge source user into target user")]
64    Merge(merge::MergeArgs),
65
66    #[command(subcommand, about = "Bulk operations on users")]
67    Bulk(bulk::BulkCommands),
68
69    #[command(subcommand, about = "Role management commands")]
70    Role(role::RoleCommands),
71
72    #[command(subcommand, about = "Session management commands")]
73    Session(session::SessionCommands),
74
75    #[command(subcommand, about = "IP ban management commands")]
76    Ban(ban::BanCommands),
77
78    #[command(subcommand, about = "WebAuthn credential management commands")]
79    Webauthn(webauthn::WebauthnCommands),
80}
81
82pub async fn execute(cmd: UsersCommands, config: &CliConfig) -> Result<()> {
83    match cmd {
84        UsersCommands::List(args) => {
85            let result = list::execute(args, config).await?;
86            render_result(&result);
87            Ok(())
88        },
89        UsersCommands::Show(args) => {
90            let result = show::execute(args, config).await?;
91            render_result(&result);
92            Ok(())
93        },
94        UsersCommands::Search(args) => {
95            let result = search::execute(args, config).await?;
96            render_result(&result);
97            Ok(())
98        },
99        UsersCommands::Create(args) => {
100            let result = create::execute(args, config).await?;
101            render_result(&result);
102            Ok(())
103        },
104        UsersCommands::Update(args) => {
105            let result = update::execute(args, config).await?;
106            render_result(&result);
107            Ok(())
108        },
109        UsersCommands::Delete(args) => {
110            let result = delete::execute(args, config).await?;
111            render_result(&result);
112            Ok(())
113        },
114        UsersCommands::Count(args) => {
115            let result = count::execute(args, config).await?;
116            render_result(&result);
117            Ok(())
118        },
119        UsersCommands::Export(args) => {
120            let result = export::execute(args, config).await?;
121            render_result(&result);
122            Ok(())
123        },
124        UsersCommands::Stats => {
125            let result = stats::execute(config).await?;
126            render_result(&result);
127            Ok(())
128        },
129        UsersCommands::Merge(args) => {
130            let result = merge::execute(args, config).await?;
131            render_result(&result);
132            Ok(())
133        },
134        UsersCommands::Bulk(cmd) => bulk::execute(cmd, config).await,
135        UsersCommands::Role(cmd) => role::execute(cmd, config).await,
136        UsersCommands::Session(cmd) => session::execute(cmd, config).await,
137        UsersCommands::Ban(cmd) => ban::execute(cmd, config).await,
138        UsersCommands::Webauthn(cmd) => webauthn::execute(cmd, config).await,
139    }
140}
141
142pub async fn execute_with_db(
143    cmd: UsersCommands,
144    db_ctx: &DatabaseContext,
145    config: &CliConfig,
146) -> Result<()> {
147    match cmd {
148        UsersCommands::List(args) => {
149            let result = list::execute_with_pool(args, db_ctx.db_pool(), config).await?;
150            render_result(&result);
151            Ok(())
152        },
153        UsersCommands::Show(args) => {
154            let result = show::execute_with_pool(args, db_ctx.db_pool(), config).await?;
155            render_result(&result);
156            Ok(())
157        },
158        UsersCommands::Search(args) => {
159            let result = search::execute_with_pool(args, db_ctx.db_pool(), config).await?;
160            render_result(&result);
161            Ok(())
162        },
163        UsersCommands::Count(args) => {
164            let result = count::execute_with_pool(args, db_ctx.db_pool(), config).await?;
165            render_result(&result);
166            Ok(())
167        },
168        UsersCommands::Export(args) => {
169            let result = export::execute_with_pool(args, db_ctx.db_pool(), config).await?;
170            render_result(&result);
171            Ok(())
172        },
173        UsersCommands::Stats => {
174            let result = stats::execute_with_pool(db_ctx.db_pool(), config).await?;
175            render_result(&result);
176            Ok(())
177        },
178        UsersCommands::Session(cmd) => {
179            session::execute_with_pool(cmd, db_ctx.db_pool(), config).await
180        },
181        UsersCommands::Ban(cmd) => ban::execute_with_pool(cmd, db_ctx.db_pool(), config).await,
182        UsersCommands::Role(cmd) => role::execute_with_pool(cmd, db_ctx.db_pool(), config),
183        UsersCommands::Create(_)
184        | UsersCommands::Update(_)
185        | UsersCommands::Delete(_)
186        | UsersCommands::Merge(_)
187        | UsersCommands::Bulk(_)
188        | UsersCommands::Webauthn(_) => {
189            bail!("Write operations require full profile context")
190        },
191    }
192}