Skip to main content

uarp_sdk/generated/api/
notifications.rs

1// Code generated by @uarp/codegen from spec/openapi.json. DO NOT EDIT.
2//!
3//! User notifications
4
5#![allow(unused_imports, clippy::too_many_arguments)]
6
7use reqwest::Method;
8use serde::{Deserialize, Serialize};
9
10use crate::client::{Client, Request, NO_BODY, NO_QUERY};
11use crate::error::Result;
12use crate::generated::models;
13use crate::multipart::{field_text, FilePart};
14use crate::sse::EventStream;
15use crate::util::encode_path;
16
17/// Query and header parameters for `bulkDeleteNotifications`.
18#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
19pub struct BulkDeleteNotificationsParams {
20    #[serde(default, skip_serializing_if = "Option::is_none")]
21    pub scope: Option<models::BulkDeleteNotificationsScope>,
22}
23
24/// Query and header parameters for `listNotifications`.
25#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
26pub struct ListNotificationsParams {
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub limit: Option<i64>,
29    /// Filter to unread only
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    pub unread: Option<bool>,
32}
33
34/// Query and header parameters for `streamNotifications`.
35#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
36pub struct StreamNotificationsParams {
37    /// Short-lived SSE/WebSocket token (mint via `POST /api/v1/auth/sse-tokens`) or full API key.
38    /// Used by browser EventSource which cannot set Authorization header.
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub token: Option<String>,
41    /// SSE resumption cursor. The browser's EventSource sets this automatically on reconnect;
42    /// servers replay events strictly after this id.
43    #[serde(skip)]
44    pub last_event_id: Option<String>,
45}
46
47/// User notifications
48#[derive(Debug, Clone)]
49pub struct NotificationsApi {
50    pub(crate) client: Client,
51}
52
53impl Client {
54    /// User notifications
55    pub fn notifications(&self) -> NotificationsApi {
56        NotificationsApi { client: self.clone() }
57    }
58}
59
60impl NotificationsApi {
61    /// Bulk-purge notifications
62    ///
63    /// Bulk delete. Optional `?scope=read` keeps unread items so the operator can't accidentally
64    /// wipe pending approvals; default wipes everything.
65    ///
66    /// `DELETE /api/v1/notifications`
67    ///
68    /// Required scopes: `notifications:write`.
69    pub async fn bulk_delete_notifications(&self, params: &BulkDeleteNotificationsParams) -> Result<models::BulkDeleteNotificationsResponse> {
70        self.client
71            .request_json(Request {
72                method: Method::DELETE,
73                path: "/api/v1/notifications".to_string(),
74                query: Some(params),
75                body: NO_BODY,
76                headers: Vec::new(),
77                idempotent: true,
78            })
79            .await
80    }
81
82    /// Purge a single notification
83    ///
84    /// `DELETE /api/v1/notifications/{notifId}`
85    ///
86    /// Required scopes: `notifications:write`.
87    pub async fn delete(&self, notif_id: &str) -> Result<models::DeleteNotificationResponse> {
88        self.client
89            .request_json(Request {
90                method: Method::DELETE,
91                path: format!("/api/v1/notifications/{}", encode_path(notif_id)),
92                query: NO_QUERY,
93                body: NO_BODY,
94                headers: Vec::new(),
95                idempotent: true,
96            })
97            .await
98    }
99
100    /// Remove a target
101    ///
102    /// `DELETE /api/v1/notifications/targets/{targetId}`
103    ///
104    /// Required scopes: `notifications:write`.
105    pub async fn delete_notification_target(&self, target_id: &str) -> Result<models::DeleteNotificationTargetResponse> {
106        self.client
107            .request_json(Request {
108                method: Method::DELETE,
109                path: format!("/api/v1/notifications/targets/{}", encode_path(target_id)),
110                query: NO_QUERY,
111                body: NO_BODY,
112                headers: Vec::new(),
113                idempotent: true,
114            })
115            .await
116    }
117
118    /// Read the tenant's notification routing preferences
119    ///
120    /// Returns the stored preferences, or the server defaults (critical → in_app+email, everything
121    /// else → in_app) when none are stored. Note: `email` in a channel list only delivers when the
122    /// tenant also has an email target configured (see POST /notifications/targets).
123    ///
124    /// `GET /api/v1/notifications/prefs`
125    ///
126    /// Required scopes: `notifications:read`.
127    pub async fn get_notification_preferences(&self) -> Result<models::NotificationPreferences> {
128        self.client
129            .request_json(Request {
130                method: Method::GET,
131                path: "/api/v1/notifications/prefs".to_string(),
132                query: NO_QUERY,
133                body: NO_BODY,
134                headers: Vec::new(),
135                idempotent: false,
136            })
137            .await
138    }
139
140    /// Get unread notification count
141    ///
142    /// `GET /api/v1/notifications/unread`
143    ///
144    /// Required scopes: `notifications:read`.
145    pub async fn get_unread_count(&self) -> Result<models::GetUnreadCountResponse> {
146        self.client
147            .request_json(Request {
148                method: Method::GET,
149                path: "/api/v1/notifications/unread".to_string(),
150                query: NO_QUERY,
151                body: NO_BODY,
152                headers: Vec::new(),
153                idempotent: false,
154            })
155            .await
156    }
157
158    /// List notifications
159    ///
160    /// `GET /api/v1/notifications`
161    ///
162    /// Required scopes: `notifications:read`.
163    pub async fn list(&self, params: &ListNotificationsParams) -> Result<models::ListNotificationsResponse> {
164        self.client
165            .request_json(Request {
166                method: Method::GET,
167                path: "/api/v1/notifications".to_string(),
168                query: Some(params),
169                body: NO_BODY,
170                headers: Vec::new(),
171                idempotent: false,
172            })
173            .await
174    }
175
176    /// List notification targets
177    ///
178    /// Every configured destination, with secrets redacted — see `NotificationTarget`.
179    ///
180    /// `GET /api/v1/notifications/targets`
181    ///
182    /// Required scopes: `notifications:read`.
183    pub async fn list_notification_targets(&self) -> Result<models::ListNotificationTargetsResponse> {
184        self.client
185            .request_json(Request {
186                method: Method::GET,
187                path: "/api/v1/notifications/targets".to_string(),
188                query: NO_QUERY,
189                body: NO_BODY,
190                headers: Vec::new(),
191                idempotent: false,
192            })
193            .await
194    }
195
196    /// Mark all notifications as read
197    ///
198    /// `PUT /api/v1/notifications/read-all`
199    ///
200    /// Required scopes: `notifications:write`.
201    pub async fn mark_all_notifications_read(&self) -> Result<models::MarkAllNotificationsReadResponse> {
202        self.client
203            .request_json(Request {
204                method: Method::PUT,
205                path: "/api/v1/notifications/read-all".to_string(),
206                query: NO_QUERY,
207                body: NO_BODY,
208                headers: Vec::new(),
209                idempotent: true,
210            })
211            .await
212    }
213
214    /// Mark notification as read
215    ///
216    /// `PUT /api/v1/notifications/{notifId}/read`
217    ///
218    /// Required scopes: `notifications:write`.
219    pub async fn mark_notification_read(&self, notif_id: &str) -> Result<models::MarkNotificationReadResponse> {
220        self.client
221            .request_json(Request {
222                method: Method::PUT,
223                path: format!("/api/v1/notifications/{}/read", encode_path(notif_id)),
224                query: NO_QUERY,
225                body: NO_BODY,
226                headers: Vec::new(),
227                idempotent: true,
228            })
229            .await
230    }
231
232    /// Replace the tenant's notification routing preferences
233    ///
234    /// WRITE SEMANTICS: replaces. An omitted field is stored as omitted (the only way to clear
235    /// muted_types or drop quiet_hours). `tenant_id` and `updated_at` are ignored — the server
236    /// derives them.
237    ///
238    /// `PUT /api/v1/notifications/prefs`
239    ///
240    /// Required scopes: `notifications:write`.
241    pub async fn replace_notification_preferences(&self, body: &models::NotificationPreferencesInput) -> Result<models::NotificationPreferences> {
242        self.client
243            .request_json(Request {
244                method: Method::PUT,
245                path: "/api/v1/notifications/prefs".to_string(),
246                query: NO_QUERY,
247                body: Some(body),
248                headers: Vec::new(),
249                idempotent: true,
250            })
251            .await
252    }
253
254    /// Open SSE stream of notifications for the tenant
255    ///
256    /// Server-Sent Events push channel. Replaces the 15-second polling loop: every new notification
257    /// created in the store for the calling tenant is fanned out to all open streams within
258    /// milliseconds. The first event is `event: ready` so the client knows the stream is live;
259    /// comment lines every 20 s keep proxies from killing idle connections.
260    ///
261    /// `GET /api/v1/notifications/stream`
262    ///
263    /// Required scopes: `notifications:read`.
264    ///
265    /// Returns a server-sent event stream.
266    pub fn stream(&self, params: &StreamNotificationsParams) -> EventStream {
267        let mut headers: Vec<(&'static str, String)> = Vec::new();
268        if let Some(value) = &params.last_event_id {
269            headers.push(("Last-Event-ID", value.clone()));
270        }
271        self.client.request_stream(
272            "/api/v1/notifications/stream",
273            Some(params),
274            headers,
275        )
276    }
277
278    /// Send a test notification
279    ///
280    /// Queues one notification through the real fan-out, so it proves the whole path rather than
281    /// the stored configuration. **200 means queued, not delivered** — read `last_delivered_at` and
282    /// `last_error` on the target afterwards for the outcome.
283    ///
284    /// `POST /api/v1/notifications/targets/{targetId}/test`
285    ///
286    /// Required scopes: `notifications:write`.
287    pub async fn test_notification_target(&self, target_id: &str) -> Result<models::TestNotificationTargetResponse> {
288        self.client
289            .request_json(Request {
290                method: Method::POST,
291                path: format!("/api/v1/notifications/targets/{}/test", encode_path(target_id)),
292                query: NO_QUERY,
293                body: NO_BODY,
294                headers: Vec::new(),
295                idempotent: true,
296            })
297            .await
298    }
299
300    /// Create or update a target
301    ///
302    /// Upsert, not insert: sending an `id` rewrites that target. A device target (push or web push)
303    /// additionally reuses the id of an existing entry for the same device, so a client that
304    /// re-registers on every launch does not accumulate duplicates.
305    ///
306    /// The answer is the REDACTED target — the signing secret or device token you just sent is not
307    /// echoed back.
308    ///
309    /// `POST /api/v1/notifications/targets`
310    ///
311    /// Required scopes: `notifications:write`.
312    pub async fn upsert_notification_target(&self, body: &models::UpsertNotificationTargetRequest) -> Result<models::NotificationTarget> {
313        self.client
314            .request_json(Request {
315                method: Method::POST,
316                path: "/api/v1/notifications/targets".to_string(),
317                query: NO_QUERY,
318                body: Some(body),
319                headers: Vec::new(),
320                idempotent: true,
321            })
322            .await
323    }
324}