mirror of
https://github.com/olegvodyanov/docbot.git
synced 2025-12-19 23:57:05 +03:00
79 lines
2.7 KiB
Python
79 lines
2.7 KiB
Python
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,
|
||
}
|