docbot/src/docbot/services/session_service.py
oleg.vodyanov91@gmail.com 2379e6e2a9 change code
2025-06-04 00:58:57 +04:00

79 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import select
from db.session import AsyncSessionLocal
from db.models import SessionCode
async def create_session_code(telegram_id: int, form_link: str) -> str:
"""
Генерирует уникальный код, сохраняет его вместе с Telegram ID и ссылкой на анкету.
Возвращает этот код.
"""
code = uuid.uuid4().hex[:8]
async with AsyncSessionLocal() as session: # безопасно создаём сессию
async with session.begin():
session.add(SessionCode(
code=code,
patient_telegram_id=telegram_id,
sent_at=datetime.utcnow()
))
return code
async def mark_consulted(code: str) -> bool:
"""
Отмечает, что консультация получена (добавляет consulted_at).
Возвращает True, если запись найдена и обновлена.
"""
async with AsyncSessionLocal() as session:
async with session.begin():
result = await session.execute(
select(SessionCode).where(SessionCode.code.match(code))
)
sc: SessionCode | None = result.scalar_one_or_none()
if not sc:
return False
sc.consulted_at = datetime.utcnow()
return True
async def get_pending_session(telegram_id: int) -> SessionCode | None:
"""
Ищет самую «свежую» сессию по telegram_id, где consulted_at ещё не заполнен.
Вернёт объект SessionCode или None.
"""
async with AsyncSessionLocal() as session:
result = await session.execute(
select(SessionCode)
.where(SessionCode.patient_telegram_id.match(telegram_id))
.where(SessionCode.consulted_at.is_(None))
.order_by(SessionCode.sent_at.desc())
.limit(1)
)
return result.scalar_one_or_none()
async def get_session_info(code: str) -> dict | None:
"""
Возвращает словарь с информацией по коду:
telegram_id, form_link, sent_at, consulted_at.
"""
async with AsyncSessionLocal() as session:
result = await session.execute(
select(SessionCode).where(SessionCode.code.match(code))
)
sc: SessionCode | None = result.scalar_one_or_none()
if not sc:
return None
return {
"telegram_id": sc.patient_telegram_id,
"form_link": sc.form_link,
"sent_at": sc.sent_at,
"consulted_at": sc.consulted_at,
}