From cc4265c0768d9e4c189e1da38244eafcd3ec10c9 Mon Sep 17 00:00:00 2001 From: ogt Date: Wed, 15 Jul 2026 20:25:17 +0800 Subject: [PATCH] fix(ansible): persist scheduled candidate incidents --- apps/api/src/models/incident.py | 1 + .../services/awooop_ansible_audit_service.py | 12 +++++- ...st_incident_signal_source_compatibility.py | 8 +++- .../api/tests/test_sre_typed_domain_router.py | 37 +++++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/apps/api/src/models/incident.py b/apps/api/src/models/incident.py index b648a8446..e1e4cc0d9 100644 --- a/apps/api/src/models/incident.py +++ b/apps/api/src/models/incident.py @@ -84,6 +84,7 @@ SignalSource = Literal[ "node-exporter", "sensor-probe", "sensor-agent", + "iwooos_scheduler", ] SIGNAL_SOURCE_VALUES: frozenset[str] = frozenset(get_args(SignalSource)) diff --git a/apps/api/src/services/awooop_ansible_audit_service.py b/apps/api/src/services/awooop_ansible_audit_service.py index 58e46d7d5..16f49c11d 100644 --- a/apps/api/src/services/awooop_ansible_audit_service.py +++ b/apps/api/src/services/awooop_ansible_audit_service.py @@ -1520,7 +1520,11 @@ async def _ensure_ansible_incident_ledger_with_db( proposal_ids, alertname, notification_type, - alert_category + alert_category, + created_at, + updated_at, + ttl_days, + vectorized ) VALUES ( :incident_id, :project_id, @@ -1532,7 +1536,11 @@ async def _ensure_ansible_incident_ledger_with_db( CAST('[]' AS json), :alertname, :notification_type, - :alert_category + :alert_category, + NOW(), + NOW(), + 7, + FALSE ) ON CONFLICT (incident_id) DO NOTHING RETURNING incident_id diff --git a/apps/api/tests/test_incident_signal_source_compatibility.py b/apps/api/tests/test_incident_signal_source_compatibility.py index a924eaa3c..69b7244c0 100644 --- a/apps/api/tests/test_incident_signal_source_compatibility.py +++ b/apps/api/tests/test_incident_signal_source_compatibility.py @@ -17,7 +17,13 @@ from src.repositories.incident_repository import IncidentDBRepository from src.services.incident_engine import IncidentEngineAdapter from src.services.incident_service import IncidentService -SENSOR_SOURCES = ("journal", "node-exporter", "sensor-probe", "sensor-agent") +SENSOR_SOURCES = ( + "journal", + "node-exporter", + "sensor-probe", + "sensor-agent", + "iwooos_scheduler", +) D037_INCIDENT_ID = "INC-20260711-D037E5" diff --git a/apps/api/tests/test_sre_typed_domain_router.py b/apps/api/tests/test_sre_typed_domain_router.py index 83884d81a..cfe1d9cb7 100644 --- a/apps/api/tests/test_sre_typed_domain_router.py +++ b/apps/api/tests/test_sre_typed_domain_router.py @@ -159,6 +159,43 @@ class _GenerationDb: raise AssertionError(f"unexpected SQL: {sql}") +@pytest.mark.asyncio +async def test_candidate_incident_ledger_supplies_required_runtime_columns( + monkeypatch: pytest.MonkeyPatch, +) -> None: + db = _GenerationDb(None) + + @asynccontextmanager + async def fake_db_context(_project_id: str = "awoooi"): + yield db + + monkeypatch.setattr( + "src.services.awooop_ansible_audit_service.get_db_context", + fake_db_context, + ) + + inserted = await record_ansible_decision_audit( + incident=_sentry_runtime_incident(), + proposal_data=_sentry_runtime_proposal("alert-current-1"), + decision_path="repair_candidate_controlled_queue", + not_used_reason="production incident ledger contract", + automation_run_id="00000000-0000-0000-0000-000000471307", + ) + + assert inserted is True + incident_insert = next( + sql + for sql in db.statements + if "WITH inserted AS" in sql and "INSERT INTO incidents" in sql + ) + assert "created_at" in incident_insert + assert "updated_at" in incident_insert + assert "ttl_days" in incident_insert + assert "vectorized" in incident_insert + assert "NOW()" in incident_insert + assert "FALSE" in incident_insert + + def test_unknown_registry_identity_fails_closed_without_restart_fallback() -> None: registry = ServiceRegistryClient(REGISTRY)