fix(report): FE 问卷键名双侧兼容 + worker 持久事件循环(live E2E 两处修复)
CI / lint / typecheck / import-linter / tests / secrets (push) Canceled after 0s

FE↔后端联调实测暴露并修复:
1. 问卷键名三处错位(FE height_cm/weight_kg/psych_style vs 文档
   height/weight/psyche_style)——vision._bmi 多键取值、diagnosis 维度
   装配与规则上下文双键或运算,两侧谁改键名都不再炸
2. celery worker asyncio.run 每投递起新 loop + 模块级引擎缓存 →
   asyncpg 连接跨 loop(同进程第 3 个报告任务必现 RuntimeError:
   attached to a different loop;集成测试单循环掩盖)。新增
   apps/worker/loop.py 持久 loop,report/ping 两任务接入

E2E 终态: psyche_style/height_weight 恢复、BMI 体型确定值、ok 26/32、
真实 LLM 文案通过校验 degraded=False。
This commit is contained in:
xsl
2026-08-15 01:05:10 +08:00
parent da41e9ab0d
commit cb8a1e3c0f
5 changed files with 56 additions and 13 deletions
+4 -4
View File
@@ -9,9 +9,9 @@ render) follow exactly this shape and additionally call
from __future__ import annotations
import asyncio
from typing import Any
from typing import Any, cast
from apps.worker import loop as worker_loop
from apps.worker.celery_app import celery_app
from packages.domain.task.state import TaskStatus
from packages.shared.context import bind_context
@@ -61,9 +61,9 @@ async def _fail_ping(task_id: int, error: str) -> None:
def ping_task(self: Any, task_id: int, echo: str | None = None) -> dict[str, Any]:
bind_context(task_id=task_id)
try:
return asyncio.run(_run_ping(task_id, echo))
return cast("dict[str, Any]", worker_loop.run(_run_ping(task_id, echo)))
except Exception as exc:
logger.exception("ping_task_failed", task_id=task_id)
# Real tasks additionally refund the quota reservation here (FR-BILL-05).
asyncio.run(_fail_ping(task_id, f"{type(exc).__name__}: {exc}"))
worker_loop.run(_fail_ping(task_id, f"{type(exc).__name__}: {exc}"))
raise