fix(awooop): keep callback audit summary stable
All checks were successful
CD Pipeline / tests (push) Successful in 1m15s
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / build-and-deploy (push) Successful in 3m51s
CD Pipeline / post-deploy-checks (push) Successful in 1m30s

This commit is contained in:
Your Name
2026-05-25 17:07:47 +08:00
parent 0c1f9a1e37
commit 44d24b1858
3 changed files with 35 additions and 7 deletions

View File

@@ -401,7 +401,7 @@ async def list_callback_replies(
total = count_result.scalar_one()
rows_result = await db.execute(list_sql, params)
rows = list(rows_result.mappings().all())
summary = await _fetch_callback_reply_audit_summary(
audit_summary = await _fetch_callback_reply_audit_summary(
db,
project_id=project_id or "awoooi",
)
@@ -446,22 +446,22 @@ async def list_callback_replies(
item["awooop_status_chain"] = chain
summary_cache_key = (item_project_id, incident_id)
summary = km_completion_summary_cache.get(summary_cache_key)
if summary is None:
summary = await _fetch_km_stale_completion_summary_for_incident(
km_summary = km_completion_summary_cache.get(summary_cache_key)
if km_summary is None:
km_summary = await _fetch_km_stale_completion_summary_for_incident(
project_id=item_project_id,
incident_id=incident_id,
queue_cache=km_completion_queue_cache,
)
km_completion_summary_cache[summary_cache_key] = summary
item["km_stale_completion_summary"] = summary
km_completion_summary_cache[summary_cache_key] = km_summary
item["km_stale_completion_summary"] = km_summary
return {
"items": items,
"total": total,
"page": page,
"per_page": per_page,
"summary": summary,
"summary": audit_summary,
}

View File

@@ -1,4 +1,5 @@
import asyncio
import inspect
from datetime import datetime
from decimal import Decimal
from types import SimpleNamespace
@@ -706,6 +707,15 @@ def test_list_callback_replies_response_preserves_callback_evidence() -> None:
assert dumped["summary"]["snapshot_status"] == "not_captured"
def test_list_callback_replies_keeps_audit_summary_separate_from_km_summary() -> None:
source = inspect.getsource(platform_operator_service.list_callback_replies)
assert "audit_summary = await _fetch_callback_reply_audit_summary" in source
assert '"summary": audit_summary' in source
assert "km_summary = km_completion_summary_cache.get" in source
assert 'item["km_stale_completion_summary"] = km_summary' in source
def test_callback_reply_audit_summary_marks_missing_snapshots() -> None:
summary = _callback_reply_audit_summary_from_row(
{

View File

@@ -20268,6 +20268,24 @@ pnpm --dir apps/web lint -- --file 'src/app/[locale]/awooop/runs/page.tsx'
NEXT_PUBLIC_API_URL=https://awoooi.wooo.work pnpm --dir apps/web run build
```
**T183b production smoke hotfix**
- 首次 production smoke `/api/v1/platform/runs/callback-replies?project_id=awoooi&per_page=2` 回傳 HTTP 500。
- root cause`list_callback_replies()` 的 API 頂層 coverage `summary` 被每筆 callback event 的 KM completion `summary` 區域變數覆蓋FastAPI response validation 收到 `km_stale_owner_review_completion_callback_summary_v1`,因此不符合 `telegram_callback_reply_audit_summary_v1` schema。
- 修正:
- API 頂層 coverage 改名為 `audit_summary`
- 每筆事件的 KM completion summary 改名為 `km_summary`
- response 固定回傳 `"summary": audit_summary`
- 新增 regression test 防止 audit summary / KM summary 再次 shadowing。
- hotfix local validation
```text
python3 -m py_compile apps/api/src/services/platform_operator_service.py apps/api/tests/test_awooop_operator_timeline_labels.py
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
52 passed in 0.80s
```
**目前整體進度**
- AwoooP 告警可觀測鏈:約 99.52%。