//! 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;
