Skip to main content

grits_core/
models.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4// Status is just a string in Go
5pub type Status = String;
6pub type IssueType = String;
7
8#[derive(Debug, Serialize, Deserialize, Clone)]
9pub struct Dependency {
10    pub issue_id: String,
11    pub depends_on_id: String,
12    #[serde(rename = "type")]
13    pub type_: String,
14    pub created_at: DateTime<Utc>,
15    pub created_by: String,
16}
17
18#[derive(Debug, Serialize, Deserialize, Clone)]
19pub struct Comment {
20    pub id: String,
21    pub issue_id: String,
22    pub author: String,
23    pub text: String,
24    pub created_at: DateTime<Utc>,
25}
26
27#[derive(Debug, Serialize, Deserialize, Clone, Default)]
28pub struct Issue {
29    pub id: String,
30
31    #[serde(skip)]
32    pub content_hash: String,
33
34    #[serde(default)]
35    pub title: String,
36    #[serde(default)]
37    pub description: String,
38
39    #[serde(default)]
40    pub design: String,
41
42    #[serde(default)]
43    pub acceptance_criteria: String,
44
45    #[serde(default)]
46    pub notes: String,
47
48    #[serde(default)]
49    pub status: Status,
50    #[serde(default)]
51    pub priority: i32,
52    #[serde(default)]
53    pub issue_type: IssueType,
54
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub assignee: Option<String>,
57
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub estimated_minutes: Option<i32>,
60
61    #[serde(default = "Utc::now")]
62    pub created_at: DateTime<Utc>,
63    #[serde(default = "Utc::now")]
64    pub updated_at: DateTime<Utc>,
65
66    #[serde(default, skip_serializing_if = "Option::is_none")]
67    pub closed_at: Option<DateTime<Utc>>,
68
69    #[serde(default, skip_serializing_if = "Option::is_none")]
70    pub external_ref: Option<String>,
71
72    // Messaging fields
73    #[serde(default)]
74    pub sender: String,
75    #[serde(default)]
76    pub ephemeral: bool,
77    #[serde(default)]
78    pub replies_to: String,
79
80    #[serde(default, skip_serializing_if = "Vec::is_empty")]
81    pub relates_to: Vec<String>,
82
83    #[serde(default)]
84    pub duplicate_of: String,
85    #[serde(default)]
86    pub superseded_by: String,
87
88    // Tombstone fields
89    #[serde(default, skip_serializing_if = "Option::is_none")]
90    pub deleted_at: Option<DateTime<Utc>>,
91    #[serde(default)]
92    pub deleted_by: String,
93    #[serde(default)]
94    pub delete_reason: String,
95    #[serde(default)]
96    pub original_type: String,
97
98    // Extra fields for export
99    #[serde(default, skip_serializing_if = "Vec::is_empty")]
100    pub labels: Vec<String>,
101
102    #[serde(default, skip_serializing_if = "Vec::is_empty")]
103    pub dependencies: Vec<Dependency>,
104
105    #[serde(default, skip_serializing_if = "Vec::is_empty")]
106    pub comments: Vec<Comment>,
107
108    // Topology fields
109    #[serde(default, skip_serializing_if = "Vec::is_empty")]
110    pub affected_symbols: Vec<String>,
111}