1use super::VectorizerClient;
13use crate::error::{Result, VectorizerError};
14use crate::models::{
15 CreateUserBackupRequest, HubApiKeyValidation, QuotaInfo, RestoreUserBackupRequest,
16 UploadUserBackupRequest, UsageStatistics, UserBackup,
17};
18
19impl VectorizerClient {
20 pub async fn list_user_backups(&self, user_id: &str) -> Result<Vec<UserBackup>> {
24 let endpoint = format!("/hub/backups?user_id={user_id}");
25 let response = self.make_request("GET", &endpoint, None).await?;
26 let val: serde_json::Value = serde_json::from_str(&response).map_err(|e| {
27 VectorizerError::server(format!("Failed to parse list_user_backups response: {e}"))
28 })?;
29 let arr = val
30 .get("backups")
31 .and_then(|b| b.as_array())
32 .cloned()
33 .unwrap_or_default();
34 arr.into_iter()
35 .map(|v| {
36 serde_json::from_value(v).map_err(|e| {
37 VectorizerError::server(format!("Failed to parse user backup entry: {e}"))
38 })
39 })
40 .collect()
41 }
42
43 pub async fn create_user_backup(&self, request: CreateUserBackupRequest) -> Result<UserBackup> {
47 let payload = serde_json::to_value(&request).map_err(|e| {
48 VectorizerError::server(format!(
49 "Failed to serialize create_user_backup request: {e}"
50 ))
51 })?;
52 let response = self
53 .make_request("POST", "/hub/backups", Some(payload))
54 .await?;
55 let val: serde_json::Value = serde_json::from_str(&response).map_err(|e| {
56 VectorizerError::server(format!("Failed to parse create_user_backup response: {e}"))
57 })?;
58 serde_json::from_value(val.get("backup").cloned().unwrap_or(val)).map_err(|e| {
59 VectorizerError::server(format!("Failed to parse user backup from response: {e}"))
60 })
61 }
62
63 pub async fn restore_user_backup(&self, request: RestoreUserBackupRequest) -> Result<()> {
67 let payload = serde_json::to_value(&request).map_err(|e| {
68 VectorizerError::server(format!(
69 "Failed to serialize restore_user_backup request: {e}"
70 ))
71 })?;
72 self.make_request("POST", "/hub/backups/restore", Some(payload))
73 .await?;
74 Ok(())
75 }
76
77 pub async fn upload_user_backup(&self, request: UploadUserBackupRequest) -> Result<UserBackup> {
87 let mut qs = format!("user_id={}", request.user_id);
88 if let Some(name) = &request.name {
89 qs.push_str(&format!("&name={name}"));
90 }
91 let endpoint = format!("/hub/backups/upload?{qs}");
92 let payload = serde_json::json!({ "data": request.data });
96 let response = self.make_request("POST", &endpoint, Some(payload)).await?;
97 let val: serde_json::Value = serde_json::from_str(&response).map_err(|e| {
98 VectorizerError::server(format!("Failed to parse upload_user_backup response: {e}"))
99 })?;
100 serde_json::from_value(val.get("backup").cloned().unwrap_or(val)).map_err(|e| {
101 VectorizerError::server(format!(
102 "Failed to parse user backup from upload response: {e}"
103 ))
104 })
105 }
106
107 pub async fn get_user_backup(&self, user_id: &str, backup_id: &str) -> Result<UserBackup> {
111 let endpoint = format!("/hub/backups/{backup_id}?user_id={user_id}");
112 let response = self.make_request("GET", &endpoint, None).await?;
113 let val: serde_json::Value = serde_json::from_str(&response).map_err(|e| {
114 VectorizerError::server(format!("Failed to parse get_user_backup response: {e}"))
115 })?;
116 serde_json::from_value(val.get("backup").cloned().unwrap_or(val)).map_err(|e| {
117 VectorizerError::server(format!(
118 "Failed to parse user backup from get response: {e}"
119 ))
120 })
121 }
122
123 pub async fn delete_user_backup(&self, user_id: &str, backup_id: &str) -> Result<()> {
127 let endpoint = format!("/hub/backups/{backup_id}?user_id={user_id}");
128 self.make_request("DELETE", &endpoint, None).await?;
129 Ok(())
130 }
131
132 pub async fn download_user_backup(&self, user_id: &str, backup_id: &str) -> Result<Vec<u8>> {
140 let endpoint = format!("/hub/backups/{backup_id}/download?user_id={user_id}");
141 let response = self.make_request("GET", &endpoint, None).await?;
142 Ok(response.into_bytes())
143 }
144
145 pub async fn get_usage_statistics(&self, user_id: &str) -> Result<UsageStatistics> {
149 let endpoint = format!("/hub/usage/statistics?user_id={user_id}");
150 let response = self.make_request("GET", &endpoint, None).await?;
151 serde_json::from_str(&response).map_err(|e| {
152 VectorizerError::server(format!(
153 "Failed to parse get_usage_statistics response: {e}"
154 ))
155 })
156 }
157
158 pub async fn get_quota_info(&self, user_id: &str) -> Result<QuotaInfo> {
162 let endpoint = format!("/hub/usage/quota?user_id={user_id}");
163 let response = self.make_request("GET", &endpoint, None).await?;
164 serde_json::from_str(&response).map_err(|e| {
165 VectorizerError::server(format!("Failed to parse get_quota_info response: {e}"))
166 })
167 }
168
169 pub async fn validate_hub_api_key(&self, key: &str) -> Result<HubApiKeyValidation> {
177 let payload = serde_json::json!({ "key": key });
178 let response = self
179 .make_request("POST", "/hub/validate-key", Some(payload))
180 .await?;
181 serde_json::from_str(&response).map_err(|e| {
182 VectorizerError::server(format!(
183 "Failed to parse validate_hub_api_key response: {e}"
184 ))
185 })
186 }
187}
188
189#[cfg(test)]
190mod tests {
191 #![allow(clippy::unwrap_used)]
192
193 use serde_json::json;
194
195 use crate::models::{
196 CreateUserBackupRequest, HubApiKeyValidation, QuotaInfo, RestoreUserBackupRequest,
197 UsageStatistics, UserBackup,
198 };
199
200 #[test]
201 fn user_backup_deserializes() {
202 let raw = json!({
203 "id": "b-1",
204 "user_id": "u-1",
205 "name": "my-backup",
206 "collections": ["docs"],
207 "created_at": "2026-05-02T00:00:00Z",
208 "size": 8192u64,
209 "status": "active"
210 });
211 let b: UserBackup = serde_json::from_value(raw).unwrap();
212 assert_eq!(b.id, "b-1");
213 assert_eq!(b.status, "active");
214 assert_eq!(b.size, 8192);
215 }
216
217 #[test]
218 fn user_backup_round_trip() {
219 let b = UserBackup {
220 id: "b-2".into(),
221 user_id: "u-2".into(),
222 name: "weekly".into(),
223 description: Some("desc".into()),
224 collections: vec!["col1".into()],
225 created_at: "2026-05-02T00:00:00Z".into(),
226 size: 1024,
227 status: "active".into(),
228 };
229 let serialized = serde_json::to_value(&b).unwrap();
230 let parsed: UserBackup = serde_json::from_value(serialized).unwrap();
231 assert_eq!(parsed.id, "b-2");
232 assert_eq!(parsed.description.as_deref(), Some("desc"));
233 }
234
235 #[test]
236 fn create_user_backup_request_serializes() {
237 let req = CreateUserBackupRequest {
238 user_id: "u-1".into(),
239 name: "nightly".into(),
240 description: None,
241 collections: Some(vec!["code".into()]),
242 };
243 let v = serde_json::to_value(&req).unwrap();
244 assert_eq!(v["user_id"], "u-1");
245 assert_eq!(v["name"], "nightly");
246 assert_eq!(v["collections"][0], "code");
247 assert!(v.get("description").is_none());
249 }
250
251 #[test]
252 fn restore_user_backup_request_serializes() {
253 let req = RestoreUserBackupRequest {
254 user_id: "u-1".into(),
255 backup_id: "b-99".into(),
256 overwrite: true,
257 };
258 let v = serde_json::to_value(&req).unwrap();
259 assert_eq!(v["backup_id"], "b-99");
260 assert!(v["overwrite"].as_bool().unwrap());
261 }
262
263 #[test]
264 fn usage_statistics_deserializes() {
265 let raw = json!({
266 "success": true,
267 "message": "ok",
268 "stats": {
269 "user_id": "u-1",
270 "total_collections": 3,
271 "total_vectors": 500u64,
272 "total_storage": 512000u64
273 }
274 });
275 let us: UsageStatistics = serde_json::from_value(raw).unwrap();
276 assert!(us.success);
277 assert!(us.stats.is_some());
278 }
279
280 #[test]
281 fn quota_info_deserializes() {
282 let raw = json!({
283 "success": true,
284 "message": "ok",
285 "quota": {
286 "tenant_id": "t-1",
287 "storage": { "limit": 1_000_000u64, "used": 50_000u64 }
288 }
289 });
290 let qi: QuotaInfo = serde_json::from_value(raw).unwrap();
291 assert!(qi.success);
292 assert!(qi.quota.is_some());
293 }
294
295 #[test]
296 fn hub_api_key_validation_deserializes_valid() {
297 let raw = json!({
298 "valid": true,
299 "tenant_id": "t-abc",
300 "tenant_name": "Acme",
301 "permissions": ["Read", "Write"],
302 "validated_at": "2026-05-02T00:00:00Z"
303 });
304 let v: HubApiKeyValidation = serde_json::from_value(raw).unwrap();
305 assert!(v.valid);
306 assert_eq!(v.tenant_id, "t-abc");
307 assert_eq!(v.permissions.len(), 2);
308 }
309
310 #[test]
311 fn hub_api_key_validation_deserializes_invalid() {
312 let raw = json!({
313 "valid": false,
314 "tenant_id": "",
315 "tenant_name": "",
316 "permissions": [],
317 "validated_at": ""
318 });
319 let v: HubApiKeyValidation = serde_json::from_value(raw).unwrap();
320 assert!(!v.valid);
321 }
322}