"""v2 baseline Revision ID: 0001_v2_baseline Revises: Create Date: 2026-07-27 19:15:52.319338 """ from collections.abc import Sequence import sqlalchemy as sa from alembic import op revision: str = "0001_v2_baseline" down_revision: str | Sequence[str] | None = None branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.create_table( "repositories", sa.Column("name", sa.String(length=255), nullable=False), sa.Column("root", sa.Text(), nullable=False), sa.Column("format_version", sa.Integer(), nullable=False), sa.Column("compression", sa.String(length=32), nullable=False), sa.Column("encryption", sa.String(length=32), nullable=False), sa.Column("state", sa.String(length=32), nullable=False), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint( "state IN ('active','archived','unavailable')", name=op.f("ck_repositories_state") ), sa.CheckConstraint( "format_version > 0", name=op.f("ck_repositories_format_version_positive") ), sa.PrimaryKeyConstraint("id", name=op.f("pk_repositories")), sa.UniqueConstraint("name", name=op.f("uq_repositories_name")), sa.UniqueConstraint("root", name=op.f("uq_repositories_root")), ) op.create_table( "secrets", sa.Column("ciphertext", sa.LargeBinary(), nullable=False), sa.Column("key_id", sa.String(length=255), nullable=False), sa.Column("purpose", sa.String(length=64), nullable=False), sa.Column("version", sa.Integer(), nullable=False), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint("version > 0", name=op.f("ck_secrets_version_positive")), sa.PrimaryKeyConstraint("id", name=op.f("pk_secrets")), ) op.create_table( "sources", sa.Column("name", sa.String(length=255), nullable=False), sa.Column("kind", sa.String(length=32), nullable=False), sa.Column("public_config", sa.JSON(), nullable=False), sa.Column("secret_refs", sa.JSON(), nullable=False), sa.Column("state", sa.String(length=32), nullable=False), sa.Column("last_probe", sa.JSON(), nullable=True), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint( "kind IN ('local','sftp','postgresql','mysql')", name=op.f("ck_sources_kind") ), sa.CheckConstraint( "state IN ('active','archived','unavailable')", name=op.f("ck_sources_state") ), sa.PrimaryKeyConstraint("id", name=op.f("pk_sources")), sa.UniqueConstraint("name", name=op.f("uq_sources_name")), ) op.create_table( "users", sa.Column("username", sa.String(length=255), nullable=False), sa.Column("password_hash", sa.Text(), nullable=False), sa.Column("state", sa.String(length=32), nullable=False), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint("state IN ('active','disabled')", name=op.f("ck_users_state")), sa.PrimaryKeyConstraint("id", name=op.f("pk_users")), sa.UniqueConstraint("username", name=op.f("uq_users_username")), ) op.create_table( "api_tokens", sa.Column("owner_id", sa.String(length=36), nullable=False), sa.Column("token_hash", sa.Text(), nullable=False), sa.Column("scopes", sa.JSON(), nullable=False), sa.Column("expires_at", sa.DateTime(timezone=True), nullable=True), sa.Column("revoked_at", sa.DateTime(timezone=True), nullable=True), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.ForeignKeyConstraint( ["owner_id"], ["users.id"], name=op.f("fk_api_tokens_owner_id_users"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_api_tokens")), sa.UniqueConstraint("token_hash", name=op.f("uq_api_tokens_token_hash")), ) op.create_index("ix_api_tokens_owner_id", "api_tokens", ["owner_id"], unique=False) op.create_table( "audit_events", sa.Column("actor_id", sa.String(length=36), nullable=True), sa.Column("action", sa.String(length=255), nullable=False), sa.Column("resource_type", sa.String(length=64), nullable=False), sa.Column("resource_id", sa.String(length=36), nullable=True), sa.Column("outcome", sa.String(length=32), nullable=False), sa.Column("request_id", sa.String(length=36), nullable=False), sa.Column("details", sa.JSON(), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column("id", sa.String(length=36), nullable=False), sa.CheckConstraint( "outcome IN ('success','failure','denied')", name=op.f("ck_audit_events_outcome") ), sa.ForeignKeyConstraint( ["actor_id"], ["users.id"], name=op.f("fk_audit_events_actor_id_users"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_audit_events")), ) op.create_index("ix_audit_events_actor_id", "audit_events", ["actor_id"], unique=False) op.create_index("ix_audit_events_created_at", "audit_events", ["created_at"], unique=False) op.create_table( "idempotency_records", sa.Column("actor_id", sa.String(length=36), nullable=False), sa.Column("key", sa.String(length=255), nullable=False), sa.Column("operation", sa.String(length=255), nullable=False), sa.Column("request_digest", sa.String(length=64), nullable=False), sa.Column("response_resource_type", sa.String(length=64), nullable=False), sa.Column("response_resource_id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column("id", sa.String(length=36), nullable=False), sa.ForeignKeyConstraint( ["actor_id"], ["users.id"], name=op.f("fk_idempotency_records_actor_id_users"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_idempotency_records")), sa.UniqueConstraint( "actor_id", "key", "operation", name="uq_idempotency_actor_key_operation" ), ) op.create_index( "ix_idempotency_created_at", "idempotency_records", ["created_at"], unique=False ) op.create_table( "jobs", sa.Column("name", sa.String(length=255), nullable=False), sa.Column("source_id", sa.String(length=36), nullable=False), sa.Column("repository_id", sa.String(length=36), nullable=False), sa.Column("requested_mode", sa.String(length=32), nullable=False), sa.Column("exclusions", sa.JSON(), nullable=False), sa.Column("retention", sa.JSON(), nullable=False), sa.Column("enabled", sa.Boolean(), nullable=False), sa.Column("allow_empty", sa.Boolean(), nullable=False), sa.Column("state", sa.String(length=32), nullable=False), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint( "requested_mode IN ('full','incremental')", name=op.f("ck_jobs_requested_mode") ), sa.CheckConstraint("state IN ('active','archived')", name=op.f("ck_jobs_state")), sa.ForeignKeyConstraint( ["repository_id"], ["repositories.id"], name=op.f("fk_jobs_repository_id_repositories"), ondelete="RESTRICT", ), sa.ForeignKeyConstraint( ["source_id"], ["sources.id"], name=op.f("fk_jobs_source_id_sources"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_jobs")), sa.UniqueConstraint("name", name=op.f("uq_jobs_name")), ) op.create_index("ix_jobs_repository_id", "jobs", ["repository_id"], unique=False) op.create_index("ix_jobs_source_id", "jobs", ["source_id"], unique=False) op.create_table( "notification_subscriptions", sa.Column("channel", sa.String(length=32), nullable=False), sa.Column("event_filters", sa.JSON(), nullable=False), sa.Column("destination_config", sa.JSON(), nullable=False), sa.Column("secret_id", sa.String(length=36), nullable=True), sa.Column("state", sa.String(length=32), nullable=False), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint( "channel IN ('webhook','email')", name=op.f("ck_notification_subscriptions_channel") ), sa.CheckConstraint( "state IN ('active','disabled','archived')", name=op.f("ck_notification_subscriptions_state"), ), sa.ForeignKeyConstraint( ["secret_id"], ["secrets.id"], name=op.f("fk_notification_subscriptions_secret_id_secrets"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_notification_subscriptions")), ) op.create_table( "notification_deliveries", sa.Column("event_id", sa.String(length=36), nullable=False), sa.Column("subscription_id", sa.String(length=36), nullable=False), sa.Column("attempt", sa.Integer(), nullable=False), sa.Column("state", sa.String(length=32), nullable=False), sa.Column("response_class", sa.String(length=64), nullable=True), sa.Column("next_attempt_at", sa.DateTime(timezone=True), nullable=True), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint( "state IN ('pending','delivered','retry','failed')", name=op.f("ck_notification_deliveries_state"), ), sa.CheckConstraint("attempt > 0", name=op.f("ck_notification_deliveries_attempt_positive")), sa.ForeignKeyConstraint( ["subscription_id"], ["notification_subscriptions.id"], name=op.f("fk_notification_deliveries_subscription_id_notification_subscriptions"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_notification_deliveries")), sa.UniqueConstraint("event_id", "subscription_id", "attempt", name="uq_delivery_attempt"), ) op.create_index( "ix_notification_deliveries_state_next", "notification_deliveries", ["state", "next_attempt_at"], unique=False, ) op.create_table( "schedules", sa.Column("job_id", sa.String(length=36), nullable=False), sa.Column("cron", sa.String(length=255), nullable=False), sa.Column("timezone", sa.String(length=255), nullable=False), sa.Column("misfire_grace_seconds", sa.Integer(), nullable=False), sa.Column("overlap_policy", sa.String(length=32), nullable=False), sa.Column("enabled", sa.Boolean(), nullable=False), sa.Column("next_nominal_at", sa.DateTime(timezone=True), nullable=True), sa.Column("last_enqueue_outcome", sa.String(length=64), nullable=True), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint( "overlap_policy IN ('prohibit')", name=op.f("ck_schedules_overlap_policy") ), sa.CheckConstraint( "misfire_grace_seconds >= 0", name=op.f("ck_schedules_misfire_nonnegative") ), sa.ForeignKeyConstraint( ["job_id"], ["jobs.id"], name=op.f("fk_schedules_job_id_jobs"), ondelete="RESTRICT" ), sa.PrimaryKeyConstraint("id", name=op.f("pk_schedules")), sa.UniqueConstraint("job_id", name=op.f("uq_schedules_job_id")), ) op.create_table( "executions", sa.Column("job_id", sa.String(length=36), nullable=False), sa.Column("schedule_id", sa.String(length=36), nullable=True), sa.Column("nominal_run_at", sa.DateTime(timezone=True), nullable=True), sa.Column("trigger", sa.String(length=32), nullable=False), sa.Column("state", sa.String(length=32), nullable=False), sa.Column("attempt", sa.Integer(), nullable=False), sa.Column("lease_owner", sa.String(length=255), nullable=True), sa.Column("lease_expires_at", sa.DateTime(timezone=True), nullable=True), sa.Column("heartbeat_at", sa.DateTime(timezone=True), nullable=True), sa.Column("progress", sa.JSON(), nullable=False), sa.Column("reason_code", sa.String(length=64), nullable=True), sa.Column("operator_message", sa.Text(), nullable=True), sa.Column("started_at", sa.DateTime(timezone=True), nullable=True), sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint( "state IN ('queued','preparing','running','verifying','committed'," "'cancelling','cancelled','failed')", name=op.f("ck_executions_state"), ), sa.CheckConstraint( "trigger IN ('manual','schedule','retry')", name=op.f("ck_executions_trigger") ), sa.CheckConstraint("attempt > 0", name=op.f("ck_executions_attempt_positive")), sa.ForeignKeyConstraint( ["job_id"], ["jobs.id"], name=op.f("fk_executions_job_id_jobs"), ondelete="RESTRICT" ), sa.ForeignKeyConstraint( ["schedule_id"], ["schedules.id"], name=op.f("fk_executions_schedule_id_schedules"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_executions")), sa.UniqueConstraint( "schedule_id", "nominal_run_at", name="uq_execution_schedule_occurrence" ), ) op.create_index("ix_executions_job_id", "executions", ["job_id"], unique=False) op.create_index( "ix_executions_state_created", "executions", ["state", "created_at"], unique=False ) op.create_index( "uq_executions_active_job", "executions", ["job_id"], unique=True, sqlite_where=sa.text("state IN ('queued','preparing','running','verifying','cancelling')"), ) op.create_table( "backups", sa.Column("execution_id", sa.String(length=36), nullable=False), sa.Column("parent_backup_id", sa.String(length=36), nullable=True), sa.Column("manifest_id", sa.String(length=36), nullable=False), sa.Column("manifest_digest", sa.String(length=64), nullable=False), sa.Column("logical_bytes", sa.Integer(), nullable=False), sa.Column("stored_bytes", sa.Integer(), nullable=False), sa.Column("integrity", sa.String(length=32), nullable=False), sa.Column("pinned", sa.Boolean(), nullable=False), sa.Column("tombstoned_at", sa.DateTime(timezone=True), nullable=True), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column("id", sa.String(length=36), nullable=False), sa.CheckConstraint( "integrity IN ('unverified','verified','degraded','corrupt')", name=op.f("ck_backups_integrity"), ), sa.CheckConstraint("logical_bytes >= 0", name=op.f("ck_backups_logical_bytes_nonnegative")), sa.CheckConstraint("stored_bytes >= 0", name=op.f("ck_backups_stored_bytes_nonnegative")), sa.ForeignKeyConstraint( ["execution_id"], ["executions.id"], name=op.f("fk_backups_execution_id_executions"), ondelete="RESTRICT", ), sa.ForeignKeyConstraint( ["parent_backup_id"], ["backups.id"], name=op.f("fk_backups_parent_backup_id_backups"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_backups")), sa.UniqueConstraint("execution_id", name=op.f("uq_backups_execution_id")), sa.UniqueConstraint("manifest_digest", name=op.f("uq_backups_manifest_digest")), sa.UniqueConstraint("manifest_id", name=op.f("uq_backups_manifest_id")), ) op.create_index("ix_backups_created_at", "backups", ["created_at"], unique=False) op.create_table( "restores", sa.Column("backup_id", sa.String(length=36), nullable=False), sa.Column("destination", sa.Text(), nullable=False), sa.Column("selection", sa.JSON(), nullable=False), sa.Column("overwrite_policy", sa.String(length=32), nullable=False), sa.Column("state", sa.String(length=32), nullable=False), sa.Column("result", sa.JSON(), nullable=True), sa.Column("id", sa.String(length=36), nullable=False), sa.Column( "created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False, ), sa.CheckConstraint( "overwrite_policy IN ('fail','skip','replace')", name=op.f("ck_restores_overwrite_policy"), ), sa.CheckConstraint( "state IN ('queued','running','committed','cancelled','failed')", name=op.f("ck_restores_state"), ), sa.ForeignKeyConstraint( ["backup_id"], ["backups.id"], name=op.f("fk_restores_backup_id_backups"), ondelete="RESTRICT", ), sa.PrimaryKeyConstraint("id", name=op.f("pk_restores")), ) op.create_index("ix_restores_backup_id", "restores", ["backup_id"], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.drop_index("ix_restores_backup_id", table_name="restores") op.drop_table("restores") op.drop_index("ix_backups_created_at", table_name="backups") op.drop_table("backups") op.drop_index( "uq_executions_active_job", table_name="executions", sqlite_where=sa.text("state IN ('queued','preparing','running','verifying','cancelling')"), ) op.drop_index("ix_executions_state_created", table_name="executions") op.drop_index("ix_executions_job_id", table_name="executions") op.drop_table("executions") op.drop_table("schedules") op.drop_index("ix_notification_deliveries_state_next", table_name="notification_deliveries") op.drop_table("notification_deliveries") op.drop_table("notification_subscriptions") op.drop_index("ix_jobs_source_id", table_name="jobs") op.drop_index("ix_jobs_repository_id", table_name="jobs") op.drop_table("jobs") op.drop_index("ix_idempotency_created_at", table_name="idempotency_records") op.drop_table("idempotency_records") op.drop_index("ix_audit_events_created_at", table_name="audit_events") op.drop_index("ix_audit_events_actor_id", table_name="audit_events") op.drop_table("audit_events") op.drop_index("ix_api_tokens_owner_id", table_name="api_tokens") op.drop_table("api_tokens") op.drop_table("users") op.drop_table("sources") op.drop_table("secrets") op.drop_table("repositories") # ### end Alembic commands ###