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. On a
5//! `--database-url` invocation only the read-only commands are served; write
6//! operations require a full profile context.
7//!
8//! Copyright (c) systemprompt.io — Business Source License 1.1.
9//! See <https://systemprompt.io> for licensing details.
10
11mod ban;
12mod bulk;
13mod count;
14mod create;
15pub(crate) mod delete;
16mod export;
17mod list;
18mod merge;
19mod role;
20mod search;
21mod session;
22mod show;
23mod stats;
24mod types;
25mod update;
26mod webauthn;
27
28use crate::context::CommandContext;
29use crate::shared::render_result;
30use anyhow::{Result, bail};
31use clap::Subcommand;
32
33pub use types::*;
34
35#[derive(Debug, Subcommand)]
36pub enum UsersCommands {
37    #[command(about = "List users with pagination and filtering")]
38    List(list::ListArgs),
39
40    #[command(about = "Show detailed user information")]
41    Show(show::ShowArgs),
42
43    #[command(about = "Search users by name, email, or full name")]
44    Search(search::SearchArgs),
45
46    #[command(about = "Create a new user")]
47    Create(create::CreateArgs),
48
49    #[command(about = "Update user fields")]
50    Update(update::UpdateArgs),
51
52    #[command(about = "Delete a user")]
53    Delete(delete::DeleteArgs),
54
55    #[command(about = "Get total user count")]
56    Count(count::CountArgs),
57
58    #[command(about = "Export users to JSON")]
59    Export(export::ExportArgs),
60
61    #[command(about = "Show user statistics dashboard")]
62    Stats,
63
64    #[command(about = "Merge source user into target user")]
65    Merge(merge::MergeArgs),
66
67    #[command(subcommand, about = "Bulk operations on users")]
68    Bulk(bulk::BulkCommands),
69
70    #[command(subcommand, about = "Role management commands")]
71    Role(role::RoleCommands),
72
73    #[command(subcommand, about = "Session management commands")]
74    Session(session::SessionCommands),
75
76    #[command(subcommand, about = "IP ban management commands")]
77    Ban(ban::BanCommands),
78
79    #[command(subcommand, about = "WebAuthn credential management commands")]
80    Webauthn(webauthn::WebauthnCommands),
81}
82
83pub async fn execute(cmd: UsersCommands, ctx: &CommandContext) -> Result<()> {
84    if ctx.is_database_scoped()
85        && matches!(
86            cmd,
87            UsersCommands::Create(_)
88                | UsersCommands::Update(_)
89                | UsersCommands::Delete(_)
90                | UsersCommands::Merge(_)
91                | UsersCommands::Bulk(_)
92                | UsersCommands::Webauthn(_)
93        )
94    {
95        bail!("Write operations require full profile context");
96    }
97
98    match cmd {
99        UsersCommands::List(args) => {
100            let result = list::execute(args, ctx).await?;
101            render_result(&result, &ctx.cli);
102            Ok(())
103        },
104        UsersCommands::Show(args) => {
105            let result = show::execute(args, ctx).await?;
106            render_result(&result, &ctx.cli);
107            Ok(())
108        },
109        UsersCommands::Search(args) => {
110            let result = search::execute(args, ctx).await?;
111            render_result(&result, &ctx.cli);
112            Ok(())
113        },
114        UsersCommands::Create(args) => {
115            let result = create::execute(args, ctx).await?;
116            render_result(&result, &ctx.cli);
117            Ok(())
118        },
119        UsersCommands::Update(args) => {
120            let result = update::execute(args, ctx).await?;
121            render_result(&result, &ctx.cli);
122            Ok(())
123        },
124        UsersCommands::Delete(args) => {
125            let result = delete::execute(args, ctx).await?;
126            render_result(&result, &ctx.cli);
127            Ok(())
128        },
129        UsersCommands::Count(args) => {
130            let result = count::execute(args, ctx).await?;
131            render_result(&result, &ctx.cli);
132            Ok(())
133        },
134        UsersCommands::Export(args) => {
135            let result = export::execute(args, ctx).await?;
136            render_result(&result, &ctx.cli);
137            Ok(())
138        },
139        UsersCommands::Stats => {
140            let result = stats::execute(ctx).await?;
141            render_result(&result, &ctx.cli);
142            Ok(())
143        },
144        UsersCommands::Merge(args) => {
145            let result = merge::execute(args, ctx).await?;
146            render_result(&result, &ctx.cli);
147            Ok(())
148        },
149        UsersCommands::Bulk(cmd) => bulk::execute(cmd, ctx).await,
150        UsersCommands::Role(cmd) => role::execute(cmd, ctx).await,
151        UsersCommands::Session(cmd) => session::execute(cmd, ctx).await,
152        UsersCommands::Ban(cmd) => ban::execute(cmd, ctx).await,
153        UsersCommands::Webauthn(cmd) => webauthn::execute(cmd, ctx).await,
154    }
155}