From 20acef6ad8708624f3b1d6d6ee202c8f6b56d806 Mon Sep 17 00:00:00 2001 From: GGlamer <52128225+Gamer201760@users.noreply.github.com> Date: Sun, 27 Sep 2026 23:23:05 +0300 Subject: [PATCH] =?UTF-8?q?chore:=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=B0=D1=83=D0=B7=20=D0=B2=D0=BD=D0=B5=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=BA=20=D0=B8=D0=B7=20main,=20=D1=87=D1=82=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=20=D0=B2=D0=B5=D1=82=D0=BA=D1=83=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=B8=D1=82=D1=8C=20=D1=81=D0=BB=D0=B8=D1=8F?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/http/sessions.py | 13 ++++++------- backend/app/api/ws/call.py | 6 +++--- backend/tests/test_checkpoint_model.py | 6 +++--- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/backend/app/api/http/sessions.py b/backend/app/api/http/sessions.py index 1996e95..bebcc6c 100644 --- a/backend/app/api/http/sessions.py +++ b/backend/app/api/http/sessions.py @@ -111,10 +111,10 @@ class ActiveSessionOut(BaseModel): dds_overdue_cards: int dds_work_overdue_cards: int dds_statuses: dict[str, str] + paused: bool = False dds_snapshot: StationSnapshot | None = None signals: list[Signal] = [] presence_known: bool = True - paused: bool = False def _out(session) -> SessionOut: @@ -203,11 +203,10 @@ def _signals( ) -> list[Signal]: """Сигналы реестра: очередь, повторные отказы, курсант не на связи. - Пауза занятия (`session.pause`) их не трогает и ложных срабатываний не - даёт: очередь на паузе не выдаёт карточки, команды станции отклоняются, - поэтому счётчики стоят; присутствие сокета — факт и на паузе. - Присутствие — по наличию подписчика в хабе этого узла; окно нужно, чтобы - короткий разрыв соединения не сразу считался потерей связи курсанта. + Не завязаны на паузу занятия (`session.pause`, если появится) — очередь, + отказы и присутствие сокета не читают таймеры. Присутствие — по наличию + подписчика в хабе этого узла; окно нужно, чтобы короткий разрыв + соединения не сразу считался потерей связи курсанта. `live=False` — снимок чужого узла: его сокеты здесь не видны, поэтому присутствие неизвестно. Чтение реестра не меняет состояние занятия. @@ -331,10 +330,10 @@ async def active( for card in state.desk.cards.values() ), dds_statuses=latest_statuses, + paused=state.paused, dds_snapshot=station, signals=_signals(state, queue, now, live=state.session_id not in checkpoint_only), presence_known=state.session_id not in checkpoint_only, - paused=state.paused, )) return result diff --git a/backend/app/api/ws/call.py b/backend/app/api/ws/call.py index 37ac20b..78387ff 100644 --- a/backend/app/api/ws/call.py +++ b/backend/app/api/ws/call.py @@ -432,9 +432,6 @@ async def call(ws: WebSocket, session_id: UUID) -> None: if hub.is_lease_fenced(session_id): await close_fenced(ws) return - # Каждый новый канал получает серверное состояние, включая снятую паузу: - # клиент мог потерять событие resume во время переподключения. - queue.put_nowait(SessionPaused(paused=state.paused)) if state.exercise is Exercise.CARD: from app.api.ws.control import card_briefing @@ -468,6 +465,9 @@ async def call(ws: WebSocket, session_id: UUID) -> None: if state.recorder is None: state.recorder = start_recording(session_id) _start_voice(session_id, state, initial_statement=False) + # Каждый новый канал получает серверное состояние, включая снятую паузу: + # клиент мог потерять событие resume во время переподключения. + queue.put_nowait(SessionPaused(paused=state.paused)) writer = asyncio.create_task(pump(ws, queue)) try: while True: diff --git a/backend/tests/test_checkpoint_model.py b/backend/tests/test_checkpoint_model.py index 5cc764e..90cead6 100644 --- a/backend/tests/test_checkpoint_model.py +++ b/backend/tests/test_checkpoint_model.py @@ -160,14 +160,14 @@ def full_state() -> SessionState: desk=desk, resolved_outcome="справка", resolve_comment="передано в другой регион", + paused=True, + paused_at=AT, + total_paused_ms=15_000, processed_station_commands=[str(uuid4())], text_revealed_facts={"f_address": "улица Ленина, 14"}, consecutive_refusals=2, socket_last_seen_at=AT, socket_connected_at_checkpoint=True, - paused=True, - paused_at=AT, - total_paused_ms=15_000, )