feat: 手术视频消耗、待确认与持久化改造

- 新增 Alembic 初始迁移、领域明细模型及归档持久化与重试链路\n- 拆分视频会话注册表、分类处理、推理时间窗聚合与流处理\n- 消耗日志:TSV/Markdown 含 top2/top3;item_id 优先产品编码;待确认记「待确认」行,语音确认后落正式行并更新汇总\n- 待确认时内存/DB 明细为占位行,确认后替换;拒绝时移除占位\n- 分类 probs 先 detach/cpu 再转 NumPy,修复 MPS/CUDA 上推理被静默跳过\n- 补充集成测试、归档与设备张量等单测

Made-with: Cursor
This commit is contained in:
Kevin
2026-04-23 20:42:21 +08:00
parent 69980d8073
commit 3d7bd70355
55 changed files with 4544 additions and 2050 deletions

View File

@@ -0,0 +1,54 @@
"""语音确认服务访问会话状态的端口协议。
把 `VoiceConfirmationService` 对 `CameraSessionManager` 的强依赖解耦为
`PendingConfirmationStore` 协议;便于单元测试用 fake并为后续拆分会话管理器
`SurgerySessionRegistry` 等)保留切换点。
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Protocol, runtime_checkable
if TYPE_CHECKING:
from app.services.video.session_manager import PendingConsumableConfirmation
@runtime_checkable
class PendingConfirmationStore(Protocol):
"""语音确认链路需要的最小会话接口。"""
def get_pending_confirmation_by_id(
self,
surgery_id: str,
confirmation_id: str,
) -> "PendingConsumableConfirmation | None":
...
def get_surgery_candidate_consumables(self, surgery_id: str) -> list[str]:
...
async def record_voice_parse_failure(
self,
surgery_id: str,
confirmation_id: str,
) -> tuple[int, int]:
...
async def resolve_pending_confirmation(
self,
surgery_id: str,
confirmation_id: str,
*,
chosen_label: str | None,
rejected: bool,
) -> None:
...
def record_voice_trace(
self,
surgery_id: str,
*,
asr_text: str | None,
error: str | None,
) -> None:
...