feat: Tauri commands for tracker CRUD, Tuleap fields, and manual polling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8f7da7b581
commit
e91225d71d
4 changed files with 234 additions and 0 deletions
|
|
@ -1,2 +1,4 @@
|
|||
pub mod credential;
|
||||
pub mod poller;
|
||||
pub mod project;
|
||||
pub mod tracker;
|
||||
|
|
|
|||
98
src-tauri/src/commands/poller.rs
Normal file
98
src-tauri/src/commands/poller.rs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
use crate::error::AppError;
|
||||
use crate::models::credential::TuleapCredentials;
|
||||
use crate::models::ticket::ProcessedTicket;
|
||||
use crate::models::tracker::WatchedTracker;
|
||||
use crate::services::{crypto, filter_engine};
|
||||
use crate::services::tuleap_client::TuleapClient;
|
||||
use crate::AppState;
|
||||
use tauri::State;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn manual_poll(
|
||||
state: State<'_, AppState>,
|
||||
tracker_id: String,
|
||||
) -> Result<Vec<ProcessedTicket>, AppError> {
|
||||
let (tracker, client) = {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
let tracker = WatchedTracker::get_by_id(&db, &tracker_id)?;
|
||||
|
||||
let cred = TuleapCredentials::get(&db)?
|
||||
.ok_or_else(|| AppError::from("No Tuleap credentials configured".to_string()))?;
|
||||
|
||||
let password = crypto::decrypt(&state.encryption_key, &cred.password_encrypted)
|
||||
.map_err(AppError::from)?;
|
||||
|
||||
let client = TuleapClient::new(
|
||||
&state.http_client,
|
||||
&cred.tuleap_url,
|
||||
&cred.username,
|
||||
&password,
|
||||
);
|
||||
|
||||
(tracker, client)
|
||||
}; // lock dropped here
|
||||
|
||||
let artifacts = client
|
||||
.get_artifacts(tracker.tracker_id)
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
|
||||
let filtered = filter_engine::apply_filters(&artifacts, &tracker.filters);
|
||||
|
||||
let mut newly_inserted: Vec<ProcessedTicket> = Vec::new();
|
||||
|
||||
{
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
for artifact in &filtered {
|
||||
let artifact_id = artifact
|
||||
.get("id")
|
||||
.and_then(|v| v.as_i64())
|
||||
.unwrap_or(0) as i32;
|
||||
|
||||
let artifact_title = artifact
|
||||
.get("title")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
|
||||
let artifact_data = serde_json::to_string(artifact)
|
||||
.unwrap_or_else(|_| "{}".to_string());
|
||||
|
||||
if let Some(ticket) = ProcessedTicket::insert_if_new(
|
||||
&db,
|
||||
&tracker.id,
|
||||
artifact_id,
|
||||
&artifact_title,
|
||||
&artifact_data,
|
||||
)? {
|
||||
newly_inserted.push(ticket);
|
||||
}
|
||||
}
|
||||
|
||||
WatchedTracker::update_last_polled(&db, &tracker.id)?;
|
||||
}
|
||||
|
||||
Ok(newly_inserted)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_queue_status(
|
||||
state: State<'_, AppState>,
|
||||
project_id: String,
|
||||
) -> Result<Vec<ProcessedTicket>, AppError> {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
let tickets = ProcessedTicket::list_by_project(&db, &project_id)?;
|
||||
Ok(tickets)
|
||||
}
|
||||
126
src-tauri/src/commands/tracker.rs
Normal file
126
src-tauri/src/commands/tracker.rs
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
use crate::error::AppError;
|
||||
use crate::models::credential::TuleapCredentials;
|
||||
use crate::models::ticket::ProcessedTicket;
|
||||
use crate::models::tracker::{AgentConfig, FilterGroup, WatchedTracker};
|
||||
use crate::services::crypto;
|
||||
use crate::services::tuleap_client::TuleapClient;
|
||||
use crate::AppState;
|
||||
use tauri::State;
|
||||
|
||||
fn build_tuleap_client(state: &State<AppState>) -> Result<TuleapClient, AppError> {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
let cred = TuleapCredentials::get(&db)?
|
||||
.ok_or_else(|| AppError::from("No Tuleap credentials configured".to_string()))?;
|
||||
|
||||
let password = crypto::decrypt(&state.encryption_key, &cred.password_encrypted)
|
||||
.map_err(AppError::from)?;
|
||||
|
||||
Ok(TuleapClient::new(
|
||||
&state.http_client,
|
||||
&cred.tuleap_url,
|
||||
&cred.username,
|
||||
&password,
|
||||
))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn add_tracker(
|
||||
state: State<'_, AppState>,
|
||||
project_id: String,
|
||||
tracker_id: i32,
|
||||
tracker_label: String,
|
||||
polling_interval: i32,
|
||||
agent_config: AgentConfig,
|
||||
filters: Vec<FilterGroup>,
|
||||
) -> Result<WatchedTracker, AppError> {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
let tracker = WatchedTracker::insert(
|
||||
&db,
|
||||
&project_id,
|
||||
tracker_id,
|
||||
&tracker_label,
|
||||
polling_interval,
|
||||
agent_config,
|
||||
filters,
|
||||
)?;
|
||||
|
||||
Ok(tracker)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn list_trackers(
|
||||
state: State<'_, AppState>,
|
||||
project_id: String,
|
||||
) -> Result<Vec<WatchedTracker>, AppError> {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
let trackers = WatchedTracker::list_by_project(&db, &project_id)?;
|
||||
Ok(trackers)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn update_tracker(
|
||||
state: State<'_, AppState>,
|
||||
id: String,
|
||||
polling_interval: i32,
|
||||
agent_config: AgentConfig,
|
||||
filters: Vec<FilterGroup>,
|
||||
enabled: bool,
|
||||
) -> Result<(), AppError> {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
WatchedTracker::update(&db, &id, polling_interval, agent_config, filters, enabled)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn remove_tracker(state: State<'_, AppState>, id: String) -> Result<(), AppError> {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
WatchedTracker::delete(&db, &id)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_tracker_fields(
|
||||
state: State<'_, AppState>,
|
||||
tracker_id: i32,
|
||||
) -> Result<Vec<crate::services::tuleap_client::TrackerField>, AppError> {
|
||||
let client = build_tuleap_client(&state)?;
|
||||
let fields = client
|
||||
.get_tracker_fields(tracker_id)
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
Ok(fields)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn list_processed_tickets(
|
||||
state: State<'_, AppState>,
|
||||
project_id: String,
|
||||
) -> Result<Vec<ProcessedTicket>, AppError> {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
let tickets = ProcessedTicket::list_by_project(&db, &project_id)?;
|
||||
Ok(tickets)
|
||||
}
|
||||
|
|
@ -46,6 +46,14 @@ pub fn run() {
|
|||
commands::credential::get_tuleap_credentials,
|
||||
commands::credential::delete_tuleap_credentials,
|
||||
commands::credential::test_tuleap_connection,
|
||||
commands::tracker::add_tracker,
|
||||
commands::tracker::list_trackers,
|
||||
commands::tracker::update_tracker,
|
||||
commands::tracker::remove_tracker,
|
||||
commands::tracker::get_tracker_fields,
|
||||
commands::tracker::list_processed_tickets,
|
||||
commands::poller::manual_poll,
|
||||
commands::poller::get_queue_status,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
|
|
|||
Loading…
Reference in a new issue