db/heromodels/examples/flow_example.rs
2025-06-19 13:18:10 +03:00

201 lines
7.4 KiB
Rust

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::<Flow>()
.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::<Flow>()
.expect("can open flow collection")
.get::<flow_uuid_idx, _>(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::<FlowStep>()
.expect("can open flow_step collection")
.get::<flow_step_flow_id_idx, _>(&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::<SignatureRequirement>()
.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::<SignatureRequirement>()
.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::<FlowStep>()
.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::<FlowStep>()
.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::<FlowStep>()
.expect("can open flow_step collection")
.get::<flow_step_flow_id_idx, _>(&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!");
}