Skip to main content

max / goingson

2.3 KB · 87 lines History Blame Raw
1 //! Milestone domain types and DTOs.
2
3 use chrono::{DateTime, Utc};
4 use serde::{Deserialize, Serialize};
5 use strum_macros::EnumString;
6 use crate::id_types::{MilestoneId, UserId, ProjectId};
7 use super::shared::{CssClass, DbValue, ParseableEnum};
8
9 // ============ Milestones ============
10
11 /// Lifecycle status of a milestone.
12 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, EnumString)]
13 pub enum MilestoneStatus {
14 /// Milestone is still being worked toward.
15 #[strum(serialize = "Open")]
16 #[default]
17 Open,
18 /// All milestone tasks are done.
19 #[strum(serialize = "Completed")]
20 Completed,
21 }
22
23 impl MilestoneStatus {
24 /// Returns a human-readable display string.
25 pub fn as_str(&self) -> &'static str {
26 match self {
27 MilestoneStatus::Open => "Open",
28 MilestoneStatus::Completed => "Completed",
29 }
30 }
31
32 }
33
34 impl ParseableEnum for MilestoneStatus {}
35
36 impl DbValue for MilestoneStatus {
37 fn db_value(&self) -> &'static str {
38 match self {
39 MilestoneStatus::Open => "open",
40 MilestoneStatus::Completed => "completed",
41 }
42 }
43 }
44
45 impl CssClass for MilestoneStatus {
46 fn css_class(&self) -> &'static str {
47 match self {
48 MilestoneStatus::Open => "milestone-open",
49 MilestoneStatus::Completed => "milestone-completed",
50 }
51 }
52 }
53
54 /// A project milestone representing a scope boundary.
55 #[derive(Debug, Clone, Serialize, Deserialize)]
56 #[serde(rename_all = "camelCase")]
57 pub struct Milestone {
58 /// Unique identifier.
59 pub id: MilestoneId,
60 /// Owner user ID.
61 pub user_id: UserId,
62 /// Parent project ID.
63 pub project_id: ProjectId,
64 /// Milestone name.
65 pub name: String,
66 /// Optional description.
67 pub description: String,
68 /// Display order (lower = first).
69 pub position: i32,
70 /// Target completion date.
71 pub target_date: Option<chrono::NaiveDate>,
72 /// Current status.
73 pub status: MilestoneStatus,
74 /// When the milestone was created.
75 pub created_at: DateTime<Utc>,
76 }
77
78 /// Data for creating a new milestone.
79 #[derive(Debug, Clone, Serialize, Deserialize)]
80 pub struct NewMilestone {
81 pub project_id: ProjectId,
82 pub name: String,
83 pub description: String,
84 pub position: i32,
85 pub target_date: Option<chrono::NaiveDate>,
86 }
87