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 TenantCreateOutput {
132    pub id: String,
133    pub name: String,
134    pub tenant_type: String,
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub database_url: Option<String>,
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub profile_name: Option<String>,
139    pub message: String,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
143pub struct RotateCredentialsOutput {
144    #[serde(rename = "tenant_id")]
145    pub tenant: String,
146    pub status: String,
147    pub internal_database_url: String,
148    pub external_database_url: String,
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
152pub struct ProfileSummary {
153    pub name: String,
154    pub has_secrets: bool,
155    pub is_active: bool,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
159pub struct ProfileListOutput {
160    pub profiles: Vec<ProfileSummary>,
161    pub total: usize,
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub active_profile: Option<String>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
167pub struct DeployOutput {
168    pub tenant_name: String,
169    pub image: String,
170    pub status: String,
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub url: Option<String>,
173    pub secrets_synced: usize,
174    pub cloud_credentials_synced: usize,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
178pub struct SyncOutput {
179    pub direction: String,
180    pub dry_run: bool,
181    pub operations: Vec<SyncOperationOutput>,
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
185pub struct SyncOperationOutput {
186    pub operation: String,
187    pub success: bool,
188    pub items_synced: usize,
189    pub errors: Vec<String>,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
193pub struct AdminUserSyncResultOutput {
194    pub profile: String,
195    pub success: bool,
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub message: Option<String>,
198    #[serde(skip_serializing_if = "Option::is_none")]
199    pub error: Option<String>,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
203pub struct AdminUserSyncOutput {
204    pub cloud_user_email: String,
205    pub results: Vec<AdminUserSyncResultOutput>,
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
209pub struct SkillsSyncOutput {
210    pub direction: String,
211    pub dry_run: bool,
212    pub synced: usize,
213    pub created: usize,
214    pub updated: usize,
215    pub deleted: usize,
216    pub errors: Vec<String>,
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
220pub struct SecretsOutput {
221    pub operation: String,
222    pub keys: Vec<String>,
223    #[serde(skip_serializing_if = "Option::is_none")]
224    pub rejected_keys: Option<Vec<String>>,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
228pub struct RestartOutput {
229    pub tenant_name: String,
230    pub status: String,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
234pub struct DomainOutput {
235    pub tenant_name: String,
236    pub domain: String,
237    pub status: String,
238    #[serde(skip_serializing_if = "Option::is_none")]
239    pub certificate_status: Option<String>,
240}
241
242#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
243pub struct DockerfileOutput {
244    pub content: String,
245}
246
247#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
248pub struct InitOutput {
249    pub message: String,
250    pub created_paths: Vec<String>,
251}
252
253#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
254pub struct CancelSubscriptionOutput {
255    #[serde(rename = "tenant_id")]
256    pub tenant: String,
257    pub tenant_name: String,
258    pub message: String,
259}