from pydantic import BaseModel, Field from typing import Optional, List, Dict, Any from datetime import datetime # Source schemas class SourceBase(BaseModel): name: str type: str = Field(..., pattern="^(local|ssh|database)$") config: Dict[str, Any] = Field(default_factory=dict) class SourceCreate(SourceBase): pass class SourceUpdate(BaseModel): name: Optional[str] = None config: Optional[Dict[str, Any]] = None class Source(SourceBase): id: int created_at: datetime updated_at: datetime class Config: from_attributes = True # Job schemas class JobBase(BaseModel): name: str source_id: int strategy: str = Field(default="full", pattern="^(full|incremental)$") destination_path: str exclude_patterns: List[str] = Field(default_factory=list) enabled: bool = True class JobCreate(JobBase): pass class JobUpdate(BaseModel): name: Optional[str] = None strategy: Optional[str] = None destination_path: Optional[str] = None exclude_patterns: Optional[List[str]] = None enabled: Optional[bool] = None class Job(JobBase): id: int created_at: datetime updated_at: datetime class Config: from_attributes = True # Schedule schemas class ScheduleBase(BaseModel): job_id: int cron_expression: str enabled: bool = True class ScheduleCreate(ScheduleBase): pass class ScheduleUpdate(BaseModel): cron_expression: Optional[str] = None enabled: Optional[bool] = None class Schedule(ScheduleBase): id: int created_at: datetime class Config: from_attributes = True # Execution schemas class JobExecutionBase(BaseModel): job_id: int status: str = Field(default="pending", pattern="^(pending|running|success|failed|cancelled)$") triggered_by: str = Field(..., pattern="^(manual|schedule)$") class JobExecutionCreate(JobExecutionBase): pass class JobExecution(JobExecutionBase): id: int started_at: Optional[datetime] = None completed_at: Optional[datetime] = None bytes_processed: int = 0 bytes_backed_up: int = 0 error_message: Optional[str] = None class Config: from_attributes = True # Backup schemas class BackupBase(BaseModel): execution_id: int storage_path: str size_bytes: int = 0 checksum: Optional[str] = None type: str = Field(..., pattern="^(full|incremental)$") parent_backup_id: Optional[int] = None class BackupCreate(BackupBase): pass class Backup(BackupBase): id: int created_at: datetime class Config: from_attributes = True # Settings schemas class SettingBase(BaseModel): key: str value: Optional[str] = None class SettingCreate(SettingBase): pass class SettingUpdate(BaseModel): value: Optional[str] = None class Setting(SettingBase): updated_at: datetime class Config: from_attributes = True # Dashboard schemas class DashboardStats(BaseModel): active_jobs: int total_backups: int storage_used_bytes: int recent_failures: int recent_executions: List[JobExecution]