fix(clippy): reduce tracker insert/add argument count
This commit is contained in:
parent
7fc7a674f0
commit
2d87ad5344
7 changed files with 278 additions and 165 deletions
|
|
@ -2,10 +2,11 @@ use crate::error::AppError;
|
|||
use crate::models::agent::{Agent, AgentRole};
|
||||
use crate::models::credential::TuleapCredentials;
|
||||
use crate::models::ticket::ProcessedTicket;
|
||||
use crate::models::tracker::{FilterGroup, TrackerUpdate, WatchedTracker};
|
||||
use crate::models::tracker::{FilterGroup, NewWatchedTracker, TrackerUpdate, WatchedTracker};
|
||||
use crate::services::crypto;
|
||||
use crate::services::tuleap_client::TuleapClient;
|
||||
use crate::AppState;
|
||||
use serde::Deserialize;
|
||||
use tauri::State;
|
||||
|
||||
fn build_tuleap_client(state: &State<AppState>) -> Result<TuleapClient, AppError> {
|
||||
|
|
@ -17,8 +18,8 @@ fn build_tuleap_client(state: &State<AppState>) -> Result<TuleapClient, AppError
|
|||
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 password =
|
||||
crypto::decrypt(&state.encryption_key, &cred.password_encrypted).map_err(AppError::from)?;
|
||||
|
||||
Ok(TuleapClient::new(
|
||||
&state.http_client,
|
||||
|
|
@ -28,7 +29,11 @@ fn build_tuleap_client(state: &State<AppState>) -> Result<TuleapClient, AppError
|
|||
))
|
||||
}
|
||||
|
||||
fn ensure_agent_role(db: &rusqlite::Connection, agent_id: &str, expected: AgentRole) -> Result<(), AppError> {
|
||||
fn ensure_agent_role(
|
||||
db: &rusqlite::Connection,
|
||||
agent_id: &str,
|
||||
expected: AgentRole,
|
||||
) -> Result<(), AppError> {
|
||||
let agent = Agent::get_by_id(db, agent_id)?;
|
||||
if agent.role != expected {
|
||||
return Err(AppError::from(format!(
|
||||
|
|
@ -41,34 +46,42 @@ fn ensure_agent_role(db: &rusqlite::Connection, agent_id: &str, expected: AgentR
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddTrackerPayload {
|
||||
pub project_id: String,
|
||||
pub tracker_id: i32,
|
||||
pub tracker_label: String,
|
||||
pub polling_interval: i32,
|
||||
pub analyst_agent_id: String,
|
||||
pub developer_agent_id: String,
|
||||
pub filters: Vec<FilterGroup>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn add_tracker(
|
||||
state: State<'_, AppState>,
|
||||
project_id: String,
|
||||
tracker_id: i32,
|
||||
tracker_label: String,
|
||||
polling_interval: i32,
|
||||
analyst_agent_id: String,
|
||||
developer_agent_id: String,
|
||||
filters: Vec<FilterGroup>,
|
||||
payload: AddTrackerPayload,
|
||||
) -> Result<WatchedTracker, AppError> {
|
||||
let db = state
|
||||
.db
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
ensure_agent_role(&db, &analyst_agent_id, AgentRole::Analyst)?;
|
||||
ensure_agent_role(&db, &developer_agent_id, AgentRole::Developer)?;
|
||||
ensure_agent_role(&db, &payload.analyst_agent_id, AgentRole::Analyst)?;
|
||||
ensure_agent_role(&db, &payload.developer_agent_id, AgentRole::Developer)?;
|
||||
|
||||
let tracker = WatchedTracker::insert(
|
||||
&db,
|
||||
&project_id,
|
||||
tracker_id,
|
||||
&tracker_label,
|
||||
polling_interval,
|
||||
&analyst_agent_id,
|
||||
&developer_agent_id,
|
||||
filters,
|
||||
NewWatchedTracker {
|
||||
project_id: payload.project_id,
|
||||
tracker_id: payload.tracker_id,
|
||||
tracker_label: payload.tracker_label,
|
||||
polling_interval: payload.polling_interval,
|
||||
analyst_agent_id: payload.analyst_agent_id,
|
||||
developer_agent_id: payload.developer_agent_id,
|
||||
filters: payload.filters,
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(tracker)
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ mod tests {
|
|||
use super::*;
|
||||
use crate::db;
|
||||
use crate::models::project::Project;
|
||||
use crate::models::tracker::WatchedTracker;
|
||||
use crate::models::tracker::{NewWatchedTracker, WatchedTracker};
|
||||
|
||||
fn setup() -> Connection {
|
||||
db::init_in_memory().expect("db init should succeed")
|
||||
|
|
@ -302,10 +302,9 @@ mod tests {
|
|||
"new script",
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(
|
||||
err.to_string()
|
||||
.contains("Default agents cannot change name, role, or tool")
|
||||
);
|
||||
assert!(err
|
||||
.to_string()
|
||||
.contains("Default agents cannot change name, role, or tool"));
|
||||
|
||||
Agent::update(
|
||||
&conn,
|
||||
|
|
@ -338,18 +337,20 @@ mod tests {
|
|||
let analyst_default = Agent::get_default_by_role(&conn, AgentRole::Analyst).unwrap();
|
||||
let developer_default = Agent::get_default_by_role(&conn, AgentRole::Developer).unwrap();
|
||||
|
||||
let analyst = Agent::insert(&conn, "Analyst", AgentRole::Analyst, AgentTool::Codex, "")
|
||||
.unwrap();
|
||||
let analyst =
|
||||
Agent::insert(&conn, "Analyst", AgentRole::Analyst, AgentTool::Codex, "").unwrap();
|
||||
|
||||
let tracker = WatchedTracker::insert(
|
||||
&conn,
|
||||
&project.id,
|
||||
100,
|
||||
"Bugs",
|
||||
10,
|
||||
&analyst.id,
|
||||
&developer_default.id,
|
||||
vec![],
|
||||
NewWatchedTracker {
|
||||
project_id: project.id.clone(),
|
||||
tracker_id: 100,
|
||||
tracker_label: "Bugs".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst.id.clone(),
|
||||
developer_agent_id: developer_default.id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,14 @@ impl ProcessedTicket {
|
|||
"INSERT INTO processed_tickets \
|
||||
(id, tracker_id, artifact_id, artifact_title, artifact_data, status, detected_at) \
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, 'Pending', ?6)",
|
||||
params![id, tracker_id, artifact_id, artifact_title, artifact_data, now],
|
||||
params![
|
||||
id,
|
||||
tracker_id,
|
||||
artifact_id,
|
||||
artifact_title,
|
||||
artifact_data,
|
||||
now
|
||||
],
|
||||
)?;
|
||||
|
||||
let ticket = ProcessedTicket {
|
||||
|
|
@ -183,7 +190,7 @@ mod tests {
|
|||
use crate::db;
|
||||
use crate::models::agent::{Agent, AgentRole, AgentTool};
|
||||
use crate::models::project::Project;
|
||||
use crate::models::tracker::WatchedTracker;
|
||||
use crate::models::tracker::{NewWatchedTracker, WatchedTracker};
|
||||
|
||||
fn setup() -> (Connection, String) {
|
||||
let conn = db::init_in_memory().expect("db init should succeed");
|
||||
|
|
@ -193,13 +200,15 @@ mod tests {
|
|||
Agent::insert(&conn, "D", AgentRole::Developer, AgentTool::ClaudeCode, "").unwrap();
|
||||
let tracker = WatchedTracker::insert(
|
||||
&conn,
|
||||
&project.id,
|
||||
456,
|
||||
"Bugs",
|
||||
10,
|
||||
&analyst.id,
|
||||
&developer.id,
|
||||
vec![],
|
||||
NewWatchedTracker {
|
||||
project_id: project.id.clone(),
|
||||
tracker_id: 456,
|
||||
tracker_label: "Bugs".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst.id.clone(),
|
||||
developer_agent_id: developer.id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
(conn, tracker.id)
|
||||
|
|
@ -257,8 +266,8 @@ mod tests {
|
|||
fn test_exists() {
|
||||
let (conn, tracker_id) = setup();
|
||||
|
||||
let before = ProcessedTicket::exists(&conn, &tracker_id, 303)
|
||||
.expect("exists check should succeed");
|
||||
let before =
|
||||
ProcessedTicket::exists(&conn, &tracker_id, 303).expect("exists check should succeed");
|
||||
assert!(!before);
|
||||
|
||||
ProcessedTicket::insert_if_new(&conn, &tracker_id, 303, "Some ticket", "{}")
|
||||
|
|
@ -285,10 +294,15 @@ mod tests {
|
|||
fn test_get_by_id() {
|
||||
let (conn, tracker_id) = setup();
|
||||
|
||||
let inserted =
|
||||
ProcessedTicket::insert_if_new(&conn, &tracker_id, 404, "Not Found Bug", "{\"id\": 404}")
|
||||
.expect("insert should succeed")
|
||||
.expect("should be Some");
|
||||
let inserted = ProcessedTicket::insert_if_new(
|
||||
&conn,
|
||||
&tracker_id,
|
||||
404,
|
||||
"Not Found Bug",
|
||||
"{\"id\": 404}",
|
||||
)
|
||||
.expect("insert should succeed")
|
||||
.expect("should be Some");
|
||||
|
||||
let found =
|
||||
ProcessedTicket::get_by_id(&conn, &inserted.id).expect("get_by_id should succeed");
|
||||
|
|
|
|||
|
|
@ -41,6 +41,17 @@ pub struct TrackerUpdate {
|
|||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct NewWatchedTracker {
|
||||
pub project_id: String,
|
||||
pub tracker_id: i32,
|
||||
pub tracker_label: String,
|
||||
pub polling_interval: i32,
|
||||
pub analyst_agent_id: String,
|
||||
pub developer_agent_id: String,
|
||||
pub filters: Vec<FilterGroup>,
|
||||
}
|
||||
|
||||
fn normalize_agent_id(agent_id: &str) -> Option<String> {
|
||||
let trimmed = agent_id.trim();
|
||||
if trimmed.is_empty() {
|
||||
|
|
@ -50,7 +61,10 @@ fn normalize_agent_id(agent_id: &str) -> Option<String> {
|
|||
}
|
||||
}
|
||||
|
||||
fn compute_status(analyst_agent_id: &Option<String>, developer_agent_id: &Option<String>) -> String {
|
||||
fn compute_status(
|
||||
analyst_agent_id: &Option<String>,
|
||||
developer_agent_id: &Option<String>,
|
||||
) -> String {
|
||||
if analyst_agent_id.is_some() && developer_agent_id.is_some() {
|
||||
"valid".to_string()
|
||||
} else {
|
||||
|
|
@ -62,8 +76,9 @@ fn from_row(row: &rusqlite::Row) -> rusqlite::Result<WatchedTracker> {
|
|||
let filters_json: String = row.get(7)?;
|
||||
let enabled_int: i32 = row.get(8)?;
|
||||
|
||||
let filters: Vec<FilterGroup> = serde_json::from_str(&filters_json)
|
||||
.map_err(|e| rusqlite::Error::FromSqlConversionFailure(7, rusqlite::types::Type::Text, Box::new(e)))?;
|
||||
let filters: Vec<FilterGroup> = serde_json::from_str(&filters_json).map_err(|e| {
|
||||
rusqlite::Error::FromSqlConversionFailure(7, rusqlite::types::Type::Text, Box::new(e))
|
||||
})?;
|
||||
|
||||
Ok(WatchedTracker {
|
||||
id: row.get(0)?,
|
||||
|
|
@ -82,49 +97,50 @@ fn from_row(row: &rusqlite::Row) -> rusqlite::Result<WatchedTracker> {
|
|||
}
|
||||
|
||||
impl WatchedTracker {
|
||||
pub fn insert(
|
||||
conn: &Connection,
|
||||
project_id: &str,
|
||||
tracker_id: i32,
|
||||
tracker_label: &str,
|
||||
polling_interval: i32,
|
||||
analyst_agent_id: &str,
|
||||
developer_agent_id: &str,
|
||||
filters: Vec<FilterGroup>,
|
||||
) -> Result<WatchedTracker> {
|
||||
pub fn insert(conn: &Connection, new_tracker: NewWatchedTracker) -> Result<WatchedTracker> {
|
||||
let NewWatchedTracker {
|
||||
project_id,
|
||||
tracker_id,
|
||||
tracker_label,
|
||||
polling_interval,
|
||||
analyst_agent_id,
|
||||
developer_agent_id,
|
||||
filters,
|
||||
} = new_tracker;
|
||||
|
||||
let id = Uuid::new_v4().to_string();
|
||||
let now = chrono::Utc::now().to_rfc3339();
|
||||
|
||||
let filters_json = serde_json::to_string(&filters)
|
||||
.map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
|
||||
|
||||
let analyst_agent_id = normalize_agent_id(analyst_agent_id);
|
||||
let developer_agent_id = normalize_agent_id(developer_agent_id);
|
||||
let analyst_agent_id = normalize_agent_id(&analyst_agent_id);
|
||||
let developer_agent_id = normalize_agent_id(&developer_agent_id);
|
||||
let status = compute_status(&analyst_agent_id, &developer_agent_id);
|
||||
|
||||
conn.execute(
|
||||
"INSERT INTO watched_trackers (id, project_id, tracker_id, tracker_label, polling_interval, agent_config_json, filters_json, analyst_agent_id, developer_agent_id, status, created_at) \
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)",
|
||||
params![
|
||||
id,
|
||||
project_id,
|
||||
&id,
|
||||
&project_id,
|
||||
tracker_id,
|
||||
tracker_label,
|
||||
&tracker_label,
|
||||
polling_interval,
|
||||
"{}",
|
||||
filters_json,
|
||||
analyst_agent_id,
|
||||
developer_agent_id,
|
||||
status,
|
||||
now,
|
||||
analyst_agent_id.as_deref(),
|
||||
developer_agent_id.as_deref(),
|
||||
&status,
|
||||
&now,
|
||||
],
|
||||
)?;
|
||||
|
||||
Ok(WatchedTracker {
|
||||
id,
|
||||
project_id: project_id.to_string(),
|
||||
project_id,
|
||||
tracker_id,
|
||||
tracker_label: tracker_label.to_string(),
|
||||
tracker_label,
|
||||
polling_interval,
|
||||
analyst_agent_id,
|
||||
developer_agent_id,
|
||||
|
|
@ -232,14 +248,8 @@ mod tests {
|
|||
}
|
||||
|
||||
fn create_agents(conn: &Connection) -> (String, String) {
|
||||
let analyst = Agent::insert(
|
||||
conn,
|
||||
"Analyst",
|
||||
AgentRole::Analyst,
|
||||
AgentTool::Codex,
|
||||
"",
|
||||
)
|
||||
.unwrap();
|
||||
let analyst =
|
||||
Agent::insert(conn, "Analyst", AgentRole::Analyst, AgentTool::Codex, "").unwrap();
|
||||
|
||||
let developer = Agent::insert(
|
||||
conn,
|
||||
|
|
@ -271,13 +281,15 @@ mod tests {
|
|||
|
||||
let tracker = WatchedTracker::insert(
|
||||
&conn,
|
||||
&pid,
|
||||
42,
|
||||
"Bug Tracker",
|
||||
15,
|
||||
&analyst_id,
|
||||
&developer_id,
|
||||
sample_filters(),
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 42,
|
||||
tracker_label: "Bug Tracker".to_string(),
|
||||
polling_interval: 15,
|
||||
analyst_agent_id: analyst_id.clone(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: sample_filters(),
|
||||
},
|
||||
)
|
||||
.expect("insert should succeed");
|
||||
|
||||
|
|
@ -288,8 +300,14 @@ mod tests {
|
|||
assert_eq!(tracker.polling_interval, 15);
|
||||
assert!(tracker.enabled);
|
||||
assert_eq!(tracker.status, "valid");
|
||||
assert_eq!(tracker.analyst_agent_id.as_deref(), Some(analyst_id.as_str()));
|
||||
assert_eq!(tracker.developer_agent_id.as_deref(), Some(developer_id.as_str()));
|
||||
assert_eq!(
|
||||
tracker.analyst_agent_id.as_deref(),
|
||||
Some(analyst_id.as_str())
|
||||
);
|
||||
assert_eq!(
|
||||
tracker.developer_agent_id.as_deref(),
|
||||
Some(developer_id.as_str())
|
||||
);
|
||||
assert!(tracker.last_polled_at.is_none());
|
||||
assert!(!tracker.created_at.is_empty());
|
||||
assert_eq!(tracker.filters.len(), 1);
|
||||
|
|
@ -301,8 +319,32 @@ mod tests {
|
|||
let pid = project_id(&conn);
|
||||
let (analyst_id, developer_id) = create_agents(&conn);
|
||||
|
||||
WatchedTracker::insert(&conn, &pid, 1, "Tracker A", 10, &analyst_id, &developer_id, vec![]).unwrap();
|
||||
WatchedTracker::insert(&conn, &pid, 2, "Tracker B", 20, &analyst_id, &developer_id, vec![]).unwrap();
|
||||
WatchedTracker::insert(
|
||||
&conn,
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 1,
|
||||
tracker_label: "Tracker A".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst_id.clone(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
WatchedTracker::insert(
|
||||
&conn,
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 2,
|
||||
tracker_label: "Tracker B".to_string(),
|
||||
polling_interval: 20,
|
||||
analyst_agent_id: analyst_id.clone(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let trackers = WatchedTracker::list_by_project(&conn, &pid).expect("list should succeed");
|
||||
assert_eq!(trackers.len(), 2);
|
||||
|
|
@ -314,10 +356,35 @@ mod tests {
|
|||
let pid = project_id(&conn);
|
||||
let (analyst_id, developer_id) = create_agents(&conn);
|
||||
|
||||
let valid = WatchedTracker::insert(&conn, &pid, 1, "Valid", 10, &analyst_id, &developer_id, vec![]).unwrap();
|
||||
WatchedTracker::insert(&conn, &pid, 2, "Invalid", 10, "", &developer_id, vec![]).unwrap();
|
||||
let valid = WatchedTracker::insert(
|
||||
&conn,
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 1,
|
||||
tracker_label: "Valid".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst_id.clone(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
WatchedTracker::insert(
|
||||
&conn,
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 2,
|
||||
tracker_label: "Invalid".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: "".to_string(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let enabled = WatchedTracker::list_all_enabled(&conn).expect("list_all_enabled should succeed");
|
||||
let enabled =
|
||||
WatchedTracker::list_all_enabled(&conn).expect("list_all_enabled should succeed");
|
||||
assert_eq!(enabled.len(), 1);
|
||||
assert_eq!(enabled[0].id, valid.id);
|
||||
}
|
||||
|
|
@ -330,17 +397,20 @@ mod tests {
|
|||
|
||||
let created = WatchedTracker::insert(
|
||||
&conn,
|
||||
&pid,
|
||||
99,
|
||||
"My Tracker",
|
||||
30,
|
||||
&analyst_id,
|
||||
&developer_id,
|
||||
sample_filters(),
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 99,
|
||||
tracker_label: "My Tracker".to_string(),
|
||||
polling_interval: 30,
|
||||
analyst_agent_id: analyst_id.clone(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: sample_filters(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let found = WatchedTracker::get_by_id(&conn, &created.id).expect("get_by_id should succeed");
|
||||
let found =
|
||||
WatchedTracker::get_by_id(&conn, &created.id).expect("get_by_id should succeed");
|
||||
assert_eq!(found.id, created.id);
|
||||
assert_eq!(found.tracker_id, 99);
|
||||
assert_eq!(found.tracker_label, "My Tracker");
|
||||
|
|
@ -356,13 +426,15 @@ mod tests {
|
|||
|
||||
let created = WatchedTracker::insert(
|
||||
&conn,
|
||||
&pid,
|
||||
10,
|
||||
"Original",
|
||||
5,
|
||||
&analyst_id,
|
||||
&developer_id,
|
||||
sample_filters(),
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 10,
|
||||
tracker_label: "Original".to_string(),
|
||||
polling_interval: 5,
|
||||
analyst_agent_id: analyst_id.clone(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: sample_filters(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
@ -406,19 +478,22 @@ mod tests {
|
|||
|
||||
let created = WatchedTracker::insert(
|
||||
&conn,
|
||||
&pid,
|
||||
5,
|
||||
"Poller",
|
||||
10,
|
||||
&analyst_id,
|
||||
&developer_id,
|
||||
vec![],
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 5,
|
||||
tracker_label: "Poller".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst_id.clone(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(created.last_polled_at.is_none());
|
||||
|
||||
WatchedTracker::update_last_polled(&conn, &created.id).expect("update_last_polled should succeed");
|
||||
WatchedTracker::update_last_polled(&conn, &created.id)
|
||||
.expect("update_last_polled should succeed");
|
||||
|
||||
let updated = WatchedTracker::get_by_id(&conn, &created.id).unwrap();
|
||||
assert!(updated.last_polled_at.is_some());
|
||||
|
|
@ -432,13 +507,15 @@ mod tests {
|
|||
|
||||
let created = WatchedTracker::insert(
|
||||
&conn,
|
||||
&pid,
|
||||
7,
|
||||
"ToDelete",
|
||||
10,
|
||||
&analyst_id,
|
||||
&developer_id,
|
||||
vec![],
|
||||
NewWatchedTracker {
|
||||
project_id: pid.clone(),
|
||||
tracker_id: 7,
|
||||
tracker_label: "ToDelete".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst_id.clone(),
|
||||
developer_agent_id: developer_id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,12 @@ const SELECT_ALL_COLS: &str = "SELECT id, ticket_id, path, branch_name, status,
|
|||
created_at, merged_at, merged_into FROM worktrees";
|
||||
|
||||
impl Worktree {
|
||||
pub fn insert(conn: &Connection, ticket_id: &str, path: &str, branch_name: &str) -> Result<Worktree> {
|
||||
pub fn insert(
|
||||
conn: &Connection,
|
||||
ticket_id: &str,
|
||||
path: &str,
|
||||
branch_name: &str,
|
||||
) -> Result<Worktree> {
|
||||
let id = Uuid::new_v4().to_string();
|
||||
let now = chrono::Utc::now().to_rfc3339();
|
||||
|
||||
|
|
@ -103,7 +108,7 @@ mod tests {
|
|||
use crate::models::agent::{Agent, AgentRole, AgentTool};
|
||||
use crate::models::project::Project;
|
||||
use crate::models::ticket::ProcessedTicket;
|
||||
use crate::models::tracker::WatchedTracker;
|
||||
use crate::models::tracker::{NewWatchedTracker, WatchedTracker};
|
||||
|
||||
fn setup() -> (Connection, String) {
|
||||
let conn = db::init_in_memory().expect("db init");
|
||||
|
|
@ -113,13 +118,15 @@ mod tests {
|
|||
Agent::insert(&conn, "D", AgentRole::Developer, AgentTool::ClaudeCode, "").unwrap();
|
||||
let tracker = WatchedTracker::insert(
|
||||
&conn,
|
||||
&project.id,
|
||||
100,
|
||||
"Bugs",
|
||||
10,
|
||||
&analyst.id,
|
||||
&developer.id,
|
||||
vec![],
|
||||
NewWatchedTracker {
|
||||
project_id: project.id.clone(),
|
||||
tracker_id: 100,
|
||||
tracker_label: "Bugs".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst.id.clone(),
|
||||
developer_agent_id: developer.id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let ticket = ProcessedTicket::insert_if_new(&conn, &tracker.id, 42, "Bug 42", "{}")
|
||||
|
|
@ -165,13 +172,15 @@ mod tests {
|
|||
Agent::insert(&conn, "D", AgentRole::Developer, AgentTool::ClaudeCode, "").unwrap();
|
||||
let tracker = WatchedTracker::insert(
|
||||
&conn,
|
||||
&project.id,
|
||||
100,
|
||||
"Bugs",
|
||||
10,
|
||||
&analyst.id,
|
||||
&developer.id,
|
||||
vec![],
|
||||
NewWatchedTracker {
|
||||
project_id: project.id.clone(),
|
||||
tracker_id: 100,
|
||||
tracker_label: "Bugs".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst.id.clone(),
|
||||
developer_agent_id: developer.id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let t1 = ProcessedTicket::insert_if_new(&conn, &tracker.id, 1, "T1", "{}")
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ mod tests {
|
|||
use crate::models::agent::{Agent, AgentRole, AgentTool};
|
||||
use crate::models::project::Project;
|
||||
use crate::models::ticket::ProcessedTicket;
|
||||
use crate::models::tracker::WatchedTracker;
|
||||
use crate::models::tracker::{NewWatchedTracker, WatchedTracker};
|
||||
|
||||
fn setup() -> (Arc<Mutex<Connection>>, String) {
|
||||
let conn = db::init_in_memory().expect("db init should succeed");
|
||||
|
|
@ -159,25 +159,22 @@ mod tests {
|
|||
|
||||
let tracker = WatchedTracker::insert(
|
||||
&conn,
|
||||
project_id,
|
||||
101,
|
||||
"Bugs",
|
||||
10,
|
||||
&analyst.id,
|
||||
&developer.id,
|
||||
vec![],
|
||||
NewWatchedTracker {
|
||||
project_id: project_id.to_string(),
|
||||
tracker_id: 101,
|
||||
tracker_label: "Bugs".to_string(),
|
||||
polling_interval: 10,
|
||||
analyst_agent_id: analyst.id.clone(),
|
||||
developer_agent_id: developer.id.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
)
|
||||
.expect("tracker insert should succeed");
|
||||
|
||||
let ticket = ProcessedTicket::insert_if_new(
|
||||
&conn,
|
||||
&tracker.id,
|
||||
1,
|
||||
"Ticket 1",
|
||||
"{\"id\":1}",
|
||||
)
|
||||
.expect("ticket insert should succeed")
|
||||
.expect("ticket should be inserted");
|
||||
let ticket =
|
||||
ProcessedTicket::insert_if_new(&conn, &tracker.id, 1, "Ticket 1", "{\"id\":1}")
|
||||
.expect("ticket insert should succeed")
|
||||
.expect("ticket should be inserted");
|
||||
|
||||
ticket.id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,13 +99,15 @@ export async function addTracker(
|
|||
filters: FilterGroup[]
|
||||
): Promise<WatchedTracker> {
|
||||
return invoke("add_tracker", {
|
||||
projectId,
|
||||
trackerId,
|
||||
trackerLabel,
|
||||
pollingInterval,
|
||||
analystAgentId,
|
||||
developerAgentId,
|
||||
filters,
|
||||
payload: {
|
||||
projectId,
|
||||
trackerId,
|
||||
trackerLabel,
|
||||
pollingInterval,
|
||||
analystAgentId,
|
||||
developerAgentId,
|
||||
filters,
|
||||
},
|
||||
});
|
||||
}
|
||||
export async function listTrackers(projectId: string): Promise<WatchedTracker[]> {
|
||||
|
|
|
|||
Loading…
Reference in a new issue