ant_types/graph.rs
1//! Graph data model: Vertex, Edge, PropertyValue, SubGraph.
2
3use std::collections::BTreeMap;
4
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7
8use crate::evidence::EvidenceId;
9use crate::ids::{EdgeId, TypeName, VertexId};
10
11pub use crate::property::PropertyValue;
12
13/// A graph node: business id, display name, qualified type label,
14/// and typed properties. The payload of a `vertex` record.
15#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
16pub struct Vertex {
17 /// Business id, unique within the type (e.g. `deal_1`).
18 pub id: VertexId,
19 /// Human-readable display name.
20 pub name: String,
21 /// Namespace-qualified, e.g. "Antares.Deal".
22 pub label: TypeName,
23 /// Typed properties, keyed by property name.
24 pub properties: BTreeMap<String, PropertyValue>,
25}
26
27/// A directed, labeled edge between two vertices, with optional
28/// bitemporal validity. The payload of an `edge` record.
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub struct Edge {
31 /// Edge id, unique within the scope.
32 pub id: EdgeId,
33 /// Source vertex id.
34 pub src: VertexId,
35 /// Source vertex type.
36 pub src_type: TypeName,
37 /// Destination vertex id.
38 pub dst: VertexId,
39 /// Destination vertex type.
40 pub dst_type: TypeName,
41 /// Relation name (e.g. "hasStakeholder"), NOT namespace-qualified.
42 pub label: String,
43 /// Typed properties carried on the edge, keyed by property name.
44 pub properties: BTreeMap<String, PropertyValue>,
45
46 // --- Antares-native bitemporal annotations ---
47 //
48 // None on valid_from = valid from -infinity (always was).
49 // None on valid_to = still holds (no end).
50 // observed_at = wall-clock time the fact was recorded.
51 // extracted_at = wall-clock time the extractor produced it.
52 /// Start of real-world validity; `None` = always was.
53 #[serde(default, skip_serializing_if = "Option::is_none")]
54 pub valid_from: Option<DateTime<Utc>>,
55 /// End of real-world validity (exclusive); `None` = still holds.
56 #[serde(default, skip_serializing_if = "Option::is_none")]
57 pub valid_to: Option<DateTime<Utc>>,
58 /// Wall-clock time the fact was recorded.
59 #[serde(default, skip_serializing_if = "Option::is_none")]
60 pub observed_at: Option<DateTime<Utc>>,
61 /// Wall-clock time the extractor produced it.
62 #[serde(default, skip_serializing_if = "Option::is_none")]
63 pub extracted_at: Option<DateTime<Utc>>,
64
65 /// Confidence in `[0,1]` for the fact. `None` is treated as 1.0 for
66 /// matching purposes.
67 #[serde(default, skip_serializing_if = "Option::is_none")]
68 pub confidence: Option<f32>,
69
70 /// First-class evidence references. Empty by default
71 /// (backwards-compatible with older payloads).
72 #[serde(default, skip_serializing_if = "Vec::is_empty")]
73 pub evidenced_by: Vec<EvidenceId>,
74}
75
76impl Edge {
77 /// Returns true iff this edge is valid at the given instant.
78 ///
79 /// Edges with no `valid_from` are treated as valid from -infinity.
80 /// Edges with no `valid_to` are treated as still-holding.
81 pub fn valid_at(&self, t: DateTime<Utc>) -> bool {
82 match (self.valid_from, self.valid_to) {
83 (None, None) => true,
84 (Some(f), None) => t >= f,
85 (None, Some(u)) => t < u,
86 (Some(f), Some(u)) => t >= f && t < u,
87 }
88 }
89
90 /// Returns true iff this edge's validity interval overlaps `[t1, t2)`.
91 pub fn valid_between(&self, t1: DateTime<Utc>, t2: DateTime<Utc>) -> bool {
92 if t2 <= t1 {
93 return false;
94 }
95 let lo = self.valid_from.unwrap_or(DateTime::<Utc>::MIN_UTC);
96 let hi = self.valid_to.unwrap_or(DateTime::<Utc>::MAX_UTC);
97 lo < t2 && t1 < hi
98 }
99
100 /// True if the edge is currently active (valid_to is None).
101 pub fn still_holds(&self) -> bool {
102 self.valid_to.is_none()
103 }
104}
105
106/// A set of vertices and edges, as returned by queries or carried in
107/// bulk payloads.
108#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
109pub struct SubGraph {
110 /// The vertices.
111 pub nodes: Vec<Vertex>,
112 /// The edges.
113 pub edges: Vec<Edge>,
114}