"""initial persistence models Revision ID: b57c5b216bce Revises: Create Date: 2026-06-07 19:29:10.222504 """ from __future__ import annotations from alembic import op import sqlalchemy as sa revision = 'b57c5b216bce' down_revision = None branch_labels = None depends_on = None def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.create_table('tenants', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('slug', sa.String(length=100), nullable=False), sa.Column('name', sa.String(length=255), nullable=False), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_tenants')) ) op.create_index(op.f('ix_tenants_slug'), 'tenants', ['slug'], unique=True) op.create_table('attachment_blobs', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=False), sa.Column('sha256', sa.String(length=64), nullable=False), sa.Column('size_bytes', sa.Integer(), nullable=False), sa.Column('mime_type', sa.String(length=255), nullable=True), sa.Column('storage_bucket', sa.String(length=255), nullable=False), sa.Column('storage_key', sa.String(length=1000), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_attachment_blobs_tenant_id_tenants'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_attachment_blobs')), sa.UniqueConstraint('tenant_id', 'sha256', name='uq_attachment_blobs_tenant_sha256') ) op.create_index(op.f('ix_attachment_blobs_sha256'), 'attachment_blobs', ['sha256'], unique=False) op.create_index(op.f('ix_attachment_blobs_tenant_id'), 'attachment_blobs', ['tenant_id'], unique=False) op.create_table('groups', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=False), sa.Column('slug', sa.String(length=100), nullable=False), sa.Column('name', sa.String(length=255), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_groups_tenant_id_tenants'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_groups')), sa.UniqueConstraint('tenant_id', 'slug', name='uq_groups_tenant_slug') ) op.create_index(op.f('ix_groups_tenant_id'), 'groups', ['tenant_id'], unique=False) op.create_table('roles', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=True), sa.Column('slug', sa.String(length=100), nullable=False), sa.Column('name', sa.String(length=255), nullable=False), sa.Column('permissions', sa.JSON(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_roles_tenant_id_tenants'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_roles')), sa.UniqueConstraint('tenant_id', 'slug', name='uq_roles_tenant_slug') ) op.create_index(op.f('ix_roles_tenant_id'), 'roles', ['tenant_id'], unique=False) op.create_table('users', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=False), sa.Column('email', sa.String(length=320), nullable=False), sa.Column('display_name', sa.String(length=255), nullable=True), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('is_tenant_admin', sa.Boolean(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_users_tenant_id_tenants'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_users')), sa.UniqueConstraint('tenant_id', 'email', name='uq_users_tenant_email') ) op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=False) op.create_index(op.f('ix_users_tenant_id'), 'users', ['tenant_id'], unique=False) op.create_table('api_keys', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=False), sa.Column('user_id', sa.String(length=36), nullable=False), sa.Column('name', sa.String(length=255), nullable=False), sa.Column('prefix', sa.String(length=16), nullable=False), sa.Column('key_hash', sa.String(length=128), nullable=False), sa.Column('scopes', sa.JSON(), nullable=False), sa.Column('expires_at', sa.DateTime(timezone=True), nullable=True), sa.Column('last_used_at', sa.DateTime(timezone=True), nullable=True), sa.Column('revoked_at', sa.DateTime(timezone=True), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_api_keys_tenant_id_tenants'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_api_keys_user_id_users'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_api_keys')) ) op.create_index(op.f('ix_api_keys_prefix'), 'api_keys', ['prefix'], unique=False) op.create_index(op.f('ix_api_keys_tenant_id'), 'api_keys', ['tenant_id'], unique=False) op.create_index(op.f('ix_api_keys_user_id'), 'api_keys', ['user_id'], unique=False) op.create_table('campaigns', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=False), sa.Column('created_by_user_id', sa.String(length=36), nullable=True), sa.Column('external_id', sa.String(length=255), nullable=False), sa.Column('name', sa.String(length=255), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('status', sa.String(length=50), nullable=False), sa.Column('current_version_id', sa.String(length=36), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['created_by_user_id'], ['users.id'], name=op.f('fk_campaigns_created_by_user_id_users'), ondelete='SET NULL'), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_campaigns_tenant_id_tenants'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_campaigns')), sa.UniqueConstraint('tenant_id', 'external_id', name='uq_campaigns_tenant_external_id') ) op.create_index(op.f('ix_campaigns_created_by_user_id'), 'campaigns', ['created_by_user_id'], unique=False) op.create_index(op.f('ix_campaigns_external_id'), 'campaigns', ['external_id'], unique=False) op.create_index(op.f('ix_campaigns_status'), 'campaigns', ['status'], unique=False) op.create_index(op.f('ix_campaigns_tenant_id'), 'campaigns', ['tenant_id'], unique=False) op.create_table('attachment_instances', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=False), sa.Column('owner_user_id', sa.String(length=36), nullable=True), sa.Column('campaign_id', sa.String(length=36), nullable=True), sa.Column('blob_id', sa.String(length=36), nullable=False), sa.Column('logical_name', sa.String(length=500), nullable=True), sa.Column('filename', sa.String(length=500), nullable=False), sa.Column('tags', sa.JSON(), nullable=False), sa.Column('metadata', sa.JSON(), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['blob_id'], ['attachment_blobs.id'], name=op.f('fk_attachment_instances_blob_id_attachment_blobs'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['campaign_id'], ['campaigns.id'], name=op.f('fk_attachment_instances_campaign_id_campaigns'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['owner_user_id'], ['users.id'], name=op.f('fk_attachment_instances_owner_user_id_users'), ondelete='SET NULL'), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_attachment_instances_tenant_id_tenants'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_attachment_instances')) ) op.create_index(op.f('ix_attachment_instances_blob_id'), 'attachment_instances', ['blob_id'], unique=False) op.create_index(op.f('ix_attachment_instances_campaign_id'), 'attachment_instances', ['campaign_id'], unique=False) op.create_index(op.f('ix_attachment_instances_owner_user_id'), 'attachment_instances', ['owner_user_id'], unique=False) op.create_index(op.f('ix_attachment_instances_tenant_id'), 'attachment_instances', ['tenant_id'], unique=False) op.create_table('audit_log', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=True), sa.Column('user_id', sa.String(length=36), nullable=True), sa.Column('api_key_id', sa.String(length=36), nullable=True), sa.Column('action', sa.String(length=100), nullable=False), sa.Column('object_type', sa.String(length=100), nullable=True), sa.Column('object_id', sa.String(length=100), nullable=True), sa.Column('details', sa.JSON(), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['api_key_id'], ['api_keys.id'], name=op.f('fk_audit_log_api_key_id_api_keys'), ondelete='SET NULL'), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_audit_log_tenant_id_tenants'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_audit_log_user_id_users'), ondelete='SET NULL'), sa.PrimaryKeyConstraint('id', name=op.f('pk_audit_log')) ) op.create_index(op.f('ix_audit_log_action'), 'audit_log', ['action'], unique=False) op.create_index(op.f('ix_audit_log_api_key_id'), 'audit_log', ['api_key_id'], unique=False) op.create_index(op.f('ix_audit_log_object_id'), 'audit_log', ['object_id'], unique=False) op.create_index(op.f('ix_audit_log_object_type'), 'audit_log', ['object_type'], unique=False) op.create_index(op.f('ix_audit_log_tenant_id'), 'audit_log', ['tenant_id'], unique=False) op.create_index(op.f('ix_audit_log_user_id'), 'audit_log', ['user_id'], unique=False) op.create_table('campaign_versions', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('campaign_id', sa.String(length=36), nullable=False), sa.Column('version_number', sa.Integer(), nullable=False), sa.Column('raw_json', sa.JSON(), nullable=False), sa.Column('schema_version', sa.String(length=50), nullable=False), sa.Column('source_filename', sa.String(length=500), nullable=True), sa.Column('validation_summary', sa.JSON(), nullable=True), sa.Column('build_summary', sa.JSON(), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['campaign_id'], ['campaigns.id'], name=op.f('fk_campaign_versions_campaign_id_campaigns'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_campaign_versions')), sa.UniqueConstraint('campaign_id', 'version_number', name='uq_campaign_versions_campaign_number') ) op.create_index(op.f('ix_campaign_versions_campaign_id'), 'campaign_versions', ['campaign_id'], unique=False) op.create_table('campaign_jobs', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=False), sa.Column('campaign_id', sa.String(length=36), nullable=False), sa.Column('campaign_version_id', sa.String(length=36), nullable=False), sa.Column('entry_index', sa.Integer(), nullable=False), sa.Column('entry_id', sa.String(length=255), nullable=True), sa.Column('recipient_email', sa.String(length=320), nullable=True), sa.Column('subject', sa.String(length=998), nullable=True), sa.Column('message_id_header', sa.String(length=255), nullable=True), sa.Column('eml_storage_key', sa.String(length=1000), nullable=True), sa.Column('eml_local_path', sa.String(length=1000), nullable=True), sa.Column('eml_size_bytes', sa.Integer(), nullable=True), sa.Column('build_status', sa.String(length=50), nullable=False), sa.Column('validation_status', sa.String(length=50), nullable=False), sa.Column('queue_status', sa.String(length=50), nullable=False), sa.Column('send_status', sa.String(length=50), nullable=False), sa.Column('imap_status', sa.String(length=50), nullable=False), sa.Column('attempt_count', sa.Integer(), nullable=False), sa.Column('last_error', sa.Text(), nullable=True), sa.Column('queued_at', sa.DateTime(timezone=True), nullable=True), sa.Column('sent_at', sa.DateTime(timezone=True), nullable=True), sa.Column('resolved_recipients', sa.JSON(), nullable=True), sa.Column('resolved_attachments', sa.JSON(), nullable=False), sa.Column('issues_snapshot', sa.JSON(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['campaign_id'], ['campaigns.id'], name=op.f('fk_campaign_jobs_campaign_id_campaigns'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['campaign_version_id'], ['campaign_versions.id'], name=op.f('fk_campaign_jobs_campaign_version_id_campaign_versions'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_campaign_jobs_tenant_id_tenants'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_campaign_jobs')), sa.UniqueConstraint('campaign_version_id', 'entry_index', name='uq_campaign_jobs_version_entry') ) op.create_index(op.f('ix_campaign_jobs_build_status'), 'campaign_jobs', ['build_status'], unique=False) op.create_index(op.f('ix_campaign_jobs_campaign_id'), 'campaign_jobs', ['campaign_id'], unique=False) op.create_index(op.f('ix_campaign_jobs_campaign_version_id'), 'campaign_jobs', ['campaign_version_id'], unique=False) op.create_index(op.f('ix_campaign_jobs_entry_id'), 'campaign_jobs', ['entry_id'], unique=False) op.create_index(op.f('ix_campaign_jobs_imap_status'), 'campaign_jobs', ['imap_status'], unique=False) op.create_index(op.f('ix_campaign_jobs_queue_status'), 'campaign_jobs', ['queue_status'], unique=False) op.create_index(op.f('ix_campaign_jobs_recipient_email'), 'campaign_jobs', ['recipient_email'], unique=False) op.create_index(op.f('ix_campaign_jobs_send_status'), 'campaign_jobs', ['send_status'], unique=False) op.create_index(op.f('ix_campaign_jobs_tenant_id'), 'campaign_jobs', ['tenant_id'], unique=False) op.create_index(op.f('ix_campaign_jobs_validation_status'), 'campaign_jobs', ['validation_status'], unique=False) op.create_table('campaign_issues', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('tenant_id', sa.String(length=36), nullable=False), sa.Column('campaign_id', sa.String(length=36), nullable=False), sa.Column('campaign_version_id', sa.String(length=36), nullable=True), sa.Column('job_id', sa.String(length=36), nullable=True), sa.Column('severity', sa.String(length=20), nullable=False), sa.Column('code', sa.String(length=100), nullable=False), sa.Column('message', sa.Text(), nullable=False), sa.Column('source', sa.String(length=255), nullable=True), sa.Column('behavior', sa.String(length=50), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['campaign_id'], ['campaigns.id'], name=op.f('fk_campaign_issues_campaign_id_campaigns'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['campaign_version_id'], ['campaign_versions.id'], name=op.f('fk_campaign_issues_campaign_version_id_campaign_versions'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['job_id'], ['campaign_jobs.id'], name=op.f('fk_campaign_issues_job_id_campaign_jobs'), ondelete='CASCADE'), sa.ForeignKeyConstraint(['tenant_id'], ['tenants.id'], name=op.f('fk_campaign_issues_tenant_id_tenants'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_campaign_issues')) ) op.create_index(op.f('ix_campaign_issues_campaign_id'), 'campaign_issues', ['campaign_id'], unique=False) op.create_index(op.f('ix_campaign_issues_campaign_version_id'), 'campaign_issues', ['campaign_version_id'], unique=False) op.create_index(op.f('ix_campaign_issues_code'), 'campaign_issues', ['code'], unique=False) op.create_index(op.f('ix_campaign_issues_job_id'), 'campaign_issues', ['job_id'], unique=False) op.create_index(op.f('ix_campaign_issues_severity'), 'campaign_issues', ['severity'], unique=False) op.create_index(op.f('ix_campaign_issues_tenant_id'), 'campaign_issues', ['tenant_id'], unique=False) op.create_table('imap_append_attempts', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('job_id', sa.String(length=36), nullable=False), sa.Column('attempt_number', sa.Integer(), nullable=False), sa.Column('folder', sa.String(length=500), nullable=True), sa.Column('status', sa.String(length=50), nullable=False), sa.Column('error_message', sa.Text(), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['job_id'], ['campaign_jobs.id'], name=op.f('fk_imap_append_attempts_job_id_campaign_jobs'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_imap_append_attempts')) ) op.create_index(op.f('ix_imap_append_attempts_job_id'), 'imap_append_attempts', ['job_id'], unique=False) op.create_table('send_attempts', sa.Column('id', sa.String(length=36), nullable=False), sa.Column('job_id', sa.String(length=36), nullable=False), sa.Column('attempt_number', sa.Integer(), nullable=False), sa.Column('smtp_status_code', sa.Integer(), nullable=True), sa.Column('smtp_response', sa.Text(), nullable=True), sa.Column('error_type', sa.String(length=255), nullable=True), sa.Column('error_message', sa.Text(), nullable=True), sa.Column('started_at', sa.DateTime(timezone=True), nullable=True), sa.Column('finished_at', sa.DateTime(timezone=True), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['job_id'], ['campaign_jobs.id'], name=op.f('fk_send_attempts_job_id_campaign_jobs'), ondelete='CASCADE'), sa.PrimaryKeyConstraint('id', name=op.f('pk_send_attempts')) ) op.create_index(op.f('ix_send_attempts_job_id'), 'send_attempts', ['job_id'], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.drop_index(op.f('ix_send_attempts_job_id'), table_name='send_attempts') op.drop_table('send_attempts') op.drop_index(op.f('ix_imap_append_attempts_job_id'), table_name='imap_append_attempts') op.drop_table('imap_append_attempts') op.drop_index(op.f('ix_campaign_issues_tenant_id'), table_name='campaign_issues') op.drop_index(op.f('ix_campaign_issues_severity'), table_name='campaign_issues') op.drop_index(op.f('ix_campaign_issues_job_id'), table_name='campaign_issues') op.drop_index(op.f('ix_campaign_issues_code'), table_name='campaign_issues') op.drop_index(op.f('ix_campaign_issues_campaign_version_id'), table_name='campaign_issues') op.drop_index(op.f('ix_campaign_issues_campaign_id'), table_name='campaign_issues') op.drop_table('campaign_issues') op.drop_index(op.f('ix_campaign_jobs_validation_status'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_tenant_id'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_send_status'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_recipient_email'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_queue_status'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_imap_status'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_entry_id'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_campaign_version_id'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_campaign_id'), table_name='campaign_jobs') op.drop_index(op.f('ix_campaign_jobs_build_status'), table_name='campaign_jobs') op.drop_table('campaign_jobs') op.drop_index(op.f('ix_campaign_versions_campaign_id'), table_name='campaign_versions') op.drop_table('campaign_versions') op.drop_index(op.f('ix_audit_log_user_id'), table_name='audit_log') op.drop_index(op.f('ix_audit_log_tenant_id'), table_name='audit_log') op.drop_index(op.f('ix_audit_log_object_type'), table_name='audit_log') op.drop_index(op.f('ix_audit_log_object_id'), table_name='audit_log') op.drop_index(op.f('ix_audit_log_api_key_id'), table_name='audit_log') op.drop_index(op.f('ix_audit_log_action'), table_name='audit_log') op.drop_table('audit_log') op.drop_index(op.f('ix_attachment_instances_tenant_id'), table_name='attachment_instances') op.drop_index(op.f('ix_attachment_instances_owner_user_id'), table_name='attachment_instances') op.drop_index(op.f('ix_attachment_instances_campaign_id'), table_name='attachment_instances') op.drop_index(op.f('ix_attachment_instances_blob_id'), table_name='attachment_instances') op.drop_table('attachment_instances') op.drop_index(op.f('ix_campaigns_tenant_id'), table_name='campaigns') op.drop_index(op.f('ix_campaigns_status'), table_name='campaigns') op.drop_index(op.f('ix_campaigns_external_id'), table_name='campaigns') op.drop_index(op.f('ix_campaigns_created_by_user_id'), table_name='campaigns') op.drop_table('campaigns') op.drop_index(op.f('ix_api_keys_user_id'), table_name='api_keys') op.drop_index(op.f('ix_api_keys_tenant_id'), table_name='api_keys') op.drop_index(op.f('ix_api_keys_prefix'), table_name='api_keys') op.drop_table('api_keys') op.drop_index(op.f('ix_users_tenant_id'), table_name='users') op.drop_index(op.f('ix_users_email'), table_name='users') op.drop_table('users') op.drop_index(op.f('ix_roles_tenant_id'), table_name='roles') op.drop_table('roles') op.drop_index(op.f('ix_groups_tenant_id'), table_name='groups') op.drop_table('groups') op.drop_index(op.f('ix_attachment_blobs_tenant_id'), table_name='attachment_blobs') op.drop_index(op.f('ix_attachment_blobs_sha256'), table_name='attachment_blobs') op.drop_table('attachment_blobs') op.drop_index(op.f('ix_tenants_slug'), table_name='tenants') op.drop_table('tenants') # ### end Alembic commands ###