34 lines
1.5 KiB
Python
34 lines
1.5 KiB
Python
"""Foreground roundtable room leases.
|
|
|
|
One row is one browser session that has entered step 2 and is still heartbeating.
|
|
Background jobs are not stored here: they already occupy a room through
|
|
``roundtable_jobs`` while their status is non-terminal. Both sides share the
|
|
job active-dedupe key so a foreground session and its later background job
|
|
count as one room.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import String
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from deerflow.persistence.base import Base
|
|
from deerflow.persistence.types import BeijingDateTime
|
|
|
|
|
|
class RoundtableRoomLeaseRow(Base):
|
|
__tablename__ = "roundtable_room_leases"
|
|
|
|
room_key: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
draft_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
|
|
user_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
task_id: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
|
# Last account to heartbeat. Release only succeeds for this account, so one
|
|
# viewer leaving a shared task room does not drop another viewer's lease.
|
|
holder_user_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
lease_until: Mapped[datetime | None] = mapped_column(BeijingDateTime(), nullable=True)
|
|
created_at: Mapped[datetime | None] = mapped_column(BeijingDateTime(), nullable=True)
|
|
updated_at: Mapped[datetime | None] = mapped_column(BeijingDateTime(), nullable=True)
|