from datetime import datetime from pathlib import Path from typing import Optional from pydantic import BaseModel, Field from gimme_job.constants import FailureClassification, RunStatus class SiteRunResult(BaseModel): site_id: str status: RunStatus = RunStatus.SUCCESS items_found: int = 0 new_items: int = 0 error_summary: Optional[str] = None failure_classification: Optional[FailureClassification] = None trace_path: Optional[Path] = None screenshot_path: Optional[Path] = None dom_snapshot_path: Optional[Path] = None started_at: datetime = Field(default_factory=datetime.utcnow) ended_at: Optional[datetime] = None def mark_done(self) -> None: self.ended_at = datetime.utcnow() class RunSummary(BaseModel): run_date: datetime = Field(default_factory=datetime.utcnow) site_results: list[SiteRunResult] = Field(default_factory=list) total_new: int = 0 total_found: int = 0 summary_text: Optional[str] = None def add_result(self, result: SiteRunResult) -> None: self.site_results.append(result) self.total_found += result.items_found self.total_new += result.new_items class ClaudeRunResult(BaseModel): success: bool session_id: Optional[str] = None output: str = "" cost_usd: Optional[float] = None duration_ms: Optional[int] = None error: Optional[str] = None