mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-22 05:09:05 +00:00
feat: dailyco poll (#730)
* dailyco api module (no-mistakes) * daily co library self-review * uncurse * self-review: daily resource leak, uniform types, enable_recording bomb, daily custom error, video_platforms/daily typing, daily timestamp dry * dailyco docs parser * phase 1-2 of daily poll * dailyco poll (no-mistakes) * poll docs * fix tests * forgotten utils file * remove generated daily docs * pr comments * dailyco poll pr review and self-review * daily recording poll api fix * daily recording poll api fix * review * review * fix tests --------- Co-authored-by: Igor Loskutov <igor.loskutoff@gmail.com>
This commit is contained in:
@@ -165,5 +165,65 @@ class DailyParticipantSessionController:
|
||||
results = await get_database().fetch_all(query)
|
||||
return [DailyParticipantSession(**result) for result in results]
|
||||
|
||||
async def get_all_sessions_for_meeting(
|
||||
self, meeting_id: NonEmptyString
|
||||
) -> dict[NonEmptyString, DailyParticipantSession]:
|
||||
query = daily_participant_sessions.select().where(
|
||||
daily_participant_sessions.c.meeting_id == meeting_id
|
||||
)
|
||||
results = await get_database().fetch_all(query)
|
||||
# TODO DailySessionId custom type
|
||||
return {row["session_id"]: DailyParticipantSession(**row) for row in results}
|
||||
|
||||
async def batch_upsert_sessions(
|
||||
self, sessions: list[DailyParticipantSession]
|
||||
) -> None:
|
||||
"""Upsert multiple sessions in single query.
|
||||
|
||||
Uses ON CONFLICT for idempotency. Updates user_name on conflict since they may change it during a meeting.
|
||||
|
||||
"""
|
||||
if not sessions:
|
||||
return
|
||||
|
||||
values = [session.model_dump() for session in sessions]
|
||||
query = insert(daily_participant_sessions).values(values)
|
||||
query = query.on_conflict_do_update(
|
||||
index_elements=["id"],
|
||||
set_={
|
||||
# Preserve existing left_at to prevent race conditions
|
||||
"left_at": sa.func.coalesce(
|
||||
daily_participant_sessions.c.left_at,
|
||||
query.excluded.left_at,
|
||||
),
|
||||
"user_name": query.excluded.user_name,
|
||||
},
|
||||
)
|
||||
await get_database().execute(query)
|
||||
|
||||
async def batch_close_sessions(
|
||||
self, session_ids: list[NonEmptyString], left_at: datetime
|
||||
) -> None:
|
||||
"""Mark multiple sessions as left in single query.
|
||||
|
||||
Only updates sessions where left_at is NULL (protects already-closed sessions).
|
||||
|
||||
Left_at mismatch for existing sessions is ignored, assumed to be not important issue if ever happens.
|
||||
"""
|
||||
if not session_ids:
|
||||
return
|
||||
|
||||
query = (
|
||||
daily_participant_sessions.update()
|
||||
.where(
|
||||
sa.and_(
|
||||
daily_participant_sessions.c.id.in_(session_ids),
|
||||
daily_participant_sessions.c.left_at.is_(None),
|
||||
)
|
||||
)
|
||||
.values(left_at=left_at)
|
||||
)
|
||||
await get_database().execute(query)
|
||||
|
||||
|
||||
daily_participant_sessions_controller = DailyParticipantSessionController()
|
||||
|
||||
Reference in New Issue
Block a user