use heromodels::db::{Collection, Db}; use heromodels::models::flow::flow::flow_index::flow_uuid as flow_uuid_idx; use heromodels::models::flow::flow_step::flow_step_index::flow_id as flow_step_flow_id_idx; use heromodels::models::flow::{Flow, FlowStep, SignatureRequirement}; use heromodels_core::Model; // In a real application, you'd use the uuid crate for generating UUIDs: // use uuid::Uuid; fn main() { // Create a new DB instance in /tmp/ourdb_flowbroker, and reset before every run let db = heromodels::db::hero::OurDB::new("/tmp/ourdb_flowbroker", true).expect("Can create DB"); println!("Hero Models - Flow Example"); println!("==========================="); // --- Create a Flow --- // In a real app: let new_flow_uuid = Uuid::new_v4().to_string(); let new_flow_uuid = "a1b2c3d4-e5f6-7890-1234-567890abcdef"; // Example UUID let flow1 = Flow::new( 1, // id new_flow_uuid, // flow_uuid "Document Approval Flow", // name "Pending", // status ); db.collection() .expect("can open flow collection") .set(&flow1) .expect("can set flow1"); println!("Created Flow: {:?}", flow1); println!("Flow ID: {}", flow1.get_id()); println!("Flow DB Prefix: {}", Flow::db_prefix()); // --- Create FlowSteps for Flow1 --- let step1_flow1 = FlowStep::new( 101, // id flow1.get_id(), // flow_id 1, // step_order "Pending", // status ) .description("Initial review by manager"); db.collection() .expect("can open flow_step collection") .set(&step1_flow1) .expect("can set step1_flow1"); println!("Created FlowStep: {:?}", step1_flow1); let step2_flow1 = FlowStep::new( 102, // id flow1.get_id(), // flow_id 2, // step_order "Pending", // status ) .description("Legal team sign-off"); db.collection() .expect("can open flow_step collection") .set(&step2_flow1) .expect("can set step2_flow1"); println!("Created FlowStep: {:?}", step2_flow1); // --- Create SignatureRequirements for step2_flow1 --- let sig_req1_step2 = SignatureRequirement::new( 201, // id step2_flow1.get_id(), // flow_step_id "pubkey_legal_team_lead_hex", // public_key "I approve this document for legal compliance.", // message "Pending", // status ); db.collection() .expect("can open sig_req collection") .set(&sig_req1_step2) .expect("can set sig_req1_step2"); println!("Created SignatureRequirement: {:?}", sig_req1_step2); let sig_req2_step2 = SignatureRequirement::new( 202, // id step2_flow1.get_id(), // flow_step_id "pubkey_general_counsel_hex", // public_key "I, as General Counsel, approve this document.", // message "Pending", // status ); db.collection() .expect("can open sig_req collection") .set(&sig_req2_step2) .expect("can set sig_req2_step2"); println!("Created SignatureRequirement: {:?}", sig_req2_step2); // --- Retrieve and Verify --- // Get Flow by ID let retrieved_flow = db .collection::() .expect("can open flow collection") .get_by_id(flow1.get_id()) .expect("can load stored flow") .unwrap(); assert_eq!(retrieved_flow.name, flow1.name); assert_eq!(retrieved_flow.flow_uuid, flow1.flow_uuid); println!("\nRetrieved Flow by ID: {:?}", retrieved_flow); // Get Flow by flow_uuid (indexed lookup) let flows_by_uuid = db .collection::() .expect("can open flow collection") .get::(new_flow_uuid) .expect("can load flows by uuid"); assert_eq!(flows_by_uuid.len(), 1); assert_eq!(flows_by_uuid[0].name, flow1.name); println!("Retrieved Flow by UUID (index): {:?}", flows_by_uuid[0]); // Get FlowSteps for the retrieved_flow let steps_for_flow1 = db .collection::() .expect("can open flow_step collection") .get::(&retrieved_flow.get_id()) .expect("can load steps for flow1"); assert_eq!(steps_for_flow1.len(), 2); println!( "Retrieved {} FlowSteps for Flow ID {}:", steps_for_flow1.len(), retrieved_flow.get_id() ); for step in &steps_for_flow1 { println!( " - Step ID: {}, Order: {}, Desc: {:?}", step.get_id(), step.step_order, step.description ); } // --- Update a SignatureRequirement (simulate signing) --- let mut retrieved_sig_req1 = db .collection::() .expect("can open sig_req collection") .get_by_id(sig_req1_step2.get_id()) .expect("can load sig_req1") .unwrap(); println!( "\nUpdating SignatureRequirement ID: {}", retrieved_sig_req1.get_id() ); retrieved_sig_req1.status = "Signed".to_string(); retrieved_sig_req1.signed_by = Some("pubkey_legal_team_lead_hex_actual_signer".to_string()); retrieved_sig_req1.signature = Some("mock_signature_base64_encoded".to_string()); db.collection() .expect("can open sig_req collection") .set(&retrieved_sig_req1) .expect("can update sig_req1"); let updated_sig_req1 = db .collection::() .expect("can open sig_req collection") .get_by_id(retrieved_sig_req1.get_id()) .expect("can load updated sig_req1") .unwrap(); assert_eq!(updated_sig_req1.status, "Signed"); assert_eq!( updated_sig_req1.signature.as_deref(), Some("mock_signature_base64_encoded") ); println!("Updated SignatureRequirement: {:?}", updated_sig_req1); // --- Delete a FlowStep --- // (In a real app, you might also want to delete associated SignatureRequirements first, or handle via DB constraints/cascade if supported) let step1_id_to_delete = step1_flow1.get_id(); db.collection::() .expect("can open flow_step collection") .delete_by_id(step1_id_to_delete) .expect("can delete step1_flow1"); println!("\nDeleted FlowStep ID: {}", step1_id_to_delete); let deleted_step = db .collection::() .expect("can open flow_step collection") .get_by_id(step1_id_to_delete) .expect("attempt to load deleted step"); assert!(deleted_step.is_none()); println!("Verified FlowStep ID {} is deleted.", step1_id_to_delete); // Verify only one step remains for flow1 let remaining_steps_for_flow1 = db .collection::() .expect("can open flow_step collection") .get::(&retrieved_flow.get_id()) .expect("can load remaining steps for flow1"); assert_eq!(remaining_steps_for_flow1.len(), 1); assert_eq!(remaining_steps_for_flow1[0].get_id(), step2_flow1.get_id()); println!( "Remaining FlowSteps for Flow ID {}: count = {}", retrieved_flow.get_id(), remaining_steps_for_flow1.len() ); println!("\nFlow example finished successfully!"); }