@@ -47,6 +47,33 @@ impl MeResponse {
4747 }
4848}
4949
50+ // -- Clients --
51+
52+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
53+ pub struct Client {
54+ pub id : String ,
55+ pub name : String ,
56+ #[ serde( default ) ]
57+ pub currency : Option < String > ,
58+ #[ serde( default ) ]
59+ pub address : Option < String > ,
60+ #[ serde( default ) ]
61+ pub is_active : bool ,
62+ #[ serde( default ) ]
63+ pub created_at : Option < DateTime < Utc > > ,
64+ #[ serde( default ) ]
65+ pub updated_at : Option < DateTime < Utc > > ,
66+ }
67+
68+ #[ derive( Debug , Serialize ) ]
69+ pub struct CreateClientRequest {
70+ pub name : String ,
71+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
72+ pub address : Option < String > ,
73+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
74+ pub currency : Option < String > ,
75+ }
76+
5077// -- Projects --
5178
5279#[ derive( Debug , Clone , Serialize , Deserialize ) ]
@@ -83,6 +110,24 @@ impl Project {
83110 }
84111}
85112
113+ #[ derive( Debug , Serialize ) ]
114+ pub struct CreateProjectRequest {
115+ pub client_id : String ,
116+ pub name : String ,
117+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
118+ pub code : Option < String > ,
119+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
120+ pub notes : Option < String > ,
121+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
122+ pub is_billable : Option < bool > ,
123+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
124+ pub bill_by : Option < String > ,
125+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
126+ pub budget_by : Option < String > ,
127+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
128+ pub task_ids : Option < Vec < String > > ,
129+ }
130+
86131// -- Tasks --
87132
88133#[ derive( Debug , Clone , Serialize , Deserialize ) ]
@@ -181,6 +226,10 @@ pub struct CreateTimeEntryRequest {
181226 pub billable : Option < bool > ,
182227 pub is_running : bool ,
183228 #[ serde( skip_serializing_if = "Option::is_none" ) ]
229+ pub started_time : Option < String > ,
230+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
231+ pub ended_time : Option < String > ,
232+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
184233 pub source : Option < String > ,
185234 #[ serde( skip_serializing_if = "Option::is_none" ) ]
186235 pub metadata : Option < serde_json:: Value > ,
@@ -189,6 +238,12 @@ pub struct CreateTimeEntryRequest {
189238#[ derive( Debug , Serialize ) ]
190239#[ allow( dead_code) ]
191240pub struct UpdateTimeEntryRequest {
241+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
242+ pub project_id : Option < String > ,
243+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
244+ pub task_id : Option < String > ,
245+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
246+ pub spent_date : Option < String > ,
192247 #[ serde( skip_serializing_if = "Option::is_none" ) ]
193248 pub is_running : Option < bool > ,
194249 #[ serde( skip_serializing_if = "Option::is_none" ) ]
@@ -198,6 +253,10 @@ pub struct UpdateTimeEntryRequest {
198253 #[ serde( skip_serializing_if = "Option::is_none" ) ]
199254 pub billable : Option < bool > ,
200255 #[ serde( skip_serializing_if = "Option::is_none" ) ]
256+ pub started_time : Option < String > ,
257+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
258+ pub ended_time : Option < String > ,
259+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
201260 pub metadata : Option < serde_json:: Value > ,
202261}
203262
@@ -233,6 +292,21 @@ pub struct ProjectsResponse {
233292 pub links : Option < PaginationLinks > ,
234293}
235294
295+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
296+ pub struct ClientsResponse {
297+ pub clients : Vec < Client > ,
298+ #[ serde( default ) ]
299+ pub per_page : Option < u64 > ,
300+ #[ serde( default ) ]
301+ pub total_pages : Option < u64 > ,
302+ #[ serde( default ) ]
303+ pub total_entries : Option < u64 > ,
304+ #[ serde( default ) ]
305+ pub page : Option < u64 > ,
306+ #[ serde( default ) ]
307+ pub links : Option < PaginationLinks > ,
308+ }
309+
236310#[ derive( Debug , Clone , Serialize , Deserialize ) ]
237311pub struct TasksResponse {
238312 pub tasks : Vec < Task > ,
@@ -297,13 +371,17 @@ mod tests {
297371 notes : Some ( "test" . into ( ) ) ,
298372 billable : Some ( true ) ,
299373 is_running : false ,
374+ started_time : Some ( "09:00" . into ( ) ) ,
375+ ended_time : Some ( "10:30" . into ( ) ) ,
300376 source : Some ( "cli" . into ( ) ) ,
301377 metadata : None ,
302378 } ;
303379
304380 let value = serde_json:: to_value ( req) . unwrap ( ) ;
305381 assert_eq ! ( value[ "spent_date" ] , "2026-03-04" ) ;
306382 assert_eq ! ( value[ "billable" ] , true ) ;
383+ assert_eq ! ( value[ "started_time" ] , "09:00" ) ;
384+ assert_eq ! ( value[ "ended_time" ] , "10:30" ) ;
307385 assert ! ( value. get( "date" ) . is_none( ) ) ;
308386 assert ! ( value. get( "is_billable" ) . is_none( ) ) ;
309387 }
0 commit comments