feat(awooop): preview recurrence repair work items
All checks were successful
Code Review / ai-code-review (push) Successful in 10s
CD Pipeline / tests (push) Successful in 1m11s
CD Pipeline / build-and-deploy (push) Successful in 3m33s
CD Pipeline / post-deploy-checks (push) Successful in 1m32s

This commit is contained in:
Your Name
2026-05-18 21:42:20 +08:00
parent 51660ecbb1
commit d1ebcdac10
6 changed files with 925 additions and 4 deletions

View File

@@ -8,9 +8,12 @@ from fastapi import HTTPException
from src.api.v1.platform.events import ChannelEventRecurrenceResponse
from src.services import channel_event_dossier_service
from src.services.channel_event_dossier_service import (
RecurrenceWorkItemNotFoundError,
build_dossier_coverage,
build_dossier_event,
build_dossier_recurrence,
build_recurrence_work_item_dry_run,
build_recurrence_work_item_preview,
fetch_channel_event_dossier,
fetch_channel_event_dossier_coverage,
fetch_channel_event_dossier_recurrence,
@@ -345,6 +348,133 @@ def test_build_dossier_recurrence_opens_work_item_for_completed_run_without_repa
}
def test_build_recurrence_work_item_preview_selects_ticket_mode() -> None:
recurrence = build_dossier_recurrence(
[
{
"event_id": "event-1",
"project_id": "awoooi",
"channel_type": "internal",
"provider_event_id": "alertmanager:received:1",
"content_hash": "a" * 64,
"content_preview": "Docker container unhealthy",
"content_redacted": "Docker container unhealthy",
"redaction_version": "audit_sink_v1",
"source_envelope": {
"provider": "alertmanager",
"source_refs": {
"alert_ids": ["alert-1"],
"incident_ids": ["INC-20260517-F25B4A"],
"fingerprints": ["fp-container-unhealthy"],
},
"log_correlation": {
"alertname": "DockerContainerUnhealthy",
"severity": "warning",
"namespace": "momo",
"target_resource": "bitan-pharmacy-bitan-1",
"fingerprint": "fp-container-unhealthy",
},
},
"is_duplicate": True,
"provider_ts": None,
"received_at": "2026-05-17T23:47:00",
"run_id": UUID("33333333-3333-4333-8333-333333333333"),
"run_state": "completed",
"run_agent_id": "openclaw",
}
],
project_id="awoooi",
limit=20,
)
preview = build_recurrence_work_item_preview(
recurrence,
work_item_id="incident:INC-20260517-F25B4A",
)
assert preview["schema_version"] == "awooop_recurrence_work_item_preview_v1"
assert preview["source"] == "channel_event_dossier.recurrence"
assert preview["mode"] == "ticket"
assert preview["allowed"] is True
assert preview["writes_incident_state"] is False
assert preview["writes_auto_repair_result"] is False
assert preview["writes_ticket"] is False
assert preview["plan"]["step"] == "prepare_repair_ticket_preview"
assert preview["plan"]["target"]["alertname"] == "DockerContainerUnhealthy"
def test_build_recurrence_work_item_dry_run_returns_ticket_preview_without_writes() -> None:
recurrence = build_dossier_recurrence(
[
{
"event_id": "event-1",
"project_id": "awoooi",
"channel_type": "internal",
"provider_event_id": "alertmanager:received:1",
"content_hash": "a" * 64,
"content_preview": "Docker container unhealthy",
"content_redacted": "Docker container unhealthy",
"redaction_version": "audit_sink_v1",
"source_envelope": {
"provider": "alertmanager",
"source_refs": {
"alert_ids": ["alert-1"],
"incident_ids": ["INC-20260517-F25B4A"],
"fingerprints": ["fp-container-unhealthy"],
},
"log_correlation": {
"alertname": "DockerContainerUnhealthy",
"severity": "warning",
"namespace": "momo",
"target_resource": "bitan-pharmacy-bitan-1",
"fingerprint": "fp-container-unhealthy",
},
},
"is_duplicate": True,
"provider_ts": None,
"received_at": "2026-05-17T23:47:00",
"run_id": UUID("33333333-3333-4333-8333-333333333333"),
"run_state": "completed",
"run_agent_id": "openclaw",
}
],
project_id="awoooi",
limit=20,
)
dry_run = build_recurrence_work_item_dry_run(
recurrence,
work_item_id="incident:INC-20260517-F25B4A",
)
assert dry_run["schema_version"] == "awooop_recurrence_work_item_dry_run_v1"
assert dry_run["mode"] == "ticket"
assert dry_run["allowed"] is True
assert dry_run["executed"] is True
assert dry_run["writes_incident_state"] is False
assert dry_run["writes_auto_repair_result"] is False
assert dry_run["writes_ticket"] is False
assert dry_run["verification_result_preview"] == "ticket_preview_ready"
assert dry_run["ticket_preview"]["would_create"] is False
assert "DockerContainerUnhealthy" in dry_run["ticket_preview"]["title"]
assert dry_run["current_state_summary"]["repair_status"] == "run_completed_no_repair"
assert dry_run["read_model_route"]["required_scope"] == "read"
def test_build_recurrence_work_item_preview_raises_for_missing_item() -> None:
recurrence = build_dossier_recurrence(
[],
project_id="awoooi",
limit=20,
)
with pytest.raises(RecurrenceWorkItemNotFoundError):
build_recurrence_work_item_preview(
recurrence,
work_item_id="incident:INC-20260517-MISSING",
)
def test_recurrence_response_model_preserves_repair_work_item_fields() -> None:
response = ChannelEventRecurrenceResponse.model_validate(
{