Files
operating-room-monitor-server/app/repositories/voice_audits.py

71 lines
2.3 KiB
Python
Raw Normal View History

from __future__ import annotations
from datetime import datetime, timezone
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.db.models import VoiceConfirmationAudit
class VoiceAuditRepository:
"""Persist voice confirmation audit rows."""
async def list_by_surgery(
self,
session: AsyncSession,
surgery_id: str,
*,
limit: int = 50,
offset: int = 0,
) -> tuple[list[VoiceConfirmationAudit], int]:
"""按手术号分页列出审计行,按 `created_at` 降序(新在前)。"""
c = select(func.count()).select_from(VoiceConfirmationAudit).where(
VoiceConfirmationAudit.surgery_id == surgery_id
)
total = int((await session.execute(c)).scalar_one())
q = (
select(VoiceConfirmationAudit)
.where(VoiceConfirmationAudit.surgery_id == surgery_id)
.order_by(VoiceConfirmationAudit.created_at.desc())
.offset(offset)
.limit(limit)
)
rows = list((await session.execute(q)).scalars().all())
return rows, total
async def save_audit(
self,
session: AsyncSession,
*,
surgery_id: str,
confirmation_id: str,
status: str,
audio_object_key: str | None,
audio_content_type: str | None,
audio_size_bytes: int | None,
audio_sha256: str | None,
asr_text: str | None,
resolved_label: str | None,
options_snapshot_json: str | None,
error_message: str | None,
created_at: datetime | None = None,
) -> None:
when = created_at or datetime.now(timezone.utc)
row = VoiceConfirmationAudit(
surgery_id=surgery_id,
confirmation_id=confirmation_id,
status=status,
audio_object_key=audio_object_key,
audio_content_type=audio_content_type,
audio_size_bytes=audio_size_bytes,
audio_sha256=audio_sha256,
asr_text=asr_text,
resolved_label=resolved_label,
options_snapshot_json=options_snapshot_json,
error_message=error_message,
created_at=when,
)
session.add(row)
await session.flush()