diff --git a/schedule/src/schedule/domain/__init__.py b/schedule/src/schedule/domain/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/schedule/src/schedule/domain/context.py b/schedule/src/schedule/domain/context.py new file mode 100644 index 0000000..143e5c9 --- /dev/null +++ b/schedule/src/schedule/domain/context.py @@ -0,0 +1,41 @@ +"""Shared constants and timezone helpers for the scheduler components. + +Designed to be import-side-effect-free: no logging, no I/O, no model imports. +Used by ``scheduler``, ``orchestrator`` and ``worker`` modules. +""" + +from __future__ import annotations + +from datetime import UTC, datetime + +TERMINAL_NODE_STATES = frozenset({ + "succeeded", + "failed", + "skipped", + "cancelled", + "timed_out", +}) +FAILED_NODE_STATES = frozenset({"failed", "cancelled", "timed_out"}) +TERMINAL_RUN_STATES = frozenset({ + "succeeded", + "failed", + "cancelled", + "timed_out", +}) + + +def naive_utc(value: datetime | None) -> datetime | None: + """Normalize a datetime to naive UTC; pass through ``None``.""" + if value is None: + return None + if value.tzinfo is None: + value = value.replace(tzinfo=UTC) + return value.astimezone(UTC).replace(tzinfo=None) + + +__all__ = [ + "FAILED_NODE_STATES", + "TERMINAL_NODE_STATES", + "TERMINAL_RUN_STATES", + "naive_utc", +] diff --git a/schedule/src/schedule/domain/execution.py b/schedule/src/schedule/domain/execution.py new file mode 100644 index 0000000..ceb355d --- /dev/null +++ b/schedule/src/schedule/domain/execution.py @@ -0,0 +1,21 @@ +"""Domain types for schedule node execution. + +Pure value objects — no I/O, no logging, no model imports. Safe to import +from any layer. +""" + +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ExecutionResult: + status: str + exit_code: int | None + logs: bytes + result: bytes + result_file_name: str + result_content_type: str + error_code: str | None = None + error_message: str | None = None