# Governance Module Enhancement Plan (Revised) ## 1. Current State Analysis The governance module currently consists of: - **Company**: Company model with basic company information - **Shareholder**: Shareholder model for managing company ownership - **Meeting**: Meeting and Attendee models for board meetings - **User**: User model for system users - **Vote**: Vote, VoteOption, and Ballot models for voting All models implement the `Storable` and `SledModel` traits for database integration, but the module has several limitations: - Not imported in src/models/mod.rs, making it inaccessible to the rest of the project - No mod.rs file to organize and re-export the types - No README.md file to document the purpose and usage - Inconsistent imports across files (e.g., crate::db vs crate::core) - Limited utility methods and relationships between models - No integration with other modules like biz, mcc, or circle ## 2. Planned Enhancements ### 2.1 Module Organization and Integration - Create a mod.rs file to organize and re-export the types - Add the governance module to src/models/mod.rs - Create a README.md file to document the purpose and usage - Standardize imports across all files ### 2.2 New Models #### 2.2.1 Resolution Model Create a new `resolution.rs` file with a Resolution model for managing board resolutions: - Resolution information (title, description, text) - Resolution status (Draft, Proposed, Approved, Rejected) - Voting results and approvals - Integration with Meeting and Vote models ### 2.3 Enhanced Relationships and Integration #### 2.3.1 Integration with Biz Module - Link Company with biz::Customer and biz::Contract - Link Shareholder with biz::Customer - Link Meeting with biz::Invoice for expense tracking #### 2.3.2 Integration with MCC Module - Link Meeting with mcc::Calendar and mcc::Event - Link User with mcc::Contact - Link Vote with mcc::Message for notifications #### 2.3.3 Integration with Circle Module - Link Company with circle::Circle for group-based access control - Link User with circle::Member for role-based permissions ### 2.4 Utility Methods and Functionality - Add filtering and searching methods to all models - Add relationship management methods between models - Add validation and business logic methods ## 3. Implementation Plan ```mermaid flowchart TD A[Review Current Models] --> B[Create mod.rs and Update models/mod.rs] B --> C[Standardize Imports and Fix Inconsistencies] C --> D[Create Resolution Model] D --> E[Implement Integration with Other Modules] E --> F[Add Utility Methods] F --> G[Create README.md and Documentation] G --> H[Write Tests] ``` ### 3.1 Detailed Changes #### 3.1.1 Module Organization Create a new `mod.rs` file in the governance directory: ```rust pub mod company; pub mod shareholder; pub mod meeting; pub mod user; pub mod vote; pub mod resolution; // Re-export all model types for convenience pub use company::{Company, CompanyStatus, BusinessType}; pub use shareholder::{Shareholder, ShareholderType}; pub use meeting::{Meeting, Attendee, MeetingStatus, AttendeeRole, AttendeeStatus}; pub use user::User; pub use vote::{Vote, VoteOption, Ballot, VoteStatus}; pub use resolution::{Resolution, ResolutionStatus, Approval}; // Re-export database components from db module pub use crate::db::{SledDB, SledDBError, SledDBResult, Storable, SledModel, DB}; ``` Update `src/models/mod.rs` to include the governance module: ```rust pub mod biz; pub mod mcc; pub mod circle; pub mod governance; ``` #### 3.1.2 Resolution Model (`resolution.rs`) ```rust use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::db::{SledModel, Storable, SledDB, SledDBError}; use crate::models::gov::{Meeting, Vote}; /// ResolutionStatus represents the status of a resolution #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum ResolutionStatus { Draft, Proposed, Approved, Rejected, Withdrawn, } /// Resolution represents a board resolution #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Resolution { pub id: u32, pub company_id: u32, pub meeting_id: Option, pub vote_id: Option, pub title: String, pub description: String, pub text: String, pub status: ResolutionStatus, pub proposed_by: u32, // User ID pub proposed_at: DateTime, pub approved_at: Option>, pub rejected_at: Option>, pub created_at: DateTime, pub updated_at: DateTime, pub approvals: Vec, } /// Approval represents an approval of a resolution by a board member #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Approval { pub id: u32, pub resolution_id: u32, pub user_id: u32, pub name: String, pub approved: bool, pub comments: String, pub created_at: DateTime, } impl Resolution { /// Create a new resolution with default values pub fn new( id: u32, company_id: u32, title: String, description: String, text: String, proposed_by: u32, ) -> Self { let now = Utc::now(); Self { id, company_id, meeting_id: None, vote_id: None, title, description, text, status: ResolutionStatus::Draft, proposed_by, proposed_at: now, approved_at: None, rejected_at: None, created_at: now, updated_at: now, approvals: Vec::new(), } } /// Propose the resolution pub fn propose(&mut self) { self.status = ResolutionStatus::Proposed; self.proposed_at = Utc::now(); self.updated_at = Utc::now(); } /// Approve the resolution pub fn approve(&mut self) { self.status = ResolutionStatus::Approved; self.approved_at = Some(Utc::now()); self.updated_at = Utc::now(); } /// Reject the resolution pub fn reject(&mut self) { self.status = ResolutionStatus::Rejected; self.rejected_at = Some(Utc::now()); self.updated_at = Utc::now(); } /// Add an approval to the resolution pub fn add_approval(&mut self, user_id: u32, name: String, approved: bool, comments: String) -> &Approval { let id = if self.approvals.is_empty() { 1 } else { self.approvals.iter().map(|a| a.id).max().unwrap_or(0) + 1 }; let approval = Approval { id, resolution_id: self.id, user_id, name, approved, comments, created_at: Utc::now(), }; self.approvals.push(approval); self.updated_at = Utc::now(); self.approvals.last().unwrap() } /// Link this resolution to a meeting pub fn link_to_meeting(&mut self, meeting_id: u32) { self.meeting_id = Some(meeting_id); self.updated_at = Utc::now(); } /// Link this resolution to a vote pub fn link_to_vote(&mut self, vote_id: u32) { self.vote_id = Some(vote_id); self.updated_at = Utc::now(); } } // Implement Storable trait (provides default dump/load) impl Storable for Resolution {} impl Storable for Approval {} // Implement SledModel trait impl SledModel for Resolution { fn get_id(&self) -> String { self.id.to_string() } fn db_prefix() -> &'static str { "resolution" } } ``` #### 3.1.3 Enhanced Company Model (`company.rs`) Add integration with other modules: ```rust impl Company { // ... existing methods ... /// Link this company to a Circle for access control pub fn link_to_circle(&mut self, circle_id: u32) -> Result<(), SledDBError> { // Implementation details self.updated_at = Utc::now(); Ok(()) } /// Link this company to a Customer in the biz module pub fn link_to_customer(&mut self, customer_id: u32) -> Result<(), SledDBError> { // Implementation details self.updated_at = Utc::now(); Ok(()) } /// Get all resolutions for this company pub fn get_resolutions(&self, db: &SledDB) -> Result, SledDBError> { let all_resolutions = db.list()?; let company_resolutions = all_resolutions .into_iter() .filter(|resolution| resolution.company_id == self.id) .collect(); Ok(company_resolutions) } } ``` #### 3.1.4 Enhanced Meeting Model (`meeting.rs`) Add integration with other modules: ```rust impl Meeting { // ... existing methods ... /// Link this meeting to a Calendar Event in the mcc module pub fn link_to_event(&mut self, event_id: u32) -> Result<(), SledDBError> { // Implementation details self.updated_at = Utc::now(); Ok(()) } /// Get all resolutions discussed in this meeting pub fn get_resolutions(&self, db: &SledDB) -> Result, SledDBError> { let all_resolutions = db.list()?; let meeting_resolutions = all_resolutions .into_iter() .filter(|resolution| resolution.meeting_id == Some(self.id)) .collect(); Ok(meeting_resolutions) } } ``` #### 3.1.5 Enhanced Vote Model (`vote.rs`) Add integration with Resolution model: ```rust impl Vote { // ... existing methods ... /// Get the resolution associated with this vote pub fn get_resolution(&self, db: &SledDB) -> Result, SledDBError> { let all_resolutions = db.list()?; let vote_resolution = all_resolutions .into_iter() .find(|resolution| resolution.vote_id == Some(self.id)); Ok(vote_resolution) } } ``` #### 3.1.6 Create README.md Create a README.md file to document the purpose and usage of the governance module. ## 4. Data Model Diagram ```mermaid classDiagram class Company { +u32 id +String name +String registration_number +DateTime incorporation_date +String fiscal_year_end +String email +String phone +String website +String address +BusinessType business_type +String industry +String description +CompanyStatus status +DateTime created_at +DateTime updated_at +add_shareholder() +link_to_circle() +link_to_customer() +get_resolutions() } class Shareholder { +u32 id +u32 company_id +u32 user_id +String name +f64 shares +f64 percentage +ShareholderType type_ +DateTime since +DateTime created_at +DateTime updated_at +update_shares() } class Meeting { +u32 id +u32 company_id +String title +DateTime date +String location +String description +MeetingStatus status +String minutes +DateTime created_at +DateTime updated_at +Vec~Attendee~ attendees +add_attendee() +update_status() +update_minutes() +find_attendee_by_user_id() +confirmed_attendees() +link_to_event() +get_resolutions() } class User { +u32 id +String name +String email +String password +String company +String role +DateTime created_at +DateTime updated_at } class Vote { +u32 id +u32 company_id +String title +String description +DateTime start_date +DateTime end_date +VoteStatus status +DateTime created_at +DateTime updated_at +Vec~VoteOption~ options +Vec~Ballot~ ballots +Vec~u32~ private_group +add_option() +add_ballot() +get_resolution() } class Resolution { +u32 id +u32 company_id +Option~u32~ meeting_id +Option~u32~ vote_id +String title +String description +String text +ResolutionStatus status +u32 proposed_by +DateTime proposed_at +Option~DateTime~ approved_at +Option~DateTime~ rejected_at +DateTime created_at +DateTime updated_at +Vec~Approval~ approvals +propose() +approve() +reject() +add_approval() +link_to_meeting() +link_to_vote() } Company "1" -- "many" Shareholder: has Company "1" -- "many" Meeting: holds Company "1" -- "many" Vote: conducts Company "1" -- "many" Resolution: issues Meeting "1" -- "many" Attendee: has Meeting "1" -- "many" Resolution: discusses Vote "1" -- "many" VoteOption: has Vote "1" -- "many" Ballot: collects Vote "1" -- "1" Resolution: decides Resolution "1" -- "many" Approval: receives ``` ## 5. Testing Strategy 1. Unit tests for each model to verify: - Basic functionality - Serialization/deserialization - Utility methods - Integration with other models 2. Integration tests to verify: - Database operations with the models - Relationships between models - Integration with other modules ## 6. Future Considerations 1. **Committee Model**: Add a Committee model in the future if needed 2. **Compliance Model**: Add compliance-related models in the future if needed 3. **API Integration**: Develop REST API endpoints for the governance module 4. **UI Components**: Create UI components for managing governance entities 5. **Reporting**: Implement reporting functionality for governance metrics