Skip to main content

raps_da/
workitems.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2024-2025 Dmytro Yemelianov
3
4//! WorkItem operations for the Design Automation API.
5
6use anyhow::{Context, Result};
7
8use raps_kernel::http;
9
10use crate::DesignAutomationClient;
11use crate::types::*;
12
13impl DesignAutomationClient {
14    /// Create a work item (run an activity)
15    pub async fn create_workitem(
16        &self,
17        activity_id: &str,
18        arguments: std::collections::HashMap<String, WorkItemArgument>,
19    ) -> Result<WorkItem> {
20        let token = self.auth.get_token().await?;
21        let url = format!("{}/workitems", self.config.da_url());
22
23        let request = CreateWorkItemRequest {
24            activity_id: activity_id.to_string(),
25            arguments,
26        };
27
28        let response = http::send_with_retry(&self.config.http_config, || {
29            self.http_client
30                .post(&url)
31                .bearer_auth(&token)
32                .header("Content-Type", "application/json")
33                .json(&request)
34        })
35        .await?;
36
37        if !response.status().is_success() {
38            let status = response.status();
39            let error_text = response.text().await.unwrap_or_default();
40            anyhow::bail!("Failed to create workitem ({status}): {error_text}");
41        }
42
43        let workitem: WorkItem = response
44            .json()
45            .await
46            .context("Failed to parse workitem response")?;
47
48        Ok(workitem)
49    }
50
51    /// List all workitems
52    ///
53    /// The DA API requires a `startAfterTime` query parameter.
54    /// Defaults to 24 hours ago if not specified.
55    pub async fn list_workitems(&self) -> Result<Vec<WorkItem>> {
56        let token = self.auth.get_token().await?;
57        // DA API requires startAfterTime -- default to 24h ago
58        let start_after = chrono::Utc::now() - chrono::Duration::hours(24);
59        let url = format!("{}/workitems", self.config.da_url());
60        // DA v3 API expects Unix epoch seconds, not ISO 8601
61        let start_after_str = start_after.timestamp().to_string();
62
63        let response = http::send_with_retry(&self.config.http_config, || {
64            self.http_client
65                .get(&url)
66                .bearer_auth(&token)
67                .query(&[("startAfterTime", &start_after_str)])
68        })
69        .await?;
70
71        if !response.status().is_success() {
72            let status = response.status();
73            let error_text = response.text().await.unwrap_or_default();
74            anyhow::bail!("Failed to list workitems ({status}): {error_text}");
75        }
76
77        let paginated: PaginatedResponse<WorkItem> = response
78            .json()
79            .await
80            .context("Failed to parse workitems response")?;
81
82        Ok(paginated.data)
83    }
84
85    /// Get work item status
86    pub async fn get_workitem_status(&self, id: &str) -> Result<WorkItem> {
87        let token = self.auth.get_token().await?;
88        let url = format!("{}/workitems/{}", self.config.da_url(), id);
89
90        let response = http::send_with_retry(&self.config.http_config, || {
91            self.http_client.get(&url).bearer_auth(&token)
92        })
93        .await?;
94
95        if !response.status().is_success() {
96            let status = response.status();
97            let error_text = response.text().await.unwrap_or_default();
98            anyhow::bail!("Failed to get workitem status ({status}): {error_text}");
99        }
100
101        let workitem: WorkItem = response
102            .json()
103            .await
104            .context("Failed to parse workitem response")?;
105
106        Ok(workitem)
107    }
108}