//! Project domain types and DTOs. //! //! Projects group related tasks, events, and emails under a single umbrella. //! Each project has a type classification (Job, SideProject, Company, Essay, //! Article, Painting, Other) and a lifecycle status (Active, OnHold, Completed, //! Archived). Projects can contain milestones for phased tracking. use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use strum_macros::EnumString; use crate::id_types::ProjectId; use super::shared::{CssClass, DbValue, ParseableEnum}; // ============ Project Types ============ /// Classification of project types. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, EnumString)] pub enum ProjectType { /// Employment or client work. #[strum(serialize = "Job")] Job, /// Personal side project. #[strum(serialize = "SideProject")] SideProject, /// Company or business venture. #[strum(serialize = "Company")] Company, /// Long-form writing project. #[strum(serialize = "Essay")] Essay, /// Article or blog post. #[strum(serialize = "Article")] Article, /// Art or visual project. #[strum(serialize = "Painting")] Painting, /// Uncategorized project. #[strum(serialize = "Other")] #[default] Other, } impl ProjectType { /// Returns a human-readable display string. pub fn as_str(&self) -> &'static str { match self { ProjectType::Job => "Job", ProjectType::SideProject => "Side Project", ProjectType::Company => "Company", ProjectType::Essay => "Essay", ProjectType::Article => "Article", ProjectType::Painting => "Painting", ProjectType::Other => "Other", } } } impl ParseableEnum for ProjectType {} impl DbValue for ProjectType { fn db_value(&self) -> &'static str { match self { ProjectType::Job => "Job", ProjectType::SideProject => "SideProject", ProjectType::Company => "Company", ProjectType::Essay => "Essay", ProjectType::Article => "Article", ProjectType::Painting => "Painting", ProjectType::Other => "Other", } } } impl CssClass for ProjectType { fn css_class(&self) -> &'static str { match self { ProjectType::Job => "type-job", ProjectType::SideProject => "type-sideproject", ProjectType::Company => "type-company", ProjectType::Essay => "type-essay", ProjectType::Article => "type-article", ProjectType::Painting => "type-painting", ProjectType::Other => "type-other", } } } /// Lifecycle status of a project. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, EnumString)] pub enum ProjectStatus { /// Currently being worked on. #[strum(serialize = "Active")] #[default] Active, /// Temporarily paused. #[strum(serialize = "OnHold")] OnHold, /// Successfully finished. #[strum(serialize = "Completed")] Completed, /// No longer relevant, hidden from views. #[strum(serialize = "Archived")] Archived, } impl ProjectStatus { /// Returns a human-readable display string. pub fn as_str(&self) -> &'static str { match self { ProjectStatus::Active => "Active", ProjectStatus::OnHold => "On Hold", ProjectStatus::Completed => "Completed", ProjectStatus::Archived => "Archived", } } } impl ParseableEnum for ProjectStatus {} impl DbValue for ProjectStatus { fn db_value(&self) -> &'static str { match self { ProjectStatus::Active => "Active", ProjectStatus::OnHold => "OnHold", ProjectStatus::Completed => "Completed", ProjectStatus::Archived => "Archived", } } } impl CssClass for ProjectStatus { fn css_class(&self) -> &'static str { match self { ProjectStatus::Active => "status-active", ProjectStatus::OnHold => "status-onhold", ProjectStatus::Completed => "status-completed", ProjectStatus::Archived => "status-archived", } } } /// A project that groups related tasks, events, and emails. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Project { /// Unique identifier. pub id: ProjectId, /// Project name. pub name: String, /// Optional description. pub description: String, /// Project classification. pub project_type: ProjectType, /// Current lifecycle status. pub status: ProjectStatus, /// When the project was created. pub created_at: DateTime, } // ============ Project DTOs ============ /// Data for creating a new project. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NewProject { pub name: String, pub description: String, pub project_type: ProjectType, pub status: ProjectStatus, } /// Data for updating an existing project. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UpdateProject { pub name: String, pub description: String, pub project_type: ProjectType, pub status: ProjectStatus, }