hostbasket/actix_mvc_app/src/models/governance.rs
Mahmoud-Emad 11d7ae37b6 feat: Enhance governance module with activity tracking and DB refactor
- Refactor database interaction for proposals and activities.
- Add activity tracking for proposal creation and voting.
- Improve logging for better debugging and monitoring.
- Update governance views to display recent activities.
- Add strum and strum_macros crates for enum handling.
- Update Cargo.lock file with new dependencies.
2025-05-27 20:45:30 +03:00

223 lines
6.2 KiB
Rust

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<Utc>,
/// Date and time when the proposal was last updated
pub updated_at: DateTime<Utc>,
/// Date and time when voting starts
pub voting_starts_at: Option<DateTime<Utc>>,
/// Date and time when voting ends
pub voting_ends_at: Option<DateTime<Utc>>,
}
#[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<Utc>, ends_at: DateTime<Utc>) {
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<String>,
/// Date and time when the vote was cast
pub created_at: DateTime<Utc>,
/// Date and time when the vote was last updated
pub updated_at: DateTime<Utc>,
}
#[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<String>,
) -> 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<String>) {
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<String>,
/// Filter by creator ID
pub creator_id: Option<i32>,
/// Search term for title and description
pub search: Option<String>,
}
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,
}
}
}