from dataclasses import dataclass @dataclass(frozen=True) class AppConfig: ip: str port: int debug: bool def as_db_tuple(self) -> tuple[str, int, int]: return ( self.ip, self.port, 1 if self.debug else 0, ) @dataclass(frozen=True) class UserAccount: username: str password_hash: str is_admin: bool @dataclass(frozen=True) class InitialSetupData: config: AppConfig admin_username: str admin_password_hash: str @dataclass(frozen=True) class BackupJob: name: str source_protocol: str source_host: str source_port: int | None source_share: str source_subpath: str source_username: str source_password: str destination_protocol: str destination_host: str destination_port: int | None destination_share: str destination_subpath: str destination_username: str destination_password: str source_entry_type: str target_kind: str target_pattern: str compression_method: str encryption_mode: str archive_password: str schedule_mode: str schedule_time: str schedule_weekday: str schedule_day_of_month: str schedule_interval: int | None schedule_cron: str @dataclass(frozen=True) class BackupExecutionJob: backup_id: int name: str source_protocol: str source_host: str source_port: int | None source_share: str source_subpath: str source_username: str source_password: str destination_protocol: str destination_host: str destination_port: int | None destination_share: str destination_subpath: str destination_username: str destination_password: str @dataclass(frozen=True) class BackupSummary: backup_id: int name: str source_label: str destination_label: str target_pattern: str compression_method: str schedule_mode: str last_run_at: str | None last_size_bytes: int | None