intent_engine/dashboard/
models.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Serialize)]
6pub struct ApiResponse<T> {
7 pub data: T,
8}
9
10#[derive(Serialize)]
12pub struct ApiError {
13 pub code: String,
14 pub message: String,
15 #[serde(skip_serializing_if = "Option::is_none")]
16 pub details: Option<Value>,
17}
18
19#[derive(Deserialize)]
21pub struct CreateTaskRequest {
22 pub name: String,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub spec: Option<String>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub priority: Option<i32>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub parent_id: Option<i64>,
29}
30
31#[derive(Deserialize)]
33pub struct UpdateTaskRequest {
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub name: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub spec: Option<String>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub priority: Option<i32>,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub status: Option<String>,
42}
43
44#[derive(Deserialize)]
46pub struct CreateEventRequest {
47 #[serde(rename = "type")]
48 pub event_type: String,
49 pub data: String,
50}
51
52#[derive(Deserialize)]
54pub struct SpawnSubtaskRequest {
55 pub name: String,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub spec: Option<String>,
58}
59
60#[derive(Deserialize)]
62pub struct TaskListQuery {
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub status: Option<String>,
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub parent: Option<String>,
67}
68
69#[derive(Deserialize)]
71pub struct EventListQuery {
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub event_type: Option<String>,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub since: Option<String>,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub limit: Option<i32>,
78}
79
80#[derive(Deserialize)]
82pub struct SwitchProjectRequest {
83 pub project_path: String,
84}
85
86#[derive(Deserialize)]
88pub struct SearchQuery {
89 pub query: String,
90 #[serde(default = "default_true")]
91 pub include_tasks: bool,
92 #[serde(default = "default_true")]
93 pub include_events: bool,
94 #[serde(skip_serializing_if = "Option::is_none")]
95 pub limit: Option<i32>,
96}
97
98fn default_true() -> bool {
99 true
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_create_task_request_deserialization() {
108 let json = r#"{"name":"Test Task","spec":"Test spec","priority":1}"#;
109 let req: CreateTaskRequest = serde_json::from_str(json).unwrap();
110 assert_eq!(req.name, "Test Task");
111 assert_eq!(req.spec, Some("Test spec".to_string()));
112 assert_eq!(req.priority, Some(1));
113 }
114
115 #[test]
116 fn test_api_response_serialization() {
117 let response = ApiResponse { data: "test" };
118 let json = serde_json::to_string(&response).unwrap();
119 assert!(json.contains("\"data\""));
120 }
121
122 #[test]
123 fn test_api_error_serialization() {
124 let error = ApiError {
125 code: "TEST_ERROR".to_string(),
126 message: "Test message".to_string(),
127 details: None,
128 };
129 let json = serde_json::to_string(&error).unwrap();
130 assert!(json.contains("TEST_ERROR"));
131 assert!(!json.contains("details"));
132 }
133
134 #[test]
135 fn test_search_query_defaults() {
136 let json = r#"{"query":"test"}"#;
137 let query: SearchQuery = serde_json::from_str(json).unwrap();
138 assert_eq!(query.query, "test");
139 assert!(query.include_tasks);
140 assert!(query.include_events);
141 }
142}