//! Domain Ontology Layer for Episteme //! //! This crate defines how subjects are structured based on predicate type and domain. //! It ensures conflicts collide correctly when different sources report on the same thing. //! //! # Key Concepts //! //! - **Domain**: A vertical (pharma, finance, etc.) with entity types, predicate schemas, and source hierarchy //! - **PredicateSchema**: Defines how subjects are built for a predicate type //! - **SubjectBuilder**: Constructs canonical subject strings from entities //! - **MedicalExtractor**: Trait for extracting claims from medical sources //! - **StemeClient**: HTTP client for submitting assertions to StemeDB //! //! # Subject Patterns //! //! Different predicate types require different subject structures: //! //! | Predicate Type | Subject Pattern | Example | //! |----------------|-----------------|---------| //! | Efficacy | `{Drug}:{Indication}` | `Semaglutide:Type2Diabetes` | //! | Safety | `{Drug}` | `Semaglutide` | //! | Mechanism | `{Drug}:{Pathway}` | `Semaglutide:GLP1Receptor` | //! //! This ensures that efficacy claims for the same drug+indication collide, //! while safety claims for the same drug collide regardless of indication. //! //! # Example //! //! ```ignore //! use stemedb_ontology::{pharma, SubjectBuilder}; //! //! let domain = pharma::definition(); //! let schema = domain.get_schema("efficacy").unwrap(); //! //! let mut entities = std::collections::HashMap::new(); //! entities.insert("Drug".to_string(), "Semaglutide".to_string()); //! entities.insert("Indication".to_string(), "Type2Diabetes".to_string()); //! //! let subject = SubjectBuilder::build(schema, &entities).unwrap(); //! assert_eq!(subject, "Semaglutide:Type2Diabetes"); //! ``` //! //! # StemeDB Integration //! //! ```ignore //! use stemedb_ontology::client::StemeClient; //! use stemedb_ontology::pharma::extractors::{FdaLabelExtractor, MedicalExtractor, SourceInput}; //! //! let client = StemeClient::new("http://localhost:18180"); //! let extractor = FdaLabelExtractor::new(); //! //! // Extract claims from FDA //! let claims = extractor.extract(&SourceInput::DrugName("semaglutide".into())).await?; //! //! // Submit to StemeDB //! for claim in claims { //! let assertion = claim.to_assertion(&signing_key, agent_id, &hlc); //! let hash = client.assert(&assertion).await?; //! } //! //! // Query for conflicts //! let skeptic = client.skeptic("Semaglutide:Type2Diabetes", "hba1c_change_percent").await?; //! ``` #![allow(clippy::print_stdout)] // CLI tool may use print pub mod client; pub mod domain; pub mod dto; pub mod pharma; pub mod subject; pub mod validator; pub use client::{ClientError, StemeClient}; pub use domain::{Domain, EntityType, PredicateSchema, SourceTier}; pub use subject::{SubjectBuilder, SubjectError}; pub use validator::{ValidationError, Validator}; // Re-export pharma domain for convenience pub use pharma::definition as pharma_domain;