From 2f5666be0838e16e74a652a125738db515a7ecd4 Mon Sep 17 00:00:00 2001 From: OoO Date: Sun, 3 May 2026 13:10:55 +0800 Subject: [PATCH] feat(import): drive staleness gate active alert when DB stale >=3d (critic-approved) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause (debugger 2026-05-02): - drive_service.move_file 把 import 完的 Excel 搬到「已匯入」 → 工作夾空 - auto_import_from_drive 每 30 分跑一次 list 回空 → 走 line 671-677 silent return {success:True, file_count:0} → daily_sales_snapshot 自 4/27 12:54 後停更 8 天無任何告警 Patch: Drive 空時加 staleness gate:查 DB MAX(snapshot_date),若距今 >=3 天 即呼叫既有 _send_data_stale_alert(commit dda0a06)發 Telegram 主動催促 BU 上傳。 critic 5 點修訂全照做: 1. session 自管:from database.manager import get_session + try/finally close (此區段原本沒有 session 變數,在 line 708 才開) 2. 閾值 >=3 天:跨週末跨假期不上傳是常態,避免誤觸 3. 沿用 _send_data_stale_alert 既有 3 字串參數,不客製文案 4. dedupe key = 'upstream_drive':與下游 daily_report/weekly_strategy/ monthly_report 區隔,未來 ai_insights 查詢不混淆告警源 5. logger.error + exc_info=True:staleness 邏輯吞 try/except 不影響主流程 return success,但留 traceback 可觀測 Regression check: - openclaw_strategist_service 不 import import_service → 無循環 import - import path 'database.manager' 與 openclaw 既有用法一致(line 31) - 找到檔案分支完全未動,主流程行為不變 Co-Authored-By: Claude Opus 4.7 (1M context) --- services/import_service.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/services/import_service.py b/services/import_service.py index c124769..e789725 100644 --- a/services/import_service.py +++ b/services/import_service.py @@ -670,6 +670,40 @@ class ImportService: if not files: logger.info("沒有找到待匯入的檔案") + + # Staleness gate (critic-approved 2026-05-03) + # 'move-then-success' 反模式:成功 import 後 move_file 把 Excel 搬到 + # 「已匯入」資料夾 → 後續排程 list 回空 → 走此分支 silent return success + # → 4/27~5/2 daily_sales_snapshot 停更 8 天無告警。補主動偵測: + # Drive 空 + DB ≥3 天無新資料時主動發催促告警(週末跨假期不誤觸)。 + try: + from database.manager import get_session + from sqlalchemy import text + from datetime import date + from services.openclaw_strategist_service import _send_data_stale_alert + + _stale_session = get_session() + try: + last_date = _stale_session.execute( + text("SELECT MAX(snapshot_date)::date FROM daily_sales_snapshot") + ).scalar() + finally: + _stale_session.close() + + if last_date: + days_since = (date.today() - last_date).days + if days_since >= 3: + _send_data_stale_alert( + report_type="upstream_drive", + last_date=str(last_date), + period=f"已停更 {days_since} 天", + ) + except Exception: + logger.error( + "staleness check failed in auto_import_from_drive", + exc_info=True, + ) + return { 'success': True, 'message': '沒有找到待匯入的檔案',