1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_json::{Value, json};
4use std::collections::HashMap;
5
6#[derive(Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct AQLResponse<T> {
9 pub aql: String,
10 pub executed_aql: String,
11 pub result_set: Vec<T>,
12 pub meta: serde_json::Value,
13}
14
15#[derive(Serialize, Debug)]
16#[serde(rename_all = "camelCase")]
17pub struct AQLQuery<'a> {
18 pub aql: &'a str,
19 pub aql_parameters: serde_json::Value,
20}
21
22#[derive(Serialize, Deserialize)]
23pub struct EhrDbEventTriggerAQLs {
24 pub aql: String,
25}
26
27#[derive(Serialize, Deserialize)]
28#[serde(rename_all = "camelCase")]
29pub struct EhrDbEventTrigger {
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub id: Option<i32>,
32 pub name: String,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub active: Option<bool>,
35 pub event_time_to_live_hours: i32,
36 pub repeat_interval_minutes: i32,
37 pub run_immediately: bool,
38 pub aqls: EhrDbEventTriggerAQLs,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 pub archetype_ids: Option<Vec<String>>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub template_ids: Option<Vec<String>>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub http_result_url: Option<String>,
45 pub population: bool,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub created: Option<String>,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub created_by: Option<String>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub updated: Option<String>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub updated_by: Option<String>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub kafka_result_topic: Option<String>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub kafka_servers: Option<String>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub parent_trigger_id: Option<i32>,
60}
61
62#[derive(Serialize, Deserialize)]
63#[serde(rename_all = "camelCase")]
64pub struct EhrDbView {
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub id: Option<i32>,
67 pub name: String,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub description: Option<String>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub import_export_name: Option<String>,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub js: Option<String>,
74 pub cacheable: bool,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub created: Option<String>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub created_by: Option<String>,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub updated: Option<String>,
81 #[serde(skip_serializing_if = "Option::is_none")]
82 pub updated_by: Option<String>,
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub parent_id: Option<i32>,
85}
86
87#[derive(Serialize, Deserialize)]
88#[serde(rename_all = "camelCase")]
89pub struct Composition {
90 #[serde(default)]
91 pub name: String,
92 pub template_id: String,
93 pub composition_uid: String,
94 pub composition: Value,
95 #[serde(default)]
96 pub tags: Option<Value>,
97 #[serde(default)]
98 pub deleted: bool,
99 #[serde(default)]
100 pub last_version: bool,
101 #[serde(default)]
102 pub ehr_id: Option<String>,
103 #[serde(default)]
104 pub lifecycle_state: Option<String>,
105}
106
107#[derive(Serialize, Deserialize)]
108#[serde(rename_all = "snake_case")]
109pub struct CompositionPreview {
110 pub uid: String,
111 pub name: String,
112 pub template_id: String,
113 pub start_time: DateTime<Utc>,
114 pub link: Option<String>,
115}
116
117#[derive(Serialize, Deserialize)]
118#[serde(rename_all = "camelCase")]
119pub struct TagsPayload {
120 pub composition_uid: String,
121 pub tags: Vec<Tag>,
122}
123
124#[derive(Serialize, Deserialize)]
125#[serde(rename_all = "camelCase")]
126pub struct EhrDbVersion {
127 pub build_time: DateTime<Utc>,
128 pub version: String,
129}
130
131#[derive(Serialize, Deserialize)]
132#[serde(rename_all = "camelCase")]
133pub struct Tag {
134 pub tag: String,
135 pub value: String,
136 pub aql_path: String,
137}
138
139impl Composition {
140 pub fn new(name: &str, template_id: &str) -> Self {
141 Self {
142 name: name.to_string(),
143 template_id: template_id.to_string(),
144 composition_uid: "".to_string(),
145 composition: json!({}), tags: None,
147 deleted: false,
148 last_version: true,
149 ehr_id: None,
150 lifecycle_state: Some("COMPLETE".to_string()),
151 }
152 }
153
154 pub fn add_content(&mut self, key: &str, value: &str) {
155 let mut json_obj = self.composition.clone();
156
157 let composed_key = format!("{}/{}", self.name, key);
159
160 json_obj[composed_key] = json!(value);
162
163 self.composition = json_obj;
165 }
166
167 pub fn add_content_from_string(&mut self, json_str: &str) {
168 let parsed: HashMap<String, String> = serde_json::from_str(json_str).unwrap();
169 for (key, value) in parsed.iter() {
170 self.add_content(key, value);
171 }
172 }
173
174 pub fn add_ctx(&mut self, key: &str, value: &str) {
175 let mut json_obj = self.composition.clone();
176 json_obj[key] = json!(value);
177 self.composition = json_obj;
178 }
179
180 pub fn add_ctx_from_string(&mut self, json_str: &str) {
181 let parsed: HashMap<String, String> = serde_json::from_str(json_str).unwrap();
182 for (key, value) in parsed.iter() {
183 self.add_ctx(key, value);
184 }
185 }
186}