feat(awooop): classify callback trace gaps
This commit is contained in:
@@ -3061,6 +3061,7 @@
|
||||
"outboundDetail": "source_refs {sourceRefs}; trace refs {traceRefs}; incident refs {incidentRefs}; coverage {coverage}",
|
||||
"outboundReplyMarkupDetail": "reply_markup {replyMarkup}; missing trace refs {missingTraceRefs}; missing incident refs {missingIncidentRefs}",
|
||||
"outboundReplyMarkupTraceFreshness": "Missing trace activity: 1h {recent1h} / 24h {recent24h} / latest {latest}",
|
||||
"outboundReplyMarkupTraceDecision": "Trace gap decision: {status}; next: {action}",
|
||||
"outboundReplyMarkupIncidentFreshness": "Missing incident activity: 1h {recent1h} / 24h {recent24h} / latest {latest}",
|
||||
"outboundReplyMarkupTopPrefixes": "Missing incident top prefixes: {prefixes}",
|
||||
"outboundReplyMarkupTraceTopPrefixes": "Missing trace top prefixes: {prefixes}",
|
||||
@@ -3080,6 +3081,20 @@
|
||||
"no_callback": "No callback yet",
|
||||
"observed": "Recorded"
|
||||
},
|
||||
"traceGapStatuses": {
|
||||
"clean": "Clean",
|
||||
"active_gap": "Active gap",
|
||||
"recent_backlog": "Recent backlog",
|
||||
"legacy_backlog": "Legacy backlog",
|
||||
"observed": "Recorded"
|
||||
},
|
||||
"traceGapNextActions": {
|
||||
"none": "No follow-up needed",
|
||||
"inspect_recent_outbound_source_refs": "Inspect outbound source_refs from the last hour",
|
||||
"watch_24h_decay": "Watch the 24h window decay to zero",
|
||||
"backfill_or_archive_legacy_callbacks": "Backfill or archive legacy callback gaps",
|
||||
"observed": "Wait for the next outbound evidence"
|
||||
},
|
||||
"nextActions": {
|
||||
"none": "No follow-up needed",
|
||||
"press_telegram_detail_or_history": "Press Telegram Detail / History once to create callback evidence",
|
||||
|
||||
@@ -3062,6 +3062,7 @@
|
||||
"outboundDetail": "source_refs {sourceRefs};trace refs {traceRefs};incident refs {incidentRefs};覆蓋 {coverage}",
|
||||
"outboundReplyMarkupDetail": "reply_markup {replyMarkup};缺 trace refs {missingTraceRefs};缺 incident refs {missingIncidentRefs}",
|
||||
"outboundReplyMarkupTraceFreshness": "缺 trace 活躍度:1h {recent1h} / 24h {recent24h} / 最新 {latest}",
|
||||
"outboundReplyMarkupTraceDecision": "缺 trace 判讀:{status};下一步:{action}",
|
||||
"outboundReplyMarkupIncidentFreshness": "缺 incident 活躍度:1h {recent1h} / 24h {recent24h} / 最新 {latest}",
|
||||
"outboundReplyMarkupTopPrefixes": "缺 incident top prefixes:{prefixes}",
|
||||
"outboundReplyMarkupTraceTopPrefixes": "缺 trace top prefixes:{prefixes}",
|
||||
@@ -3081,6 +3082,20 @@
|
||||
"no_callback": "尚無 callback",
|
||||
"observed": "已記錄"
|
||||
},
|
||||
"traceGapStatuses": {
|
||||
"clean": "乾淨",
|
||||
"active_gap": "新缺口",
|
||||
"recent_backlog": "近期歷史債",
|
||||
"legacy_backlog": "歷史待清",
|
||||
"observed": "已記錄"
|
||||
},
|
||||
"traceGapNextActions": {
|
||||
"none": "不需補動作",
|
||||
"inspect_recent_outbound_source_refs": "檢查近 1 小時 outbound source_refs",
|
||||
"watch_24h_decay": "觀察 24 小時窗口自然歸零",
|
||||
"backfill_or_archive_legacy_callbacks": "歸檔或回補舊 callback 缺口",
|
||||
"observed": "等待下一次 outbound evidence"
|
||||
},
|
||||
"nextActions": {
|
||||
"none": "不需補動作",
|
||||
"press_telegram_detail_or_history": "按一次 Telegram 詳情 / 歷史產生 callback evidence",
|
||||
|
||||
@@ -160,6 +160,8 @@ interface CallbackReplyAuditSummary {
|
||||
outbound_reply_markup_missing_trace_ref_recent_1h_total?: number;
|
||||
outbound_reply_markup_missing_trace_ref_recent_24h_total?: number;
|
||||
outbound_reply_markup_missing_trace_ref_latest_sent_at?: string | null;
|
||||
outbound_reply_markup_trace_ref_gap_status?: string | null;
|
||||
outbound_reply_markup_trace_ref_gap_next_action?: string | null;
|
||||
outbound_reply_markup_missing_incident_ref_top_prefixes?: Array<{
|
||||
prefix?: string | null;
|
||||
total?: number | null;
|
||||
@@ -2527,6 +2529,22 @@ function CallbackReplyAuditSummaryPanel({
|
||||
const latestMissingIncidentRef = formatShortDateTime(
|
||||
summary.outbound_reply_markup_missing_incident_ref_latest_sent_at
|
||||
);
|
||||
const traceGapStatusRaw =
|
||||
summary.outbound_reply_markup_trace_ref_gap_status ?? "observed";
|
||||
const traceGapStatusKey = (
|
||||
traceGapStatusRaw === "clean" ||
|
||||
traceGapStatusRaw === "active_gap" ||
|
||||
traceGapStatusRaw === "recent_backlog" ||
|
||||
traceGapStatusRaw === "legacy_backlog"
|
||||
) ? traceGapStatusRaw : "observed";
|
||||
const traceGapNextActionRaw =
|
||||
summary.outbound_reply_markup_trace_ref_gap_next_action ?? "observed";
|
||||
const traceGapNextActionKey = (
|
||||
traceGapNextActionRaw === "none" ||
|
||||
traceGapNextActionRaw === "inspect_recent_outbound_source_refs" ||
|
||||
traceGapNextActionRaw === "watch_24h_decay" ||
|
||||
traceGapNextActionRaw === "backfill_or_archive_legacy_callbacks"
|
||||
) ? traceGapNextActionRaw : "observed";
|
||||
const snapshotClass = {
|
||||
captured: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
|
||||
partial: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
|
||||
@@ -2573,6 +2591,12 @@ function CallbackReplyAuditSummaryPanel({
|
||||
latest: latestMissingTraceRef,
|
||||
})}
|
||||
</p>
|
||||
<p className="mt-1 text-xs font-semibold leading-5 text-[#141413]">
|
||||
{t("outboundReplyMarkupTraceDecision", {
|
||||
status: t(`traceGapStatuses.${traceGapStatusKey}` as never),
|
||||
action: t(`traceGapNextActions.${traceGapNextActionKey}` as never),
|
||||
})}
|
||||
</p>
|
||||
<p className="mt-1 text-xs leading-5 text-[#5f5b52]">
|
||||
{t("outboundReplyMarkupIncidentFreshness", {
|
||||
recent1h:
|
||||
|
||||
Reference in New Issue
Block a user