1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Code generated by @uarp/codegen from spec/openapi.json. DO NOT EDIT.
//!
//! Content reports — abuse/moderation reporting for authenticated users and anonymous
//! public-chat visitors, plus the operator inbox
#![allow(unused_imports, clippy::too_many_arguments)]
use reqwest::Method;
use serde::{Deserialize, Serialize};
use futures_core::Stream;
use crate::client::{Client, Request, NO_BODY, NO_QUERY};
use crate::error::Result;
use crate::generated::models;
use crate::multipart::{field_text, FilePart};
use crate::pagination::CursorGuard;
use crate::util::encode_path;
/// Query and header parameters for `listAllContentReports`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct ListAllContentReportsParams {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub limit: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
}
/// Query and header parameters for `listContentReports`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct ListContentReportsParams {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub limit: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
}
/// Content reports — abuse/moderation reporting for authenticated users and anonymous
/// public-chat visitors, plus the operator inbox
#[derive(Debug, Clone)]
pub struct ReportsApi {
pub(crate) client: Client,
}
impl Client {
/// Content reports — abuse/moderation reporting for authenticated users and anonymous
/// public-chat visitors, plus the operator inbox
pub fn reports(&self) -> ReportsApi {
ReportsApi { client: self.clone() }
}
}
impl ReportsApi {
/// File a content report
///
/// Report a message, session or agent. Available to any authenticated principal — deliberately
/// not role- or scope-gated, since reporting abuse must never be blocked by RBAC. Rate limited
/// to 10/minute per caller. `self_harm` is still accepted with 202 but raises the operator
/// notification to critical priority.
///
/// `POST /api/v1/reports`
pub async fn create_content_report(&self, body: &models::ContentReportInput) -> Result<models::ContentReportAccepted> {
self.client
.request_json(Request {
method: Method::POST,
path: "/api/v1/reports".to_string(),
query: NO_QUERY,
body: Some(body),
headers: Vec::new(),
idempotent: true,
})
.await
}
/// List content reports platform-wide (super-admin)
///
/// Every report across every tenant, newest first. A tenant whose agent is the problem must not
/// be the only party holding the evidence.
///
/// `GET /api/v1/admin/reports`
///
/// Required scopes: `admin`.
pub async fn list_all_content_reports(&self, params: &ListAllContentReportsParams) -> Result<models::ListAllContentReportsResponse> {
self.client
.request_json(Request {
method: Method::GET,
path: "/api/v1/admin/reports".to_string(),
query: Some(params),
body: NO_BODY,
headers: Vec::new(),
idempotent: false,
})
.await
}
/// Stream every item returned by `listAllContentReports`, following the `cursor` cursor until
/// the server reports no further pages.
pub fn list_all_content_reports_all<'a>(&'a self, params: &'a ListAllContentReportsParams) -> impl Stream<Item = Result<models::ContentReport>> + 'a {
async_stream::try_stream! {
let mut guard = CursorGuard::new();
let mut cursor = params.cursor.clone();
loop {
let mut page_params = params.clone();
page_params.cursor = cursor.clone();
let page = self.list_all_content_reports(&page_params).await?;
let items = page.items;
let was_empty = items.is_empty();
for item in items {
yield item;
}
match guard.advance(page.cursor, Some(page.has_more), was_empty) {
Some(next) => cursor = Some(next),
None => break,
}
}
}
}
/// List content reports for this tenant (admin+)
///
/// Moderation queue for the tenant that owns the reported content, newest first. Requires the
/// admin role — reports carry reporter free text and there is no moderation duty below admin.
///
/// `GET /api/v1/reports`
pub async fn list_content_reports(&self, params: &ListContentReportsParams) -> Result<models::ListContentReportsResponse> {
self.client
.request_json(Request {
method: Method::GET,
path: "/api/v1/reports".to_string(),
query: Some(params),
body: NO_BODY,
headers: Vec::new(),
idempotent: false,
})
.await
}
/// Stream every item returned by `listContentReports`, following the `cursor` cursor until the
/// server reports no further pages.
pub fn list_content_reports_all<'a>(&'a self, params: &'a ListContentReportsParams) -> impl Stream<Item = Result<models::ContentReport>> + 'a {
async_stream::try_stream! {
let mut guard = CursorGuard::new();
let mut cursor = params.cursor.clone();
loop {
let mut page_params = params.clone();
page_params.cursor = cursor.clone();
let page = self.list_content_reports(&page_params).await?;
let items = page.items;
let was_empty = items.is_empty();
for item in items {
yield item;
}
match guard.advance(page.cursor, Some(page.has_more), was_empty) {
Some(next) => cursor = Some(next),
None => break,
}
}
}
}
}