From dfd33aee1c033b8de370fdcff3617525502af260 Mon Sep 17 00:00:00 2001 From: timmy Date: Mon, 17 Aug 2026 20:17:43 +0000 Subject: [PATCH] fix: reject contradictory running break sessions --- src/main.py | 6 ++++++ tests/test_today_store.py | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/src/main.py b/src/main.py index bf4fecb..45be49b 100644 --- a/src/main.py +++ b/src/main.py @@ -596,6 +596,12 @@ class TodaySessionUpdate(BaseModel): running: bool break_deadline_at: int | None = Field(default=None, ge=0, le=10_000_000_000_000) + @model_validator(mode="after") + def validate_break_is_paused(self): + if self.running and self.break_deadline_at is not None: + raise ValueError("break must remain paused") + return self + class TodayRecapTimeLog(TodayRecap): log_identities: list[str] = Field(min_length=1, max_length=20) diff --git a/tests/test_today_store.py b/tests/test_today_store.py index b69bf30..90034f3 100644 --- a/tests/test_today_store.py +++ b/tests/test_today_store.py @@ -92,6 +92,14 @@ async def test_active_session_api_persists_a_bounded_break_deadline(monkeypatch, assert (await main.get_today_session()) == saved +def test_active_session_api_rejects_a_running_break(): + with pytest.raises(ValueError, match="break must remain paused"): + main.TodaySessionUpdate( + base_revision=0, device_id="phone-a", identity="issue:r:1:", + elapsed_ms=5_000, running=True, break_deadline_at=1_800_000, + ) + + @pytest.mark.anyio async def test_active_session_api_returns_current_state_on_claim_conflict(monkeypatch, tmp_path): async def user():