Skip to main content

systemprompt_cli/commands/admin/setup/
mod.rs

1mod common;
2mod docker;
3mod postgres;
4mod profile;
5mod secrets;
6mod types;
7mod wizard;
8
9use crate::shared::CommandResult;
10use anyhow::Result;
11use clap::Args;
12
13pub use types::*;
14
15#[derive(Debug, Args)]
16pub struct SetupArgs {
17    #[arg(
18        short,
19        long,
20        help = "Target environment name (e.g., dev, staging, prod)"
21    )]
22    pub environment: Option<String>,
23
24    #[arg(
25        long,
26        help = "Use Docker for PostgreSQL (default: use existing installation)"
27    )]
28    pub docker: bool,
29
30    #[arg(
31        long,
32        env = "SYSTEMPROMPT_DB_HOST",
33        default_value = "localhost",
34        help = "PostgreSQL host"
35    )]
36    pub db_host: String,
37
38    #[arg(
39        long,
40        env = "SYSTEMPROMPT_DB_PORT",
41        default_value = "5432",
42        help = "PostgreSQL port"
43    )]
44    pub db_port: u16,
45
46    #[arg(
47        long,
48        env = "SYSTEMPROMPT_DB_USER",
49        help = "PostgreSQL user (default: systemprompt_`<env>`)"
50    )]
51    pub db_user: Option<String>,
52
53    #[arg(
54        long,
55        env = "SYSTEMPROMPT_DB_PASSWORD",
56        help = "PostgreSQL password (auto-generated if not provided)"
57    )]
58    pub db_password: Option<String>,
59
60    #[arg(
61        long,
62        env = "SYSTEMPROMPT_DB_NAME",
63        help = "PostgreSQL database name (default: systemprompt_`<env>`)"
64    )]
65    pub db_name: Option<String>,
66
67    #[arg(long, env = "GEMINI_API_KEY", help = "Google AI (Gemini) API key")]
68    pub gemini_key: Option<String>,
69
70    #[arg(long, env = "ANTHROPIC_API_KEY", help = "Anthropic (Claude) API key")]
71    pub anthropic_key: Option<String>,
72
73    #[arg(long, env = "OPENAI_API_KEY", help = "OpenAI (GPT) API key")]
74    pub openai_key: Option<String>,
75
76    #[arg(long, env = "GITHUB_TOKEN", help = "GitHub token (optional)")]
77    pub github_token: Option<String>,
78
79    #[arg(long, help = "Run database migrations after setup")]
80    pub migrate: bool,
81
82    #[arg(
83        long,
84        conflicts_with = "migrate",
85        help = "Skip migrations (non-interactive default)"
86    )]
87    pub no_migrate: bool,
88
89    #[arg(long, help = "Preview setup without creating files or making changes")]
90    pub dry_run: bool,
91
92    #[arg(short = 'y', long, help = "Skip confirmation prompts")]
93    pub yes: bool,
94}
95
96impl SetupArgs {
97    pub fn effective_db_user(&self, env_name: &str) -> String {
98        self.db_user
99            .clone()
100            .unwrap_or_else(|| format!("systemprompt_{}", env_name))
101    }
102
103    pub fn effective_db_name(&self, env_name: &str) -> String {
104        self.db_name
105            .clone()
106            .unwrap_or_else(|| format!("systemprompt_{}", env_name))
107    }
108
109    pub const fn has_ai_provider(&self) -> bool {
110        self.gemini_key.is_some() || self.anthropic_key.is_some() || self.openai_key.is_some()
111    }
112}
113
114pub async fn execute(
115    args: SetupArgs,
116    config: &crate::CliConfig,
117) -> Result<CommandResult<SetupOutput>> {
118    wizard::execute(args, config).await
119}