"""Create backups table for database backup tracking. Revision ID: 0042_backups Revises: 0041_custom_field_definitions Create Date: 2026-07-26 Stores database backup records per tenant with status tracking. """ from __future__ import annotations from typing import Union import sqlalchemy as sa from alembic import op # revision identifiers revision: str = "0043_backups" down_revision: Union[str, None] = "0042_webhooks" branch_labels: Union[str, None] = None depends_on: Union[str, None] = None def upgrade() -> None: conn = op.get_bind() conn.execute( sa.text( """ CREATE TABLE IF NOT EXISTS backups ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL, filename VARCHAR(255) NOT NULL, size_bytes BIGINT, status VARCHAR(20) NOT NULL DEFAULT 'pending', error_message TEXT, created_by UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), completed_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, deleted_at TIMESTAMPTZ ) """ ) ) # Indexes conn.execute( sa.text( "CREATE INDEX IF NOT EXISTS ix_backups_tenant " "ON backups (tenant_id)" ) ) conn.execute( sa.text( "CREATE INDEX IF NOT EXISTS ix_backups_tenant_status " "ON backups (tenant_id, status)" ) ) def downgrade() -> None: conn = op.get_bind() conn.execute(sa.text("DROP INDEX IF EXISTS ix_backups_tenant_status")) conn.execute(sa.text("DROP INDEX IF EXISTS ix_backups_tenant")) conn.execute(sa.text("DROP TABLE IF EXISTS backups"))