From e43312a129a2d186d56e9cbda712a6b8aa50172c Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sun, 24 May 2026 22:52:00 -0400 Subject: [PATCH] fc3h: ImportSettings backup_* knobs + alembic 0018 (nightly-enabled, hour, keep-N per kind) Co-Authored-By: Claude Opus 4.7 (1M context) --- alembic/versions/0018_fc3h_backup_settings.py | 62 +++++++++++++++++++ backend/app/models/import_settings.py | 14 +++++ 2 files changed, 76 insertions(+) create mode 100644 alembic/versions/0018_fc3h_backup_settings.py diff --git a/alembic/versions/0018_fc3h_backup_settings.py b/alembic/versions/0018_fc3h_backup_settings.py new file mode 100644 index 0000000..517c8f1 --- /dev/null +++ b/alembic/versions/0018_fc3h_backup_settings.py @@ -0,0 +1,62 @@ +"""fc3h: backup_* knobs on import_settings + +Revision ID: 0018 +Revises: 0017 +Create Date: 2026-05-24 + +Adds four columns to the singleton import_settings row: + - backup_db_nightly_enabled (default False — opt-in) + - backup_db_nightly_hour_utc (default 3) + - backup_db_keep_last_n (default 14) + - backup_images_keep_last_n (default 3) + +server_default ensures the singleton row is backfilled in place +without an UPDATE statement. +""" +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op + +revision: str = "0018" +down_revision: Union[str, None] = "0017" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + op.add_column( + "import_settings", + sa.Column( + "backup_db_nightly_enabled", sa.Boolean(), + nullable=False, server_default=sa.false(), + ), + ) + op.add_column( + "import_settings", + sa.Column( + "backup_db_nightly_hour_utc", sa.Integer(), + nullable=False, server_default="3", + ), + ) + op.add_column( + "import_settings", + sa.Column( + "backup_db_keep_last_n", sa.Integer(), + nullable=False, server_default="14", + ), + ) + op.add_column( + "import_settings", + sa.Column( + "backup_images_keep_last_n", sa.Integer(), + nullable=False, server_default="3", + ), + ) + + +def downgrade() -> None: + op.drop_column("import_settings", "backup_images_keep_last_n") + op.drop_column("import_settings", "backup_db_keep_last_n") + op.drop_column("import_settings", "backup_db_nightly_hour_utc") + op.drop_column("import_settings", "backup_db_nightly_enabled") diff --git a/backend/app/models/import_settings.py b/backend/app/models/import_settings.py index fca7f88..323fbf6 100644 --- a/backend/app/models/import_settings.py +++ b/backend/app/models/import_settings.py @@ -49,3 +49,17 @@ class ImportSettings(Base): download_failure_warning_threshold: Mapped[int] = mapped_column( Integer, nullable=False, default=5 ) + + # FC-3h backup knobs. + backup_db_nightly_enabled: Mapped[bool] = mapped_column( + Boolean, nullable=False, default=False, + ) + backup_db_nightly_hour_utc: Mapped[int] = mapped_column( + Integer, nullable=False, default=3, + ) + backup_db_keep_last_n: Mapped[int] = mapped_column( + Integer, nullable=False, default=14, + ) + backup_images_keep_last_n: Mapped[int] = mapped_column( + Integer, nullable=False, default=3, + )