//! `upsert_task` against the partial unique index it depends on. //! //! `mission_tasks_external_uniq` is declared `WHERE external_id IS NOT NULL`. //! Postgres will not match a partial index to an `ON CONFLICT` target unless //! the statement repeats that predicate, so the upsert raised 42P10 on its //! first row for every caller — the task-card parser (INT markers) and the //! security scanner. Both map the error to a string their caller logs, so the //! feature was broken and the platform stayed green. //! //! The insert half and the update half are tested separately because they fail //! differently: a missing conflict target breaks both, but a wrong DO UPDATE //! breaks only the second write, which is the one that happens on re-run. use cm_db::repo::missions::{upsert_task, UpsertTask}; use cm_domain::{Workspace, WorkspaceId}; use uuid::Uuid; async fn seed_phase(pool: &sqlx::PgPool) -> (Uuid, Uuid) { let ws = Workspace { id: WorkspaceId::new(), name: "Task Upsert Test".into(), plan: "team".into(), }; cm_db::repo::workspaces::insert(pool, &ws).await.unwrap(); let mission = Uuid::now_v7(); sqlx::query( "INSERT INTO missions (id, workspace_id, title, template_kind, status) VALUES ($1, $2, 'upsert test', 'security_hardening', 'running')", ) .bind(mission) .bind(ws.id.as_uuid()) .execute(pool) .await .unwrap(); let phase = Uuid::now_v7(); sqlx::query( "INSERT INTO mission_phases (id, mission_id, kind, order_idx, status) VALUES ($1, $2, 'security_scan', 0, 'completed')", ) .bind(phase) .bind(mission) .execute(pool) .await .unwrap(); (mission, phase) } #[tokio::test] async fn the_same_external_id_updates_in_place_instead_of_erroring() { let pool = cm_testkit::test_pool().await; let (mission_id, phase_id) = seed_phase(&pool).await; let first = upsert_task( &pool, UpsertTask { mission_id, phase_id, external_id: "RUSTSEC-2026-0001", title: "advisory: something", assigned_agent_id: None, status: "created", run_id: None, }, ) .await .expect("first upsert must succeed — 42P10 here means the ON CONFLICT \ target no longer matches the partial unique index"); // The re-run. A scanner that finds the same advisory twice must not // duplicate the row, and must not fail. let second = upsert_task( &pool, UpsertTask { mission_id, phase_id, external_id: "RUSTSEC-2026-0001", title: "advisory: something (rescanned)", assigned_agent_id: None, status: "complete", run_id: None, }, ) .await .expect("second upsert must succeed"); assert_eq!(first, second, "the same (phase_id, external_id) must be one row"); let (title, status, completed): (String, String, Option) = sqlx::query_as("SELECT title, status, completed_at FROM mission_tasks WHERE id = $1") .bind(first) .fetch_one(&pool) .await .unwrap(); assert_eq!(title, "advisory: something (rescanned)"); assert_eq!(status, "complete"); assert!( completed.is_some(), "a task upserted as `complete` must get its completed_at stamped" ); let n: i64 = sqlx::query_scalar("SELECT count(*) FROM mission_tasks WHERE phase_id = $1") .bind(phase_id) .fetch_one(&pool) .await .unwrap(); assert_eq!(n, 1, "two upserts of one external_id left {n} rows"); }