Skip to main content

ave_common/bridge/
response.rs

1//! Response payloads returned by the Ave API.
2
3use crate::{
4    SchemaType,
5    bridge::request::{ApprovalState, EventRequestType},
6};
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9use std::{collections::HashMap, fmt::Display};
10
11#[cfg(feature = "openapi")]
12use utoipa::ToSchema;
13
14#[cfg(feature = "typescript")]
15use ts_rs::TS;
16
17/// Approval entry with request data and current state.
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[cfg_attr(feature = "openapi", derive(ToSchema))]
20#[cfg_attr(feature = "typescript", derive(TS))]
21#[cfg_attr(feature = "typescript", ts(export))]
22pub struct ApprovalEntry {
23    /// The approval request details
24    pub request: ApprovalReq,
25    /// Current state of the approval
26    pub state: ApprovalState,
27}
28
29#[derive(
30    Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd,
31)]
32#[cfg_attr(feature = "openapi", derive(ToSchema))]
33#[cfg_attr(feature = "typescript", derive(TS))]
34#[cfg_attr(feature = "typescript", ts(export))]
35pub struct SubjsData {
36    pub subject_id: String,
37    pub schema_id: SchemaType,
38    pub active: bool,
39    pub namespace: String,
40    pub name: Option<String>,
41    pub description: Option<String>,
42}
43
44#[derive(Clone, Debug, Serialize, Deserialize)]
45#[cfg_attr(feature = "openapi", derive(ToSchema))]
46#[cfg_attr(feature = "typescript", derive(TS))]
47#[cfg_attr(feature = "typescript", ts(export))]
48pub struct GovsData {
49    pub governance_id: String,
50    pub active: bool,
51    pub name: Option<String>,
52    pub description: Option<String>,
53}
54
55#[derive(Clone, Debug, Serialize, Deserialize)]
56#[cfg_attr(feature = "openapi", derive(ToSchema))]
57#[cfg_attr(feature = "typescript", derive(TS))]
58#[cfg_attr(feature = "typescript", ts(export))]
59pub struct TransferSubject {
60    pub name: Option<String>,
61    pub subject_id: String,
62    pub new_owner: String,
63    pub actual_owner: String,
64}
65
66#[derive(Clone, Debug, Serialize, Deserialize)]
67#[cfg_attr(feature = "openapi", derive(ToSchema))]
68#[cfg_attr(feature = "typescript", derive(TS))]
69#[cfg_attr(feature = "typescript", ts(export))]
70pub struct ApprovalReq {
71    /// The signed event request.
72    pub subject_id: String,
73    /// The sequence number of the event.
74    pub sn: u64,
75    /// The version of the governance contract.
76    pub gov_version: u64,
77    /// The patch to apply to the state.
78    pub patch: Value,
79
80    pub signer: String,
81}
82
83/// Network status exposed by monitoring endpoints.
84#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
85#[cfg_attr(feature = "openapi", derive(ToSchema))]
86#[cfg_attr(feature = "typescript", derive(TS))]
87#[cfg_attr(feature = "typescript", ts(export))]
88pub enum MonitorNetworkState {
89    /// Connecting to others network nodes
90    #[default]
91    Connecting,
92    /// Connected to others netowrk nodes
93    Running,
94    /// Can not connect to others network nodes
95    Down,
96}
97
98#[derive(Clone, Debug, Serialize, Deserialize)]
99#[cfg_attr(feature = "openapi", derive(ToSchema))]
100#[cfg_attr(feature = "typescript", derive(TS))]
101#[cfg_attr(feature = "typescript", ts(export))]
102pub struct LedgerDB {
103    pub subject_id: String,
104    pub sn: u64,
105    pub event_request_timestamp: u64,
106    pub event_ledger_timestamp: u64,
107    pub sink_timestamp: u64,
108    pub event: RequestEventDB,
109    pub event_type: EventRequestType,
110}
111
112#[derive(Clone, Debug, Serialize, Deserialize)]
113#[cfg_attr(feature = "openapi", derive(ToSchema))]
114#[cfg_attr(feature = "typescript", derive(TS))]
115#[cfg_attr(feature = "typescript", ts(export))]
116pub struct RequestsInManager {
117    pub handling: HashMap<String, String>,
118    pub in_queue: HashMap<String, Vec<String>>,
119}
120
121#[derive(Clone, Debug, Serialize, Deserialize)]
122#[cfg_attr(feature = "openapi", derive(ToSchema))]
123#[cfg_attr(feature = "typescript", derive(TS))]
124#[cfg_attr(feature = "typescript", ts(export))]
125pub struct RequestsInManagerSubject {
126    pub handling: Option<String>,
127    pub in_queue: Option<Vec<String>>,
128}
129
130#[derive(Clone, Debug, Serialize, Deserialize)]
131#[cfg_attr(feature = "openapi", derive(ToSchema))]
132#[cfg_attr(feature = "typescript", derive(TS))]
133#[cfg_attr(feature = "typescript", ts(export))]
134pub struct AbortDB {
135    pub request_id: String,
136    pub subject_id: String,
137    pub sn: Option<u64>,
138    pub error: String,
139    pub who: String,
140    pub abort_type: String,
141}
142
143#[derive(Clone, Debug, Serialize, Deserialize)]
144#[cfg_attr(feature = "openapi", derive(ToSchema))]
145#[cfg_attr(feature = "typescript", derive(TS))]
146#[cfg_attr(feature = "typescript", ts(export))]
147#[serde(tag = "event", content = "data", rename_all = "snake_case")]
148pub enum RequestEventDB {
149    Create {
150        name: Option<String>,
151        description: Option<String>,
152        schema_id: String,
153        namespace: String,
154    },
155    TrackerFact {
156        payload: Value,
157        evaluation_response: EvalResDB,
158    },
159    GovernanceFact {
160        payload: Value,
161        evaluation_response: EvalResDB,
162        approval_success: Option<bool>,
163    },
164    Transfer {
165        evaluation_error: Option<String>,
166        new_owner: String,
167    },
168    TrackerConfirm,
169    GovernanceConfirm {
170        name_old_owner: Option<String>,
171        evaluation_response: EvalResDB,
172    },
173    Reject,
174    EOL,
175}
176
177impl RequestEventDB {
178    pub const fn get_event_type(&self) -> EventRequestType {
179        match self {
180            Self::Create { .. } => EventRequestType::Create,
181            Self::TrackerFact { .. } | Self::GovernanceFact { .. } => {
182                EventRequestType::Fact
183            }
184            Self::Transfer { .. } => EventRequestType::Transfer,
185            Self::TrackerConfirm | Self::GovernanceConfirm { .. } => {
186                EventRequestType::Confirm
187            }
188            Self::Reject => EventRequestType::Reject,
189            Self::EOL => EventRequestType::Eol,
190        }
191    }
192}
193
194#[derive(Clone, Debug, Serialize, Deserialize)]
195#[cfg_attr(feature = "openapi", derive(ToSchema))]
196#[cfg_attr(feature = "typescript", derive(TS))]
197#[cfg_attr(feature = "typescript", ts(export))]
198pub enum EvalResDB {
199    Patch(Value),
200    Error(String),
201}
202
203#[derive(Clone, Debug, Serialize, Deserialize)]
204#[cfg_attr(feature = "openapi", derive(ToSchema))]
205#[cfg_attr(feature = "typescript", derive(TS))]
206#[cfg_attr(feature = "typescript", ts(export))]
207pub struct SubjectDB {
208    pub name: Option<String>,
209    pub description: Option<String>,
210    pub subject_id: String,
211    pub governance_id: String,
212    pub genesis_gov_version: u64,
213    pub prev_ledger_event_hash: Option<String>,
214    pub schema_id: String,
215    pub namespace: String,
216    pub sn: u64,
217    pub creator: String,
218    pub owner: String,
219    pub new_owner: Option<String>,
220    pub active: bool,
221    pub properties: Value,
222}
223
224#[derive(Clone, Debug, Serialize, Deserialize)]
225#[cfg_attr(feature = "openapi", derive(ToSchema))]
226#[cfg_attr(feature = "typescript", derive(TS))]
227#[cfg_attr(feature = "typescript", ts(export))]
228pub struct PaginatorEvents {
229    pub paginator: Paginator,
230    pub events: Vec<LedgerDB>,
231}
232
233#[derive(Clone, Debug, Serialize, Deserialize)]
234#[cfg_attr(feature = "openapi", derive(ToSchema))]
235#[cfg_attr(feature = "typescript", derive(TS))]
236#[cfg_attr(feature = "typescript", ts(export))]
237pub struct PaginatorAborts {
238    pub paginator: Paginator,
239    pub events: Vec<AbortDB>,
240}
241
242#[derive(Clone, Debug, Serialize, Deserialize)]
243#[cfg_attr(feature = "openapi", derive(ToSchema))]
244#[cfg_attr(feature = "typescript", derive(TS))]
245#[cfg_attr(feature = "typescript", ts(export))]
246pub struct Paginator {
247    pub pages: u64,
248    pub next: Option<u64>,
249    pub prev: Option<u64>,
250}
251
252#[derive(Clone, Debug, Serialize, Deserialize)]
253#[cfg_attr(feature = "openapi", derive(ToSchema))]
254#[cfg_attr(feature = "typescript", derive(TS))]
255#[cfg_attr(feature = "typescript", ts(export))]
256pub struct RequestInfo {
257    pub state: RequestState,
258    pub version: u64,
259}
260
261#[derive(Clone, Debug, Serialize, Deserialize)]
262#[cfg_attr(feature = "openapi", derive(ToSchema))]
263#[cfg_attr(feature = "typescript", derive(TS))]
264#[cfg_attr(feature = "typescript", ts(export))]
265pub struct RequestInfoExtend {
266    pub request_id: String,
267    pub state: RequestState,
268    pub version: u64,
269}
270
271#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
272#[cfg_attr(feature = "openapi", derive(ToSchema))]
273#[cfg_attr(feature = "typescript", derive(TS))]
274#[cfg_attr(feature = "typescript", ts(export))]
275pub enum RequestState {
276    // Handler
277    InQueue,
278    Handling,
279    Invalid {
280        subject_id: String,
281        who: String,
282        sn: Option<u64>,
283        error: String,
284    },
285    // Manager
286    Abort {
287        subject_id: String,
288        who: String,
289        sn: Option<u64>,
290        error: String,
291    },
292    Reboot,
293    RebootDiff {
294        seconds: u64,
295        count: u64,
296    },
297    RebootTimeOut {
298        seconds: u64,
299        count: u64,
300    },
301    Evaluation,
302    Approval,
303    Validation,
304    Distribution,
305    Finish,
306}
307
308impl Display for RequestState {
309    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
310        match self {
311            Self::Handling => write!(f, "Handling"),
312            Self::Abort {
313                subject_id,
314                who,
315                sn,
316                error,
317            } => {
318                let sn_text = sn
319                    .as_ref()
320                    .map_or_else(|| "None".to_string(), |sn| format!("{sn}"));
321
322                write!(
323                    f,
324                    "Abort, subject_id: {}, who: {}, sn: {}, error: {}",
325                    subject_id, who, sn_text, error
326                )
327            }
328            Self::InQueue => write!(f, "In Queue"),
329            Self::Invalid {
330                subject_id,
331                who,
332                sn,
333                error,
334            } => {
335                let sn_text = sn
336                    .as_ref()
337                    .map_or_else(|| "None".to_string(), |sn| format!("{sn}"));
338
339                write!(
340                    f,
341                    "Abort, subject_id: {}, who: {}, sn: {}, error: {}",
342                    subject_id, who, sn_text, error
343                )
344            }
345            Self::Finish => write!(f, "Finish"),
346            Self::Reboot => write!(f, "Reboot"),
347            Self::RebootDiff { seconds, count } => {
348                write!(f, "Reboot diff, try: {}, seconds: {}", count, seconds)
349            }
350            Self::RebootTimeOut { seconds, count } => write!(
351                f,
352                "Reboot timeout, try: {}, seconds: {}",
353                count, seconds
354            ),
355            Self::Evaluation => write!(f, "Evaluation"),
356            Self::Approval => write!(f, "Approval"),
357            Self::Validation => write!(f, "Validation"),
358            Self::Distribution => write!(f, "Distribution"),
359        }
360    }
361}
362
363#[derive(Debug, Clone, Serialize, Deserialize)]
364#[cfg_attr(feature = "openapi", derive(ToSchema))]
365#[cfg_attr(feature = "typescript", derive(TS))]
366#[cfg_attr(feature = "typescript", ts(export))]
367pub struct RequestData {
368    pub request_id: String,
369    pub subject_id: String,
370}
371
372/// Time range filter for querying events by timestamp.
373/// Both `from` and `to` are optional and should be ISO 8601 strings (e.g., "2024-01-15T14:30:00Z").
374#[derive(Clone, Debug, Default, Serialize, Deserialize)]
375#[cfg_attr(feature = "openapi", derive(ToSchema))]
376#[cfg_attr(feature = "typescript", derive(TS))]
377#[cfg_attr(feature = "typescript", ts(export))]
378pub struct TimeRange {
379    /// Start of the range (inclusive). ISO 8601 format.
380    pub from: Option<String>,
381    /// End of the range (inclusive). ISO 8601 format.
382    pub to: Option<String>,
383}