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, 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 = 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, 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) }