use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use uuid::Uuid; /// Represents the status of a governance proposal #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum ProposalStatus { /// Proposal is in draft status, not yet open for voting Draft, /// Proposal is active and open for voting Active, /// Proposal has been approved by the community Approved, /// Proposal has been rejected by the community Rejected, /// Proposal has been cancelled by the creator Cancelled, } impl std::fmt::Display for ProposalStatus { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ProposalStatus::Draft => write!(f, "Draft"), ProposalStatus::Active => write!(f, "Active"), ProposalStatus::Approved => write!(f, "Approved"), ProposalStatus::Rejected => write!(f, "Rejected"), ProposalStatus::Cancelled => write!(f, "Cancelled"), } } } /// Represents a vote on a governance proposal #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum VoteType { /// Vote in favor of the proposal Yes, /// Vote against the proposal No, /// Abstain from voting on the proposal Abstain, } impl std::fmt::Display for VoteType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { VoteType::Yes => write!(f, "Yes"), VoteType::No => write!(f, "No"), VoteType::Abstain => write!(f, "Abstain"), } } } /// Represents a governance proposal in the system #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Proposal { /// Unique identifier for the proposal pub id: String, /// User ID of the proposal creator pub creator_id: i32, /// Name of the proposal creator pub creator_name: String, /// Title of the proposal pub title: String, /// Detailed description of the proposal pub description: String, /// Current status of the proposal pub status: ProposalStatus, /// Date and time when the proposal was created pub created_at: DateTime, /// Date and time when the proposal was last updated pub updated_at: DateTime, /// Date and time when voting starts pub voting_starts_at: Option>, /// Date and time when voting ends pub voting_ends_at: Option>, } #[allow(dead_code)] impl Proposal { /// Creates a new proposal pub fn new(creator_id: i32, creator_name: String, title: String, description: String) -> Self { let now = Utc::now(); Self { id: Uuid::new_v4().to_string(), creator_id, creator_name, title, description, status: ProposalStatus::Draft, created_at: now, updated_at: now, voting_starts_at: None, voting_ends_at: None, } } /// Updates the proposal status pub fn update_status(&mut self, status: ProposalStatus) { self.status = status; self.updated_at = Utc::now(); } /// Sets the voting period for the proposal pub fn set_voting_period(&mut self, starts_at: DateTime, ends_at: DateTime) { self.voting_starts_at = Some(starts_at); self.voting_ends_at = Some(ends_at); self.updated_at = Utc::now(); } /// Activates the proposal for voting pub fn activate(&mut self) { self.status = ProposalStatus::Active; self.updated_at = Utc::now(); } /// Cancels the proposal pub fn cancel(&mut self) { self.status = ProposalStatus::Cancelled; self.updated_at = Utc::now(); } } /// Represents a vote cast on a proposal #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Vote { /// Unique identifier for the vote pub id: String, /// ID of the proposal being voted on pub proposal_id: String, /// User ID of the voter pub voter_id: i32, /// Name of the voter pub voter_name: String, /// Type of vote cast pub vote_type: VoteType, /// Optional comment explaining the vote pub comment: Option, /// Date and time when the vote was cast pub created_at: DateTime, /// Date and time when the vote was last updated pub updated_at: DateTime, } #[allow(dead_code)] impl Vote { /// Creates a new vote pub fn new( proposal_id: String, voter_id: i32, voter_name: String, vote_type: VoteType, comment: Option, ) -> Self { let now = Utc::now(); Self { id: Uuid::new_v4().to_string(), proposal_id, voter_id, voter_name, vote_type, comment, created_at: now, updated_at: now, } } /// Updates the vote type pub fn update_vote(&mut self, vote_type: VoteType, comment: Option) { self.vote_type = vote_type; self.comment = comment; self.updated_at = Utc::now(); } } /// Represents a filter for searching proposals #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProposalFilter { /// Filter by proposal status pub status: Option, /// Filter by creator ID pub creator_id: Option, /// Search term for title and description pub search: Option, } impl Default for ProposalFilter { fn default() -> Self { Self { status: None, creator_id: None, search: None, } } } /// Represents the voting results for a proposal #[derive(Debug, Clone, Serialize, Deserialize)] pub struct VotingResults { /// Proposal ID pub proposal_id: String, /// Number of yes votes pub yes_count: usize, /// Number of no votes pub no_count: usize, /// Number of abstain votes pub abstain_count: usize, /// Total number of votes pub total_votes: usize, } impl VotingResults { /// Creates a new VotingResults instance pub fn new(proposal_id: String) -> Self { Self { proposal_id, yes_count: 0, no_count: 0, abstain_count: 0, total_votes: 0, } } }