Skip to main content

ave_common/bridge/
response.rs

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