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) = ¶ms.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}