fix(api): record approval gate timeline events
Some checks failed
CD Pipeline / tests (push) Successful in 1m25s
Code Review / ai-code-review (push) Successful in 15s
CD Pipeline / build-and-deploy (push) Successful in 4m12s
CD Pipeline / post-deploy-checks (push) Failing after 11s

This commit is contained in:
Your Name
2026-06-04 15:26:56 +08:00
parent 6be8dfa0f5
commit 1ae8f809af
6 changed files with 277 additions and 4 deletions

View File

@@ -0,0 +1,60 @@
from types import SimpleNamespace
from src.models.approval import ApprovalStatus, RiskLevel
from src.services.approval_db import build_approval_created_timeline_event
def test_pending_approval_timeline_event_exposes_operator_gate() -> None:
record = SimpleNamespace(
id="approval-pending-1",
action="kubectl rollout restart deployment/api",
status=ApprovalStatus.PENDING,
risk_level=RiskLevel.MEDIUM,
required_signatures=1,
current_signatures=0,
requested_by="openclaw",
incident_id="INC-20260604-TEST01",
)
event = build_approval_created_timeline_event(record)
assert event.event_type == "human"
assert event.status == "warning"
assert event.title == "Approval gate waiting for human decision"
assert event.actor == "openclaw"
assert event.actor_role == "approval_gate"
assert event.risk_level == "medium"
assert event.approval_id == "approval-pending-1"
assert event.incident_id == "INC-20260604-TEST01"
assert "stage=approval_required" in event.description
assert "next_action=operator_approve_or_reject" in event.description
assert "blocked_reason=waiting_for_required_signatures" in event.description
assert "auto_or_manual=manual" in event.description
assert "needs_human=yes" in event.description
assert "signatures=0/1" in event.description
def test_low_risk_auto_approved_timeline_event_exposes_auto_gate() -> None:
record = SimpleNamespace(
id="approval-auto-1",
action="collect read-only diagnostics",
status=ApprovalStatus.APPROVED,
risk_level=RiskLevel.LOW,
required_signatures=0,
current_signatures=0,
requested_by="openclaw",
incident_id="INC-20260604-TEST02",
)
event = build_approval_created_timeline_event(record)
assert event.event_type == "human"
assert event.status == "success"
assert event.title == "Approval gate passed"
assert event.risk_level == "low"
assert "stage=approval_auto_approved" in event.description
assert "next_action=execute_or_verify" in event.description
assert "blocked_reason=none" in event.description
assert "auto_or_manual=auto" in event.description
assert "needs_human=no" in event.description
assert "signatures=0/0" in event.description

View File

@@ -421,6 +421,32 @@ def test_reconciliation_blocks_open_incident_after_no_action_approval() -> None:
assert "timeline_missing_for_approval" in codes
def test_reconciliation_accepts_approval_with_raw_timeline_event() -> None:
reconciliation = build_incident_reconciliation(
incident={"incident_id": "INC-1", "status": "INVESTIGATING"},
approvals=[
{
"id": "approval-1",
"status": "PENDING",
"action": "kubectl rollout restart deployment/api",
}
],
evidence_rows=[],
automation_ops=[],
timeline_events=[
{
"event_type": "human",
"status": "warning",
"approval_id": "approval-1",
}
],
)
codes = {row["code"] for row in reconciliation["mismatches"]}
assert "timeline_missing_for_approval" not in codes
assert reconciliation["facts"]["timeline_events"] == 1
def test_reconciliation_counts_auto_repair_execution_as_real_execution() -> None:
reconciliation = build_incident_reconciliation(
incident={"incident_id": "INC-2", "status": "INVESTIGATING"},