use std::collections::HashMap;
use crate::intent_graph::{GraphMetadata, IntentGraph, Node, NodeId};
mod canonical_map;
mod edge;
pub mod extended;
mod meta;
mod metadata;
mod node;
pub use canonical_map::CanonicalMapBuilder;
pub use edge::EdgeBuilder;
pub use extended::{BugBuilder, ExtendedNodeBuilder, HypothesisBuilder, MetricBuilder, StoryBuilder};
pub use meta::MetaBuilder;
pub use metadata::GraphMetadataBuilder;
pub use node::NodeBuilder;
#[derive(Debug, Default)]
pub struct IntentGraphBuilder {
metadata: Option<GraphMetadata>,
nodes: Vec<Node>,
edges: Vec<crate::intent_graph::Edge>,
node_index: HashMap<NodeId, usize>,
}
impl IntentGraphBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn metadata(mut self, metadata: GraphMetadata) -> Self {
self.metadata = Some(metadata);
self
}
pub fn with_default_metadata(mut self) -> Self {
let now = chrono::Utc::now().to_rfc3339();
self.metadata = Some(GraphMetadata {
version: "1.0.0".to_string(),
schema_uri: "https://phenotype.dev/schemas/agileplus-intent-ontology/v1.json"
.to_string(),
created_at: now.clone(),
updated_at: Some(now),
node_count: None,
edge_count: None,
dag_valid: None,
source_system: Some("agileplus-rust".to_string()),
});
self
}
pub fn node(mut self, node: Node) -> Self {
self.node_index.insert(node.id.clone(), self.nodes.len());
self.nodes.push(node);
self
}
pub fn edge(mut self, edge: crate::intent_graph::Edge) -> Self {
self.edges.push(edge);
self
}
pub fn build(self) -> Result<IntentGraph, String> {
let mut graph = IntentGraph::new(
self.metadata
.ok_or_else(|| "GraphMetadata is required".to_string())?,
);
graph.nodes = self.nodes;
graph.edges = self.edges;
graph.update_counts();
Ok(graph)
}
}