Skip to main content

systemprompt_cli/commands/cloud/
types.rs

1//! Serializable output DTOs for the `cloud` command group.
2//!
3//! Each type is the structured payload a cloud subcommand returns (status,
4//! login, tenant list/detail/create, secrets, deploy, sync, and related), used
5//! for both human rendering and `--json` output.
6
7use chrono::{DateTime, Utc};
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10
11pub use systemprompt_models::profile::ProfileInfo;
12
13#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
14pub struct CredentialsInfo {
15    pub authenticated: bool,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub user_email: Option<String>,
18    pub token_expired: bool,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
22pub struct TenantStatusInfo {
23    pub id: String,
24    pub name: String,
25    pub status: String,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub url: Option<String>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub message: Option<String>,
30    pub configured_in_profile: bool,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
34pub struct CloudStatusOutput {
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub profile: Option<ProfileInfo>,
37    pub credentials: CredentialsInfo,
38    pub tenants: Vec<TenantStatusInfo>,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
42pub struct TenantPlanInfo {
43    pub name: String,
44    pub memory_mb: i32,
45    pub volume_gb: i32,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
49pub struct LoginTenantInfo {
50    pub id: String,
51    pub name: String,
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub subscription_status: Option<String>,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub plan: Option<TenantPlanInfo>,
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub region: Option<String>,
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub hostname: Option<String>,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
63pub struct LoginUserInfo {
64    pub id: String,
65    pub email: String,
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub name: Option<String>,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
71pub struct LoginCustomerInfo {
72    pub id: String,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
76pub struct LoginOutput {
77    pub user: LoginUserInfo,
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub customer: Option<LoginCustomerInfo>,
80    pub tenants: Vec<LoginTenantInfo>,
81    pub credentials_path: String,
82    pub tenants_path: String,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
86pub struct WhoamiOutput {
87    pub user_email: String,
88    pub api_url: String,
89    pub token_status: String,
90    pub authenticated_at: DateTime<Utc>,
91    pub local_profiles: usize,
92    pub cloud_tenants: usize,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
96pub struct LogoutOutput {
97    pub message: String,
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub credentials_path: Option<String>,
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
103pub struct TenantSummary {
104    pub id: String,
105    pub name: String,
106    pub tenant_type: String,
107    pub has_database: bool,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
111pub struct TenantListOutput {
112    pub tenants: Vec<TenantSummary>,
113    pub total: usize,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
117pub struct TenantDetailOutput {
118    pub id: String,
119    pub name: String,
120    pub tenant_type: String,
121    #[serde(skip_serializing_if = "Option::is_none")]
122    pub app_id: Option<String>,
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub hostname: Option<String>,
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub region: Option<String>,
127    pub has_database: bool,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
131pub struct RotateCredentialsOutput {
132    #[serde(rename = "tenant_id")]
133    pub tenant: String,
134    pub status: String,
135    pub internal_database_url: String,
136    pub external_database_url: String,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
140pub struct ProfileSummary {
141    pub name: String,
142    pub has_secrets: bool,
143    pub is_active: bool,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
147pub struct ProfileListOutput {
148    pub profiles: Vec<ProfileSummary>,
149    pub total: usize,
150    #[serde(skip_serializing_if = "Option::is_none")]
151    pub active_profile: Option<String>,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
155pub struct SecretsOutput {
156    pub operation: String,
157    pub keys: Vec<String>,
158    #[serde(skip_serializing_if = "Option::is_none")]
159    pub rejected_keys: Option<Vec<String>>,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
163pub struct RestartOutput {
164    pub tenant_name: String,
165    pub status: String,
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
169pub struct DockerfileOutput {
170    pub content: String,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
174pub struct CancelSubscriptionOutput {
175    #[serde(rename = "tenant_id")]
176    pub tenant: String,
177    pub tenant_name: String,
178    pub message: String,
179}