"""Finite read scopes available to operational investigations.""" from datetime import timedelta from typing import Literal from pydantic import Field, JsonValue, model_validator from app.domain.schemas.shared import NonEmptyStr, StrictModel from app.domain.schemas.workbench_runtime import WorkbenchDateTime TaskDataSource = Literal[ "workbench_runtime", "scada_devices", "scada_readings", "peripheral_points", "peripheral_work_orders", "peripheral_observations", "peripheral_test_data", ] class TaskDataQuery(StrictModel): source: TaskDataSource device_ids: list[NonEmptyStr] = Field(default_factory=list, max_length=20) point_id: NonEmptyStr | None = None start: WorkbenchDateTime | None = None end: WorkbenchDateTime | None = None @model_validator(mode="after") def validate_window(self): if self.source in {"scada_readings", "peripheral_observations"}: if self.start is None or self.end is None: raise ValueError("time series queries require start and end") if not timedelta(0) < self.end - self.start <= timedelta(days=1): raise ValueError("query window must be positive and at most 24 hours") if self.source == "scada_readings" and not self.device_ids: raise ValueError("SCADA queries require device_ids") if self.source == "peripheral_observations" and not self.point_id: raise ValueError("peripheral queries require point_id") return self class TaskDataSnapshot(StrictModel): source: TaskDataSource source_ref: NonEmptyStr queried_at: WorkbenchDateTime origin: Literal["system_data", "synthetic"] data: JsonValue truncated: bool