From 5327d1f00ccd4c808862cbf10711ac95a1e4d3c0 Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Wed, 21 May 2025 09:37:45 +0300 Subject: [PATCH] fix: Add creator_name field to the proposal model --- .../governance_proposal_example/main.rs | 12 +- .../examples/governance_rhai/example.rs | 202 ++++++++++++------ heromodels/src/models/governance/proposal.rs | 6 +- 3 files changed, 152 insertions(+), 68 deletions(-) diff --git a/heromodels/examples/governance_proposal_example/main.rs b/heromodels/examples/governance_proposal_example/main.rs index f6ad994..9b75c9d 100644 --- a/heromodels/examples/governance_proposal_example/main.rs +++ b/heromodels/examples/governance_proposal_example/main.rs @@ -13,12 +13,13 @@ fn main() { // Create a new proposal with auto-generated ID let mut proposal = Proposal::new( - None, // id (auto-generated) - "user_creator_123", // creator_id - "Community Fund Allocation for Q3", // title + None, // id (auto-generated) + "user_creator_123", + "Ahmed fared", // creator_id + "Community Fund Allocation for Q3", // title "Proposal to allocate funds for community projects in the third quarter.", // description - Utc::now(), // vote_start_date - Utc::now() + Duration::days(14), // vote_end_date (14 days from now) + Utc::now(), // vote_start_date + Utc::now() + Duration::days(14), // vote_end_date (14 days from now) ); println!( @@ -125,6 +126,7 @@ fn main() { let mut private_proposal = Proposal::new( None, // auto-generated ID "user_admin_001", + "Wael Ghonem", "Internal Team Restructure Vote", "Vote on proposed internal team changes.", Utc::now(), diff --git a/heromodels/examples/governance_rhai/example.rs b/heromodels/examples/governance_rhai/example.rs index 8cd7729..65a9089 100644 --- a/heromodels/examples/governance_rhai/example.rs +++ b/heromodels/examples/governance_rhai/example.rs @@ -1,10 +1,12 @@ +use chrono::{Duration, Utc}; use heromodels::db::hero::OurDB; -use heromodels::models::governance::{Proposal, ProposalStatus, VoteEventStatus, VoteOption, Ballot}; +use heromodels::models::governance::{ + Ballot, Proposal, ProposalStatus, VoteEventStatus, VoteOption, +}; use rhai::Engine; use rhai_wrapper::wrap_vec_return; use std::sync::Arc; use std::{fs, path::Path}; -use chrono::{Utc, Duration}; fn main() -> Result<(), Box> { // Initialize Rhai engine @@ -24,21 +26,40 @@ fn main() -> Result<(), Box> { engine.register_fn("get_db", move || db.clone()); // Register builder functions for Proposal and related types - engine.register_fn("create_proposal", |id: i64, creator_id: String, title: String, description: String| { - let start_date = Utc::now(); - let end_date = start_date + Duration::days(14); - let id_option = if id <= 0 { None } else { Some(id as u32) }; - Proposal::new(id_option, creator_id, title, description, start_date, end_date) - }); + engine.register_fn( + "create_proposal", + |id: i64, creator_id: String, creator_name: String, title: String, description: String| { + let start_date = Utc::now(); + let end_date = start_date + Duration::days(14); + let id_option = if id <= 0 { None } else { Some(id as u32) }; + Proposal::new( + id_option, + creator_id, + creator_name, + title, + description, + start_date, + end_date, + ) + }, + ); engine.register_fn("create_vote_option", |id: i64, text: String| { VoteOption::new(id as u8, text) }); - engine.register_fn("create_ballot", |id: i64, user_id: i64, vote_option_id: i64, shares_count: i64| { - let id_option = if id <= 0 { None } else { Some(id as u32) }; - Ballot::new(id_option, user_id as u32, vote_option_id as u8, shares_count) - }); + engine.register_fn( + "create_ballot", + |id: i64, user_id: i64, vote_option_id: i64, shares_count: i64| { + let id_option = if id <= 0 { None } else { Some(id as u32) }; + Ballot::new( + id_option, + user_id as u32, + vote_option_id as u8, + shares_count, + ) + }, + ); // Register getter and setter methods for Proposal properties engine.register_fn("get_title", |proposal: Proposal| -> String { @@ -66,48 +87,80 @@ fn main() -> Result<(), Box> { }); // Register methods for proposal operations - engine.register_fn("add_option_to_proposal", |mut proposal: Proposal, option_id: i64, option_text: String| -> Proposal { - proposal.add_option(option_id as u8, option_text) - }); + engine.register_fn( + "add_option_to_proposal", + |mut proposal: Proposal, option_id: i64, option_text: String| -> Proposal { + proposal.add_option(option_id as u8, option_text) + }, + ); - engine.register_fn("cast_vote_on_proposal", |mut proposal: Proposal, ballot_id: i64, user_id: i64, option_id: i64, shares: i64| -> Proposal { - let ballot_id_option = if ballot_id <= 0 { None } else { Some(ballot_id as u32) }; - proposal.cast_vote(ballot_id_option, user_id as u32, option_id as u8, shares) - }); + engine.register_fn( + "cast_vote_on_proposal", + |mut proposal: Proposal, + ballot_id: i64, + user_id: i64, + option_id: i64, + shares: i64| + -> Proposal { + let ballot_id_option = if ballot_id <= 0 { + None + } else { + Some(ballot_id as u32) + }; + proposal.cast_vote(ballot_id_option, user_id as u32, option_id as u8, shares) + }, + ); - engine.register_fn("change_proposal_status", |mut proposal: Proposal, status_str: String| -> Proposal { - let new_status = match status_str.as_str() { - "Draft" => ProposalStatus::Draft, - "Active" => ProposalStatus::Active, - "Approved" => ProposalStatus::Approved, - "Rejected" => ProposalStatus::Rejected, - "Cancelled" => ProposalStatus::Cancelled, - _ => ProposalStatus::Draft, - }; - proposal.change_proposal_status(new_status) - }); + engine.register_fn( + "change_proposal_status", + |mut proposal: Proposal, status_str: String| -> Proposal { + let new_status = match status_str.as_str() { + "Draft" => ProposalStatus::Draft, + "Active" => ProposalStatus::Active, + "Approved" => ProposalStatus::Approved, + "Rejected" => ProposalStatus::Rejected, + "Cancelled" => ProposalStatus::Cancelled, + _ => ProposalStatus::Draft, + }; + proposal.change_proposal_status(new_status) + }, + ); - engine.register_fn("change_vote_event_status", |mut proposal: Proposal, status_str: String| -> Proposal { - let new_status = match status_str.as_str() { - "Open" => VoteEventStatus::Open, - "Closed" => VoteEventStatus::Closed, - "Cancelled" => VoteEventStatus::Cancelled, - _ => VoteEventStatus::Open, - }; - proposal.change_vote_event_status(new_status) - }); + engine.register_fn( + "change_vote_event_status", + |mut proposal: Proposal, status_str: String| -> Proposal { + let new_status = match status_str.as_str() { + "Open" => VoteEventStatus::Open, + "Closed" => VoteEventStatus::Closed, + "Cancelled" => VoteEventStatus::Cancelled, + _ => VoteEventStatus::Open, + }; + proposal.change_vote_event_status(new_status) + }, + ); // Register functions for database operations engine.register_fn("save_proposal", |_db: Arc, proposal: Proposal| { println!("Proposal saved: {}", proposal.title); }); - engine.register_fn("get_proposal_by_id", |_db: Arc, id: i64| -> Proposal { - // In a real implementation, this would retrieve the proposal from the database - let start_date = Utc::now(); - let end_date = start_date + Duration::days(14); - Proposal::new(Some(id as u32), "Retrieved Creator", "Retrieved Proposal", "Retrieved Description", start_date, end_date) - }); + engine.register_fn( + "get_proposal_by_id", + |_db: Arc, id: i64| -> Proposal { + // In a real implementation, this would retrieve the proposal from the database + let start_date = Utc::now(); + let end_date = start_date + Duration::days(14); + Proposal::new( + Some(id as u32), + "Retrieved Creator", + "Retrieved Creator Name", + "Retrieved Proposal", + "Retrieved Description", + start_date, + end_date, + ) + }, + ); // Register a function to check if a proposal exists engine.register_fn("proposal_exists", |_db: Arc, id: i64| -> bool { @@ -121,13 +174,32 @@ fn main() -> Result<(), Box> { let start_date = Utc::now(); let end_date = start_date + Duration::days(14); vec![ - Proposal::new(Some(1), "Creator 1", "Proposal 1", "Description 1", start_date, end_date), - Proposal::new(Some(2), "Creator 2", "Proposal 2", "Description 2", start_date, end_date) + Proposal::new( + Some(1), + "Creator 1", + "Creator Name 1", + "Proposal 1", + "Description 1", + start_date, + end_date, + ), + Proposal::new( + Some(2), + "Creator 2", + "Creator Name 2", + "Proposal 2", + "Description 2", + start_date, + end_date, + ), ] } // Register the function with the wrap_vec_return macro - engine.register_fn("get_all_proposals", wrap_vec_return!(get_all_proposals, Arc => Proposal)); + engine.register_fn( + "get_all_proposals", + wrap_vec_return!(get_all_proposals, Arc => Proposal), + ); engine.register_fn("delete_proposal_by_id", |_db: Arc, _id: i64| { // In a real implementation, this would delete the proposal from the database @@ -139,13 +211,16 @@ fn main() -> Result<(), Box> { proposal.options.len() as i64 }); - engine.register_fn("get_option_at", |proposal: Proposal, index: i64| -> VoteOption { - if index >= 0 && index < proposal.options.len() as i64 { - proposal.options[index as usize].clone() - } else { - VoteOption::new(0, "Invalid Option") - } - }); + engine.register_fn( + "get_option_at", + |proposal: Proposal, index: i64| -> VoteOption { + if index >= 0 && index < proposal.options.len() as i64 { + proposal.options[index as usize].clone() + } else { + VoteOption::new(0, "Invalid Option") + } + }, + ); engine.register_fn("get_option_text", |option: VoteOption| -> String { option.text.clone() @@ -159,13 +234,16 @@ fn main() -> Result<(), Box> { proposal.ballots.len() as i64 }); - engine.register_fn("get_ballot_at", |proposal: Proposal, index: i64| -> Ballot { - if index >= 0 && index < proposal.ballots.len() as i64 { - proposal.ballots[index as usize].clone() - } else { - Ballot::new(None, 0, 0, 0) - } - }); + engine.register_fn( + "get_ballot_at", + |proposal: Proposal, index: i64| -> Ballot { + if index >= 0 && index < proposal.ballots.len() as i64 { + proposal.ballots[index as usize].clone() + } else { + Ballot::new(None, 0, 0, 0) + } + }, + ); engine.register_fn("get_ballot_user_id", |ballot: Ballot| -> i64 { ballot.user_id as i64 diff --git a/heromodels/src/models/governance/proposal.rs b/heromodels/src/models/governance/proposal.rs index bf207e5..4e26a68 100644 --- a/heromodels/src/models/governance/proposal.rs +++ b/heromodels/src/models/governance/proposal.rs @@ -102,7 +102,9 @@ impl Ballot { #[model] // Has base.Base in V spec pub struct Proposal { pub base_data: BaseModelData, - pub creator_id: String, // User ID of the proposal creator + pub creator_id: String, // User ID of the proposal creator + pub creator_name: String, // User name of the proposal creator + pub title: String, pub description: String, pub status: ProposalStatus, @@ -129,6 +131,7 @@ impl Proposal { pub fn new( id: Option, creator_id: impl ToString, + creator_name: impl ToString, title: impl ToString, description: impl ToString, vote_start_date: DateTime, @@ -142,6 +145,7 @@ impl Proposal { Self { base_data, creator_id: creator_id.to_string(), + creator_name: creator_name.to_string(), title: title.to_string(), description: description.to_string(), status: ProposalStatus::Draft,