pipedash_core/domain/
provider.rs1use std::collections::HashMap;
2
3use async_trait::async_trait;
4use serde::{
5 Deserialize,
6 Serialize,
7};
8
9use super::error::DomainResult;
10use super::pipeline::{
11 Pipeline,
12 PipelineRun,
13 TriggerParams,
14};
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct ProviderConfig {
18 pub id: Option<i64>,
19 pub name: String,
20 pub provider_type: String,
21 pub token: String,
22 pub config: HashMap<String, String>,
23 #[serde(default = "default_refresh_interval")]
24 pub refresh_interval: i64,
25 #[serde(default)]
26 pub version: Option<i64>,
27}
28
29fn default_refresh_interval() -> i64 {
30 30
31}
32
33impl ProviderConfig {
34 pub fn display_name(&self) -> &str {
35 self.config
36 .get("display_name")
37 .map(|s| s.as_str())
38 .unwrap_or(&self.name)
39 }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43#[serde(rename_all = "lowercase")]
44pub enum FetchStatus {
45 Success,
46 Error,
47 Never,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct ProviderSummary {
52 pub id: i64,
53 pub name: String,
54 pub provider_type: String,
55 pub icon: Option<String>,
56 pub pipeline_count: usize,
57 pub last_updated: Option<chrono::DateTime<chrono::Utc>>,
58 pub refresh_interval: i64,
59 pub configured_repositories: Vec<String>,
60 pub last_fetch_status: FetchStatus,
61 pub last_fetch_error: Option<String>,
62 pub last_fetch_at: Option<chrono::DateTime<chrono::Utc>>,
63 pub version: i64,
64}
65
66#[async_trait]
67pub trait Provider: Send + Sync {
68 async fn fetch_pipelines(&self) -> DomainResult<Vec<Pipeline>>;
69
70 async fn fetch_pipelines_paginated(
71 &self, page: usize, page_size: usize,
72 ) -> DomainResult<pipedash_plugin_api::PaginatedResponse<Pipeline>> {
73 use pipedash_plugin_api::PaginatedResponse;
74
75 let all_pipelines = self.fetch_pipelines().await?;
76 let total_count = all_pipelines.len();
77 let start = (page - 1) * page_size;
78 let end = start + page_size;
79
80 let pipelines = if start < total_count {
81 all_pipelines[start..end.min(total_count)].to_vec()
82 } else {
83 Vec::new()
84 };
85
86 Ok(PaginatedResponse::new(
87 pipelines,
88 page,
89 page_size,
90 total_count,
91 ))
92 }
93
94 async fn fetch_run_history(
95 &self, pipeline_id: &str, limit: usize,
96 ) -> DomainResult<Vec<PipelineRun>>;
97
98 async fn fetch_run_details(
99 &self, pipeline_id: &str, run_number: i64,
100 ) -> DomainResult<PipelineRun>;
101
102 async fn trigger_pipeline(&self, params: TriggerParams) -> DomainResult<String>;
103
104 async fn cancel_run(&self, pipeline_id: &str, run_number: i64) -> DomainResult<()>;
105
106 async fn get_workflow_parameters(
107 &self, workflow_id: &str,
108 ) -> DomainResult<Vec<pipedash_plugin_api::WorkflowParameter>>;
109
110 #[allow(dead_code)]
111 async fn validate_credentials(&self) -> DomainResult<bool>;
112
113 #[allow(dead_code)]
114 fn provider_type(&self) -> &str;
115}