github_backup.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. """GitHub backup configuration and log models."""
  2. from datetime import datetime
  3. from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, false, func
  4. from sqlalchemy.orm import Mapped, mapped_column, relationship
  5. from backend.app.core.database import Base
  6. class GitHubBackupConfig(Base):
  7. """Configuration for GitHub profile backup."""
  8. __tablename__ = "github_backup_config"
  9. id: Mapped[int] = mapped_column(primary_key=True)
  10. repository_url: Mapped[str] = mapped_column(String(500)) # Full GitHub URL
  11. access_token: Mapped[str] = mapped_column(Text) # Personal Access Token
  12. branch: Mapped[str] = mapped_column(String(100), default="main")
  13. provider: Mapped[str] = mapped_column(String(30), default="github", server_default="github")
  14. allow_insecure_http: Mapped[bool] = mapped_column(Boolean, default=False, server_default=false())
  15. # Schedule configuration
  16. schedule_enabled: Mapped[bool] = mapped_column(Boolean, default=False)
  17. schedule_type: Mapped[str] = mapped_column(String(20), default="daily") # hourly/daily/weekly
  18. schedule_cron: Mapped[str | None] = mapped_column(String(100), nullable=True) # For future cron support
  19. # What to backup
  20. backup_kprofiles: Mapped[bool] = mapped_column(Boolean, default=True)
  21. backup_cloud_profiles: Mapped[bool] = mapped_column(Boolean, default=True)
  22. backup_settings: Mapped[bool] = mapped_column(Boolean, default=False)
  23. backup_spools: Mapped[bool] = mapped_column(Boolean, default=False)
  24. backup_archives: Mapped[bool] = mapped_column(Boolean, default=False)
  25. # Status tracking
  26. enabled: Mapped[bool] = mapped_column(Boolean, default=True)
  27. last_backup_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
  28. last_backup_status: Mapped[str | None] = mapped_column(String(20), nullable=True) # success/failed/skipped
  29. last_backup_message: Mapped[str | None] = mapped_column(Text, nullable=True)
  30. last_backup_commit_sha: Mapped[str | None] = mapped_column(String(40), nullable=True)
  31. next_scheduled_run: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
  32. # Timestamps
  33. created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
  34. updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now())
  35. # Relationships
  36. logs: Mapped[list["GitHubBackupLog"]] = relationship(back_populates="config", cascade="all, delete-orphan")
  37. class GitHubBackupLog(Base):
  38. """Log entry for GitHub backup runs."""
  39. __tablename__ = "github_backup_logs"
  40. id: Mapped[int] = mapped_column(primary_key=True)
  41. config_id: Mapped[int] = mapped_column(ForeignKey("github_backup_config.id", ondelete="CASCADE"))
  42. started_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
  43. completed_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
  44. status: Mapped[str] = mapped_column(String(20)) # running/success/failed/skipped
  45. trigger: Mapped[str] = mapped_column(String(20)) # manual/scheduled/restore
  46. commit_sha: Mapped[str | None] = mapped_column(String(40), nullable=True)
  47. files_changed: Mapped[int] = mapped_column(Integer, default=0)
  48. error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
  49. # Relationships
  50. config: Mapped["GitHubBackupConfig"] = relationship(back_populates="logs")