- 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.
223 lines
6.2 KiB
Rust
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,
|
|
}
|
|
}
|
|
}
|