use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use super::core::{Issue, Plugin, PluginResult};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SyncResult {
pub local_id: String,
pub external_id: String,
pub external_url: Option<String>,
pub status: SyncStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum SyncStatus {
Created,
Updated,
Unchanged,
Failed(String),
Skipped,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConflictResolution {
TakeLocal,
TakeRemote,
Merge(Issue),
Skip,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IntegrationInfo {
pub name: String,
pub icon: Option<String>,
pub supports_bidirectional: bool,
pub supports_webhooks: bool,
pub auth_type: AuthType,
pub base_url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AuthType {
ApiToken,
OAuth2,
BasicAuth,
None,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalLink {
pub provider: String,
pub external_id: String,
pub external_url: Option<String>,
pub last_synced: String,
pub sync_status: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct FieldMappings {
pub status_outbound: HashMap<String, String>,
pub status_inbound: HashMap<String, String>,
pub tags: HashMap<String, String>,
pub custom_fields: HashMap<String, String>,
}
pub trait IntegrationPlugin: Plugin {
fn push_issues(&mut self, issues: &[Issue]) -> PluginResult<Vec<SyncResult>>;
fn pull_issues(&mut self) -> PluginResult<Vec<Issue>>;
fn resolve_conflict(
&mut self,
local: &Issue,
remote: &Issue,
) -> PluginResult<ConflictResolution> {
Ok(if remote.updated > local.updated {
ConflictResolution::TakeRemote
} else {
ConflictResolution::TakeLocal
})
}
fn map_status_outbound(&self, status: &str) -> String;
fn map_status_inbound(&self, external_status: &str) -> String;
fn integration_info(&self) -> IntegrationInfo;
fn handle_webhook(&mut self, _payload: &serde_json::Value) -> PluginResult<Vec<Issue>> {
Ok(vec![])
}
fn field_mappings(&self) -> FieldMappings {
FieldMappings::default()
}
fn validate_connection(&mut self) -> PluginResult<bool> {
Ok(true)
}
}