Skip to main content

relay_knowledge/domain/business/
projection.rs

1use serde::{Deserialize, Serialize};
2
3use crate::domain::{FactStatus, GraphVersion};
4
5use super::{
6    BusinessAlias, BusinessSemantics, BusinessTechnicalMappingDefinition, BusinessTermStatus,
7    OntologyIdentity, TechnicalTargetKind,
8};
9
10/// One route-authorized authored glossary loaded from an immutable repository snapshot.
11#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12pub struct BusinessKnowledgeSource {
13    pub source_id: String,
14    pub source_path: String,
15    pub authority_rank: usize,
16    pub content_digest: String,
17    pub glossary: super::BusinessGlossary,
18}
19
20/// Prepared projection input written by the repository index writer.
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
22pub struct BusinessKnowledgeProjectionInput {
23    pub repository_id: String,
24    pub source_scope: String,
25    pub resolved_commit_sha: String,
26    pub sources: Vec<BusinessKnowledgeSource>,
27}
28
29/// Provenance retained for every accepted authored business fact.
30#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
31pub struct BusinessEvidence {
32    pub evidence_id: String,
33    pub source_id: String,
34    pub source_path: String,
35    pub source_digest: String,
36    pub resolved_commit_sha: String,
37    pub line_start: u32,
38    pub line_end: u32,
39    pub confidence_basis_points: u16,
40    pub lifecycle: FactStatus,
41    pub valid_from_graph_version: GraphVersion,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub valid_until_graph_version: Option<GraphVersion>,
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
47pub struct BusinessDefinitionFact {
48    pub definition: String,
49    pub preferred: bool,
50    pub evidence: BusinessEvidence,
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
54pub struct BusinessKnowledgeConflict {
55    pub predicate: String,
56    pub competing_values: Vec<String>,
57    pub evidence_ids: Vec<String>,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
61pub struct BusinessDomain {
62    pub identity: OntologyIdentity,
63    pub entity_id: String,
64    pub id: String,
65    pub name: String,
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub description: Option<String>,
68    pub evidence: BusinessEvidence,
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
72pub struct BusinessTechnicalMapping {
73    #[serde(flatten)]
74    pub definition: BusinessTechnicalMappingDefinition,
75    pub resolution_state: String,
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub resolved_id: Option<String>,
78    pub target_hint: String,
79    pub evidence: BusinessEvidence,
80}
81
82impl BusinessTechnicalMapping {
83    pub fn is_resolved(&self) -> bool {
84        self.resolution_state == "resolved" && self.resolved_id.is_some()
85    }
86
87    pub fn query_seed(&self) -> &str {
88        self.resolved_id
89            .as_deref()
90            .unwrap_or(self.target_hint.as_str())
91    }
92
93    pub fn target_kind(&self) -> TechnicalTargetKind {
94        self.definition.target_kind
95    }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
99pub struct BusinessTerm {
100    pub identity: OntologyIdentity,
101    pub entity_id: String,
102    pub id: String,
103    pub domain_id: String,
104    pub canonical_name: String,
105    pub language: String,
106    pub status: BusinessTermStatus,
107    pub definitions: Vec<BusinessDefinitionFact>,
108    pub aliases: Vec<BusinessAlias>,
109    #[serde(default, skip_serializing_if = "Vec::is_empty")]
110    pub semantics: Vec<BusinessSemantics>,
111    pub conflicts: Vec<BusinessKnowledgeConflict>,
112    pub mappings: Vec<BusinessTechnicalMapping>,
113}
114
115/// Projection freshness and bounded cardinality summary.
116#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
117pub struct BusinessKnowledgeStatus {
118    pub repository_id: String,
119    pub source_scope: String,
120    pub resolved_commit_sha: String,
121    pub projected_graph_version: GraphVersion,
122    pub stale: bool,
123    pub source_count: usize,
124    pub domain_count: usize,
125    pub term_count: usize,
126    pub mapping_count: usize,
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub last_error: Option<String>,
129}
130
131/// Storage projection before API metadata and repository scope are attached.
132#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
133pub struct BusinessKnowledgeProjection {
134    pub status: BusinessKnowledgeStatus,
135    pub resolution: super::BusinessKnowledgeResolution,
136    pub domains: Vec<BusinessDomain>,
137    pub terms: Vec<BusinessTerm>,
138}