reputation-core 0.1.0

Core calculation engine for the KnowThat Reputation System with advanced scoring algorithms
Documentation
//! Migration guide from Phase 1 to Phase 2
//! 
//! This example shows how to migrate existing code to use Phase 2 features
//! while maintaining backward compatibility.

use reputation_core::{Calculator, CalculatorPreset, BatchOptions};
use reputation_types::{AgentData, AgentDataBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== Phase 1 to Phase 2 Migration Guide ===\n");
    
    // Show that Phase 1 code still works
    println!("1. BACKWARD COMPATIBILITY");
    println!("-------------------------");
    phase1_code_still_works()?;
    
    // Enhanced features available in Phase 2
    println!("\n2. ENHANCED SCORE INFORMATION");
    println!("-----------------------------");
    enhanced_score_info()?;
    
    // New builder pattern
    println!("\n3. BUILDER PATTERN");
    println!("------------------");
    builder_pattern_migration()?;
    
    // Batch processing
    println!("\n4. BATCH PROCESSING");
    println!("-------------------");
    batch_processing_migration()?;
    
    // Utility methods
    println!("\n5. UTILITY METHODS");
    println!("------------------");
    utility_methods_new()?;
    
    Ok(())
}

fn phase1_code_still_works() -> Result<(), Box<dyn std::error::Error>> {
    println!("Phase 1 code continues to work unchanged:");
    
    // Original Phase 1 calculator creation
    let calculator = Calculator::new(15.0, 50.0, 80.0)?;
    
    // Original agent creation (using builder was already available)
    let agent = AgentDataBuilder::new("did:example:phase1")
        .with_reviews(50, 4.0)
        .total_interactions(100)
        .mcp_level(2)
        .build()?;
    
    // Original calculation
    let score = calculator.calculate(&agent)?;
    
    // Original fields still available
    println!("  Score: {:.1}", score.score);
    println!("  Confidence: {:.2}", score.confidence);
    println!("  Algorithm version: {}", score.algorithm_version);
    println!("  ✓ All Phase 1 code works!");
    
    Ok(())
}

fn enhanced_score_info() -> Result<(), Box<dyn std::error::Error>> {
    let calc = Calculator::default();
    let agent = create_test_agent()?;
    
    let score = calc.calculate(&agent)?;
    
    println!("Phase 1 fields (still available):");
    println!("  score: {:.1}", score.score);
    println!("  confidence: {:.2}", score.confidence);
    
    println!("\nNEW Phase 2 fields:");
    println!("  level: {:?}", score.level);
    println!("  is_provisional: {}", score.is_provisional);
    println!("  data_points: {}", score.data_points);
    
    println!("\nNEW detailed components:");
    println!("  components.prior_score: {:.1}", score.components.prior_score);
    println!("  components.empirical_score: {:.1}", score.components.empirical_score);
    println!("  components.confidence_level: {:?}", score.components.confidence_level);
    
    println!("\nNEW prior breakdown:");
    let breakdown = &score.components.prior_breakdown;
    println!("  base_score: {:.1}", breakdown.base_score);
    println!("  mcp_bonus: {:.1}", breakdown.mcp_bonus);
    println!("  identity_bonus: {:.1}", breakdown.identity_bonus);
    println!("  total: {:.1}", breakdown.total);
    
    Ok(())
}

fn builder_pattern_migration() -> Result<(), Box<dyn std::error::Error>> {
    println!("Phase 1 constructor:");
    println!("```rust");
    println!("let calc = Calculator::new(20.0, 50.0, 85.0)?;");
    println!("```");
    
    println!("\nPhase 2 builder pattern (more intuitive):");
    println!("```rust");
    println!("let calc = Calculator::builder()");
    println!("    .confidence_k(20.0)");
    println!("    .prior_base(50.0)");
    println!("    .prior_max(85.0)");
    println!("    .build()?;");
    println!("```");
    
    // Demonstrate actual usage
    let _calc = Calculator::builder()
        .confidence_k(20.0)
        .prior_base(50.0)
        .prior_max(85.0)
        .build()?;
    
    println!("\nUsing presets (NEW):");
    let conservative = Calculator::builder()
        .preset(CalculatorPreset::Conservative)
        .build()?;
    
    println!("  Conservative k: {}", conservative.confidence_k());
    
    // Partial configuration
    let custom = Calculator::builder()
        .preset(CalculatorPreset::Testing)
        .prior_base(55.0)  // Override just one value
        .build()?;
    
    println!("  Testing preset with custom base: k={}, base={}", 
        custom.confidence_k(), custom.prior_base());
    
    Ok(())
}

fn batch_processing_migration() -> Result<(), Box<dyn std::error::Error>> {
    let calc = Calculator::default();
    let agents = vec![
        create_test_agent()?,
        create_test_agent()?,
        create_test_agent()?,
    ];
    
    println!("Phase 1 (sequential processing):");
    println!("```rust");
    println!("let mut scores = Vec::new();");
    println!("for agent in agents {{");
    println!("    scores.push(calculator.calculate(&agent)?);");
    println!("}}");
    println!("```");
    
    println!("\nPhase 2 (parallel batch processing):");
    println!("```rust");
    println!("let scores = calculator.calculate_batch(&agents);");
    println!("```");
    
    // Simple batch
    let results = calc.calculate_batch(&agents);
    println!("\nSimple batch results: {} successful", 
        results.iter().filter(|r| r.is_ok()).count());
    
    // Advanced batch with options
    println!("\nAdvanced batch processing (NEW):");
    let options = BatchOptions {
        chunk_size: Some(10),
        fail_fast: false,
        progress_callback: Some(Box::new(|completed, total| {
            println!("  Progress: {}/{}", completed, total);
        })),
    };
    
    let batch_result = calc.calculate_batch_with_options(&agents, options);
    println!("  Duration: {:?}", batch_result.total_duration);
    println!("  Success rate: {}/{}", 
        batch_result.successful_count, 
        batch_result.calculations.len());
    
    Ok(())
}

fn utility_methods_new() -> Result<(), Box<dyn std::error::Error>> {
    let calc = Calculator::default();
    let agent = create_test_agent()?;
    
    println!("NEW utility methods in Phase 2:");
    
    // 1. Score explanation
    println!("\n1. explain_score() - Human-readable breakdown:");
    let explanation = calc.explain_score(&agent)?;
    println!("{}", explanation.explanation);
    
    // 2. Confidence planning
    println!("\n2. interactions_for_confidence() - Planning tool:");
    let needed = calc.interactions_for_confidence(
        agent.total_interactions, 
        0.9
    )?;
    println!("  Need {} more interactions for 90% confidence", needed);
    
    // 3. Score prediction
    println!("\n3. predict_score_change() - What-if analysis:");
    let prediction = calc.predict_score_change(&agent, 50, 4.5)?;
    println!("  Adding 50 reviews at 4.5★ would change score by {:+.1} points", 
        prediction.score_change);
    
    // 4. Agent comparison
    println!("\n4. compare_agents() - Side-by-side analysis:");
    let other_agent = AgentDataBuilder::new("did:example:other")
        .with_reviews(200, 3.8)
        .total_interactions(250)
        .build()?;
    
    let comparison = calc.compare_agents(&agent, &other_agent)?;
    println!("  Score difference: {:+.1}", comparison.score_difference);
    println!("  More reliable: {}", comparison.more_reliable_agent);
    
    Ok(())
}

fn create_test_agent() -> Result<AgentData, Box<dyn std::error::Error>> {
    Ok(AgentDataBuilder::new("did:example:test")
        .with_reviews(50, 4.2)
        .total_interactions(75)
        .mcp_level(1)
        .identity_verified(true)
        .build()?)
}