feat(awooop): classify callback trace gaps
All checks were successful
CD Pipeline / tests (push) Successful in 1m33s
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / build-and-deploy (push) Successful in 3m32s
CD Pipeline / post-deploy-checks (push) Successful in 1m33s

This commit is contained in:
Your Name
2026-05-25 21:32:37 +08:00
parent f52fdebe0a
commit 32e172ed8b
7 changed files with 159 additions and 7 deletions

View File

@@ -738,6 +738,20 @@ def _callback_reply_audit_summary_from_row(
top_missing_trace_prefixes = _reply_markup_gap_prefixes_from_value(
row.get("outbound_reply_markup_missing_trace_ref_top_prefixes")
)
missing_trace_total = _safe_int(
row.get("outbound_reply_markup_missing_trace_ref_total")
)
missing_trace_recent_1h = _safe_int(
row.get("outbound_reply_markup_missing_trace_ref_recent_1h_total")
)
missing_trace_recent_24h = _safe_int(
row.get("outbound_reply_markup_missing_trace_ref_recent_24h_total")
)
trace_gap_status, trace_gap_next_action = _trace_ref_gap_decision(
total=missing_trace_total,
recent_1h=missing_trace_recent_1h,
recent_24h=missing_trace_recent_24h,
)
if callback_total <= 0:
snapshot_status = "no_callback"
@@ -785,18 +799,18 @@ def _callback_reply_audit_summary_from_row(
"outbound_reply_markup_missing_incident_ref_latest_sent_at": row.get(
"outbound_reply_markup_missing_incident_ref_latest_sent_at"
),
"outbound_reply_markup_missing_trace_ref_total": _safe_int(
row.get("outbound_reply_markup_missing_trace_ref_total")
"outbound_reply_markup_missing_trace_ref_total": missing_trace_total,
"outbound_reply_markup_missing_trace_ref_recent_1h_total": (
missing_trace_recent_1h
),
"outbound_reply_markup_missing_trace_ref_recent_1h_total": _safe_int(
row.get("outbound_reply_markup_missing_trace_ref_recent_1h_total")
),
"outbound_reply_markup_missing_trace_ref_recent_24h_total": _safe_int(
row.get("outbound_reply_markup_missing_trace_ref_recent_24h_total")
"outbound_reply_markup_missing_trace_ref_recent_24h_total": (
missing_trace_recent_24h
),
"outbound_reply_markup_missing_trace_ref_latest_sent_at": row.get(
"outbound_reply_markup_missing_trace_ref_latest_sent_at"
),
"outbound_reply_markup_trace_ref_gap_status": trace_gap_status,
"outbound_reply_markup_trace_ref_gap_next_action": trace_gap_next_action,
"outbound_reply_markup_missing_incident_ref_top_prefixes": (
top_missing_prefixes
),
@@ -822,6 +836,22 @@ def _callback_reply_audit_summary_from_row(
}
def _trace_ref_gap_decision(
*,
total: int,
recent_1h: int,
recent_24h: int,
) -> tuple[str, str]:
"""Classify reply_markup messages without any source_refs into operator actions."""
if total <= 0:
return "clean", "none"
if recent_1h > 0:
return "active_gap", "inspect_recent_outbound_source_refs"
if recent_24h > 0:
return "recent_backlog", "watch_24h_decay"
return "legacy_backlog", "backfill_or_archive_legacy_callbacks"
def _reply_markup_gap_prefixes_from_value(value: Any) -> list[dict[str, Any]]:
if not isinstance(value, list):
return []