From 1baa21222bcc42c803abf0686acbb40236f078bc Mon Sep 17 00:00:00 2001 From: Neo Date: Tue, 5 May 2026 11:52:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(backend):=20F1-5a=20=E8=B5=B0=E6=9F=A5?= =?UTF-8?q?=E5=8F=91=E7=8E=B0=202=20=E4=B8=AA=E7=94=9F=E4=BA=A7=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - xcx_runtime_clock.py: require_approved 是 factory,Depends 必须 () 调用,否则 user 是 function 不是 CurrentUser → AttributeError 500 → 沙盒在小程序所有页面失效的根因(getBusinessClock 一直降级 localFallback) - admin_service.py:retry_trigger_job INSERT payload 字段是 jsonb, psycopg2 读出是 dict,未 Json() wrap 直接 INSERT 触发 "can't adapt type 'dict'" → 生产环境点重试必 500 (该 bug 在 6f8f1231 即引入,F1-5a 走查时通过 SQL 复现端到端验证暴露) 走查覆盖: - xcx_runtime_clock: 修后小程序 GET /api/xcx/runtime/clock 200, 返回完整 sandbox ctx(business_date / sandbox_instance_id) - retry_trigger_job: SQL 复现 INSERT 包含真实 jsonb payload ({foo:bar,n:42}),修后 runtime_mode=sandbox + sandbox_instance_id + payload 完整保留全部 PASS Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/backend/app/routers/xcx_runtime_clock.py | 2 +- apps/backend/app/services/ai/admin_service.py | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/backend/app/routers/xcx_runtime_clock.py b/apps/backend/app/routers/xcx_runtime_clock.py index c72e3c2..502871f 100644 --- a/apps/backend/app/routers/xcx_runtime_clock.py +++ b/apps/backend/app/routers/xcx_runtime_clock.py @@ -26,7 +26,7 @@ router = APIRouter(prefix="/api/xcx/runtime", tags=["小程序业务时钟"]) @router.get("/clock") @trace_service("获取业务时钟", "Get business clock") async def get_business_clock( - user: CurrentUser = Depends(require_approved), + user: CurrentUser = Depends(require_approved()), ): """返回当前门店的业务时钟。 diff --git a/apps/backend/app/services/ai/admin_service.py b/apps/backend/app/services/ai/admin_service.py index 6a1ad7b..a4b0225 100644 --- a/apps/backend/app/services/ai/admin_service.py +++ b/apps/backend/app/services/ai/admin_service.py @@ -15,6 +15,8 @@ import uuid from datetime import datetime, timezone, timedelta from typing import TYPE_CHECKING, Any +import psycopg2.extras + from app.ai.budget_tracker import BudgetTracker from app.database import get_connection from app.services.runtime_context import ( @@ -390,7 +392,11 @@ class AdminAIService: original.get("member_id"), site_id, original.get("connector_type", "feiqiu"), - original.get("payload"), + # F1-5a 走查发现:psycopg2 把 jsonb 列读成 dict, + # INSERT 时需 Json() 适配,否则 "can't adapt type 'dict'" + psycopg2.extras.Json(original["payload"]) + if original.get("payload") is not None + else None, original.get("app_chain"), *runtime_params, ),