1use super::cads::CADSKind;
6use super::enums::InfrastructureType;
7use super::table::{ContactDetails, SlaProperty};
8use chrono::{DateTime, Utc};
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11use uuid::Uuid;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
15#[serde(rename_all = "PascalCase")]
16pub enum CrowsfeetCardinality {
17 OneToOne,
19 OneToMany,
21 ZeroOrOne,
23 ZeroOrMany,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
32pub struct System {
33 pub id: Uuid,
35 pub name: String,
37 pub infrastructure_type: InfrastructureType,
39 pub domain_id: Uuid,
41 #[serde(skip_serializing_if = "Option::is_none")]
43 pub description: Option<String>,
44 #[serde(default)]
46 pub endpoints: Vec<String>,
47 #[serde(skip_serializing_if = "Option::is_none")]
49 pub owner: Option<String>,
50 #[serde(skip_serializing_if = "Option::is_none")]
52 pub sla: Option<Vec<SlaProperty>>,
53 #[serde(skip_serializing_if = "Option::is_none")]
55 pub contact_details: Option<ContactDetails>,
56 #[serde(skip_serializing_if = "Option::is_none")]
58 pub notes: Option<String>,
59 #[serde(skip_serializing_if = "Option::is_none")]
61 pub version: Option<String>,
62 #[serde(default)]
64 pub metadata: HashMap<String, serde_json::Value>,
65 #[serde(skip_serializing_if = "Option::is_none")]
67 pub created_at: Option<DateTime<Utc>>,
68 #[serde(skip_serializing_if = "Option::is_none")]
70 pub updated_at: Option<DateTime<Utc>>,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
77pub struct SystemConnection {
78 pub id: Uuid,
80 pub source_system_id: Uuid,
82 pub target_system_id: Uuid,
84 pub connection_type: String,
86 #[serde(default)]
88 pub bidirectional: bool,
89 #[serde(default)]
91 pub metadata: HashMap<String, serde_json::Value>,
92 #[serde(skip_serializing_if = "Option::is_none")]
94 pub created_at: Option<DateTime<Utc>>,
95 #[serde(skip_serializing_if = "Option::is_none")]
97 pub updated_at: Option<DateTime<Utc>>,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
104pub struct SharedNodeReference {
105 pub domain_id: Uuid,
107 pub node_id: Uuid,
109 pub node_version: String,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
117pub struct CADSNode {
118 pub id: Uuid,
120 pub system_id: Uuid,
122 #[serde(skip_serializing_if = "Option::is_none")]
124 pub cads_asset_id: Option<Uuid>,
125 pub kind: CADSKind,
127 #[serde(skip_serializing_if = "Option::is_none")]
129 pub shared_reference: Option<SharedNodeReference>,
130 #[serde(default)]
132 pub custom_metadata: Vec<HashMap<String, serde_json::Value>>,
133 #[serde(skip_serializing_if = "Option::is_none")]
135 pub created_at: Option<DateTime<Utc>>,
136 #[serde(skip_serializing_if = "Option::is_none")]
138 pub updated_at: Option<DateTime<Utc>>,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
145pub struct ODCSNode {
146 pub id: Uuid,
148 pub system_id: Uuid,
150 #[serde(skip_serializing_if = "Option::is_none")]
152 pub table_id: Option<Uuid>,
153 pub role: String,
155 #[serde(skip_serializing_if = "Option::is_none")]
157 pub shared_reference: Option<SharedNodeReference>,
158 #[serde(default)]
160 pub custom_metadata: Vec<HashMap<String, serde_json::Value>>,
161 #[serde(skip_serializing_if = "Option::is_none")]
163 pub created_at: Option<DateTime<Utc>>,
164 #[serde(skip_serializing_if = "Option::is_none")]
166 pub updated_at: Option<DateTime<Utc>>,
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
173pub struct NodeConnection {
174 pub id: Uuid,
176 pub source_node_id: Uuid,
178 pub target_node_id: Uuid,
180 pub cardinality: CrowsfeetCardinality,
182 pub relationship_type: String,
184 #[serde(default)]
186 pub metadata: HashMap<String, serde_json::Value>,
187 #[serde(skip_serializing_if = "Option::is_none")]
189 pub created_at: Option<DateTime<Utc>>,
190 #[serde(skip_serializing_if = "Option::is_none")]
192 pub updated_at: Option<DateTime<Utc>>,
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
199pub struct Domain {
200 pub id: Uuid,
202 pub name: String,
204 #[serde(skip_serializing_if = "Option::is_none")]
206 pub description: Option<String>,
207 #[serde(default)]
209 pub systems: Vec<System>,
210 #[serde(default)]
212 pub cads_nodes: Vec<CADSNode>,
213 #[serde(default)]
215 pub odcs_nodes: Vec<ODCSNode>,
216 #[serde(default)]
218 pub system_connections: Vec<SystemConnection>,
219 #[serde(default)]
221 pub node_connections: Vec<NodeConnection>,
222 #[serde(skip_serializing_if = "Option::is_none")]
224 pub created_at: Option<DateTime<Utc>>,
225 #[serde(skip_serializing_if = "Option::is_none")]
227 pub updated_at: Option<DateTime<Utc>>,
228}
229
230impl Domain {
231 pub fn new(name: String) -> Self {
233 Self {
234 id: Uuid::new_v4(),
235 name,
236 description: None,
237 systems: Vec::new(),
238 cads_nodes: Vec::new(),
239 odcs_nodes: Vec::new(),
240 system_connections: Vec::new(),
241 node_connections: Vec::new(),
242 created_at: Some(chrono::Utc::now()),
243 updated_at: Some(chrono::Utc::now()),
244 }
245 }
246
247 pub fn add_system(&mut self, mut system: System) {
249 system.domain_id = self.id;
250 system.created_at = Some(chrono::Utc::now());
251 system.updated_at = Some(chrono::Utc::now());
252 self.systems.push(system);
253 self.updated_at = Some(chrono::Utc::now());
254 }
255
256 pub fn add_cads_node(&mut self, mut node: CADSNode) {
258 node.created_at = Some(chrono::Utc::now());
259 node.updated_at = Some(chrono::Utc::now());
260 self.cads_nodes.push(node);
261 self.updated_at = Some(chrono::Utc::now());
262 }
263
264 pub fn add_odcs_node(&mut self, mut node: ODCSNode) {
266 node.created_at = Some(chrono::Utc::now());
267 node.updated_at = Some(chrono::Utc::now());
268 self.odcs_nodes.push(node);
269 self.updated_at = Some(chrono::Utc::now());
270 }
271
272 pub fn add_system_connection(&mut self, mut connection: SystemConnection) {
274 connection.created_at = Some(chrono::Utc::now());
275 connection.updated_at = Some(chrono::Utc::now());
276 self.system_connections.push(connection);
277 self.updated_at = Some(chrono::Utc::now());
278 }
279
280 pub fn add_node_connection(&mut self, mut connection: NodeConnection) {
282 connection.created_at = Some(chrono::Utc::now());
283 connection.updated_at = Some(chrono::Utc::now());
284 self.node_connections.push(connection);
285 self.updated_at = Some(chrono::Utc::now());
286 }
287
288 pub fn from_yaml(yaml_content: &str) -> Result<Self, serde_yaml::Error> {
290 serde_yaml::from_str(yaml_content)
291 }
292
293 pub fn to_yaml(&self) -> Result<String, serde_yaml::Error> {
295 serde_yaml::to_string(self)
296 }
297}
298
299impl System {
300 pub fn new(name: String, infrastructure_type: InfrastructureType, domain_id: Uuid) -> Self {
302 Self {
303 id: Uuid::new_v4(),
304 name,
305 infrastructure_type,
306 domain_id,
307 description: None,
308 endpoints: Vec::new(),
309 owner: None,
310 sla: None,
311 contact_details: None,
312 notes: None,
313 version: None,
314 metadata: HashMap::new(),
315 created_at: Some(chrono::Utc::now()),
316 updated_at: Some(chrono::Utc::now()),
317 }
318 }
319}
320
321impl CADSNode {
322 pub fn new_local(system_id: Uuid, cads_asset_id: Uuid, kind: CADSKind) -> Self {
324 Self {
325 id: Uuid::new_v4(),
326 system_id,
327 cads_asset_id: Some(cads_asset_id),
328 kind,
329 shared_reference: None,
330 custom_metadata: Vec::new(),
331 created_at: Some(chrono::Utc::now()),
332 updated_at: Some(chrono::Utc::now()),
333 }
334 }
335
336 pub fn new_shared(
338 system_id: Uuid,
339 kind: CADSKind,
340 shared_reference: SharedNodeReference,
341 ) -> Self {
342 Self {
343 id: Uuid::new_v4(),
344 system_id,
345 cads_asset_id: None,
346 kind,
347 shared_reference: Some(shared_reference),
348 custom_metadata: Vec::new(),
349 created_at: Some(chrono::Utc::now()),
350 updated_at: Some(chrono::Utc::now()),
351 }
352 }
353}
354
355impl ODCSNode {
356 pub fn new_local(system_id: Uuid, table_id: Uuid, role: String) -> Self {
358 Self {
359 id: Uuid::new_v4(),
360 system_id,
361 table_id: Some(table_id),
362 role,
363 shared_reference: None,
364 custom_metadata: Vec::new(),
365 created_at: Some(chrono::Utc::now()),
366 updated_at: Some(chrono::Utc::now()),
367 }
368 }
369
370 pub fn new_shared(
372 system_id: Uuid,
373 role: String,
374 shared_reference: SharedNodeReference,
375 ) -> Self {
376 Self {
377 id: Uuid::new_v4(),
378 system_id,
379 table_id: None,
380 role,
381 shared_reference: Some(shared_reference),
382 custom_metadata: Vec::new(),
383 created_at: Some(chrono::Utc::now()),
384 updated_at: Some(chrono::Utc::now()),
385 }
386 }
387}