diff --git a/apps/api/src/services/platform_operator_service.py b/apps/api/src/services/platform_operator_service.py index 71085a58..2ad6f878 100644 --- a/apps/api/src/services/platform_operator_service.py +++ b/apps/api/src/services/platform_operator_service.py @@ -582,7 +582,7 @@ def _callback_reply_audit_summary_from_row( next_action = "press_telegram_detail_or_history" elif captured > 0 and (missing > 0 or partial > 0): snapshot_status = "partial" - next_action = "press_telegram_detail_or_history_after_rollout" + next_action = "review_legacy_callback_snapshot_gap" elif partial > 0: snapshot_status = "partial" next_action = "press_telegram_detail_or_history_after_rollout" diff --git a/apps/api/tests/test_awooop_operator_timeline_labels.py b/apps/api/tests/test_awooop_operator_timeline_labels.py index 97300879..7365d1d9 100644 --- a/apps/api/tests/test_awooop_operator_timeline_labels.py +++ b/apps/api/tests/test_awooop_operator_timeline_labels.py @@ -680,7 +680,7 @@ def test_list_callback_replies_response_preserves_callback_evidence() -> None: "callback_snapshot_missing_total": 1, "callback_incident_total": 2, "snapshot_status": "partial", - "next_action": "press_telegram_detail_or_history_after_rollout", + "next_action": "review_legacy_callback_snapshot_gap", "latest_outbound_at": datetime(2026, 5, 18, 7, 40, 0), "latest_callback_at": datetime(2026, 5, 18, 7, 31, 37), }, @@ -777,7 +777,7 @@ def test_callback_reply_audit_summary_marks_mixed_legacy_snapshots_partial() -> assert summary["callback_snapshot_captured_total"] == 1 assert summary["callback_snapshot_missing_total"] == 2 assert summary["snapshot_status"] == "partial" - assert summary["next_action"] == "press_telegram_detail_or_history_after_rollout" + assert summary["next_action"] == "review_legacy_callback_snapshot_gap" @pytest.mark.asyncio diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 1898a33f..412b6361 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -2853,6 +2853,7 @@ "none": "No follow-up needed", "press_telegram_detail_or_history": "Press Telegram Detail / History once to create callback evidence", "press_telegram_detail_or_history_after_rollout": "Press Telegram Detail / History again to capture the new snapshot", + "review_legacy_callback_snapshot_gap": "New callbacks are captured; legacy missing snapshots do not need another press", "review_outbound_source_refs": "Review outbound source_refs gaps", "observed": "Wait for the next callback evidence" } diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 5d17550c..f5ff08ab 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -2854,6 +2854,7 @@ "none": "不需補動作", "press_telegram_detail_or_history": "按一次 Telegram 詳情 / 歷史產生 callback evidence", "press_telegram_detail_or_history_after_rollout": "重新按 Telegram 詳情 / 歷史補新版 snapshot", + "review_legacy_callback_snapshot_gap": "新版已捕捉;舊 callback 缺 snapshot 不需重複按", "review_outbound_source_refs": "檢查 outbound source_refs 缺口", "observed": "等待下一次 callback evidence" } diff --git a/apps/web/src/app/[locale]/awooop/runs/page.tsx b/apps/web/src/app/[locale]/awooop/runs/page.tsx index 7de32284..4ef9fc4f 100644 --- a/apps/web/src/app/[locale]/awooop/runs/page.tsx +++ b/apps/web/src/app/[locale]/awooop/runs/page.tsx @@ -1967,6 +1967,7 @@ function CallbackReplyAuditSummaryPanel({ nextActionRaw === "none" || nextActionRaw === "press_telegram_detail_or_history" || nextActionRaw === "press_telegram_detail_or_history_after_rollout" || + nextActionRaw === "review_legacy_callback_snapshot_gap" || nextActionRaw === "review_outbound_source_refs" ) ? nextActionRaw : "observed"; const sourceRefCoverage = formatCoveragePercent( diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 8b7e0365..3c1f1f37 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -20447,3 +20447,52 @@ post-deploy e2e-smoke container = finished - KM governance:約 84.6%。 - AI Provider lane visibility:約 92.2%。 - 完整 AI 自動化管理產品化:約 97.3%。 + +--- + +## 2026-05-25 T185 — Callback Coverage 下一步語意去重複化 + +**背景**: + +- T184 實機驗證後,callback coverage 已變成 `callback_total=3`、`captured=1`、`missing=2`、`snapshot_status=partial`。 +- 但 summary `next_action` 仍顯示 `press_telegram_detail_or_history_after_rollout`,會讓 operator 誤以為還要一直重複按 Telegram 詳情 / 歷史。 +- 實際狀態應是:新版 callback snapshot 已成功捕捉;剩下兩筆是 legacy callback 的歷史缺口,不能靠重複按同一筆舊訊息消除,只需追蹤新 callback 是否 captured。 + +**本輪修正**: + +- mixed captured + legacy missing 的 summary `next_action` 改為 `review_legacy_callback_snapshot_gap`。 +- 前端 i18n 新增下一步文案: + - zh-TW:`新版已捕捉;舊 callback 缺 snapshot 不需重複按` + - en:`New callbacks are captured; legacy missing snapshots do not need another press` +- Run 監控 `TG Callback Evidence` 會保留 `partial` 與 captured/missing 數據,同時避免引導 operator 重複點擊 Telegram。 + +**local validation(完成)**: + +```text +python3 -m py_compile apps/api/src/services/platform_operator_service.py apps/api/tests/test_awooop_operator_timeline_labels.py +jq empty apps/web/messages/zh-TW.json apps/web/messages/en.json +git diff --check +PYTHONPATH=. DATABASE_URL='postgresql+asyncpg://test:test@localhost/test' /Users/ogt/.pyenv/shims/pytest tests/test_awooop_operator_timeline_labels.py -q + 53 passed in 1.00s +pnpm --dir apps/web exec tsc --noEmit --tsBuildInfoFile /tmp/awoooi-t185-tsconfig.tsbuildinfo +pnpm --dir apps/web lint -- --file 'src/app/[locale]/awooop/runs/page.tsx' + pass with pre-existing i18next/no-literal-string warnings in the same file +NEXT_PUBLIC_API_URL=https://awoooi.wooo.work pnpm --dir apps/web run build + pass; Sentry global-error / instrumentation-client warnings are pre-existing +``` + +**目前整體進度**: + +- AwoooP 告警可觀測鏈:約 99.59%。 +- 低風險自動修復閉環:約 95.8%。 +- 前端 AI 自動化管理介面同步:約 99.15%。 +- 首頁 KPI / 小龍蝦流程 truth alignment:約 96.5%。 +- Telegram 詳情 / 歷史可追溯:約 99.0%。 +- Telegram outbound / callback DB coverage 可視化:約 98.9%。 +- callback / DB replayability:約 98.5%。 +- MCP / 自建 MCP 可視化:約 95.1%。 +- Sentry / SigNoz source correlation:約 93.6%。 +- Ansible / PlayBook 可視化:約 92.6%。 +- KM governance:約 84.6%。 +- AI Provider lane visibility:約 92.2%。 +- 完整 AI 自動化管理產品化:約 97.35%。