"""Data models for test persistence. This module defines dataclasses representing test runs, results, and measurements. These models map to SQLite tables (for metadata) and Parquet files (for time-series). """ from dataclasses import dataclass, field from datetime import datetime from enum import Enum class TestStatus(Enum): """Test run status.""" PENDING = "pending" RUNNING = "running" PASSED = "passed" FAILED = "failed" ERROR = "error" SKIPPED = "skipped" @dataclass class TestRun: """Test run metadata. Maps to the test_runs SQLite table. """ id: str # UUID test_name: str started_at: datetime status: TestStatus config_json: str # JSON string of test configuration description: str | None = None completed_at: datetime | None = None operator: str | None = None notes: str | None = None created_at: datetime = field(default_factory=datetime.now) @dataclass(frozen=True) class TestResult: """Immutable test result with limits. Maps to the test_results SQLite table. Represents a single scalar measurement with pass/fail limits. """ id: str # UUID test_run_id: str # Foreign key to test_runs.id parameter: str value: float unit: str measured_at: datetime lower_limit: float | None = None upper_limit: float | None = None @property def passed(self) -> bool | None: """Evaluate pass/fail. None if no limits defined.""" if self.lower_limit is None and self.upper_limit is None: return None lower_ok = self.lower_limit is None or self.value >= self.lower_limit upper_ok = self.upper_limit is None or self.value <= self.upper_limit return lower_ok and upper_ok @dataclass(frozen=True) class Measurement: """Immutable measurement record for time-series data. Maps to Parquet files for efficient storage and analysis. Includes measurement conditions (temperature, voltage, current) at time of measurement. """ timestamp: float # Seconds since epoch (high precision) parameter: str value: float unit: str temperature: float = 0.0 # Chamber temperature at measurement input_voltage: float = 0.0 # DUT input voltage at measurement load_current: float = 0.0 # DUT load current at measurement