398 lines
24 KiB
Python
398 lines
24 KiB
Python
"""Add GEO lifecycle tables
|
|
|
|
Revision ID: d4f6g8h0ab23
|
|
Revises: c3d5e7f9ab12
|
|
Create Date: 2026-05-23 10:00:00.000000
|
|
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = 'd4f6g8h0ab23'
|
|
down_revision: Union[str, Sequence[str], None] = 'c3d5e7f9ab12'
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
"""Add organizations, lifecycle, agent, content, platform_rules, brand_knowledge, keywords tables and modify users."""
|
|
|
|
# 1. organizations table (must be created first as other tables reference it)
|
|
op.create_table(
|
|
'organizations',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('name', sa.String(100), nullable=False),
|
|
sa.Column('slug', sa.String(50), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('logo_url', sa.String(500), nullable=True),
|
|
sa.Column('plan', sa.String(20), server_default='free', nullable=False),
|
|
sa.Column('max_members', sa.Integer(), server_default='5', nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.UniqueConstraint('slug')
|
|
)
|
|
op.create_index('idx_organizations_slug', 'organizations', ['slug'])
|
|
|
|
# 2. Modify users table - add organization_id and role
|
|
op.add_column('users', sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=True))
|
|
op.add_column('users', sa.Column('role', sa.String(20), server_default='owner', nullable=False))
|
|
op.create_foreign_key('fk_users_organization_id', 'users', 'organizations', ['organization_id'], ['id'], ondelete='SET NULL')
|
|
op.create_index('idx_users_organization_id', 'users', ['organization_id'])
|
|
|
|
# 3. org_members table
|
|
op.create_table(
|
|
'org_members',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('role', sa.String(20), server_default='viewer', nullable=False),
|
|
sa.Column('joined_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.Column('invited_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE')
|
|
)
|
|
op.create_index('idx_org_members_organization_id', 'org_members', ['organization_id'])
|
|
op.create_index('idx_org_members_user_id', 'org_members', ['user_id'])
|
|
op.create_index('idx_org_members_org_user', 'org_members', ['organization_id', 'user_id'], unique=True)
|
|
|
|
# 4. lifecycle_projects table
|
|
op.create_table(
|
|
'lifecycle_projects',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('brand_name', sa.String(100), nullable=False),
|
|
sa.Column('brand_aliases', postgresql.JSONB(), server_default='[]', nullable=False),
|
|
sa.Column('current_stage', sa.Integer(), server_default='1', nullable=False),
|
|
sa.Column('status', sa.String(20), server_default='active', nullable=False),
|
|
sa.Column('created_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ondelete='SET NULL')
|
|
)
|
|
op.create_index('idx_lifecycle_projects_organization_id', 'lifecycle_projects', ['organization_id'])
|
|
op.create_index('idx_lifecycle_projects_status', 'lifecycle_projects', ['status'])
|
|
op.create_index('idx_lifecycle_projects_brand_name', 'lifecycle_projects', ['brand_name'])
|
|
|
|
# 5. project_stages table
|
|
op.create_table(
|
|
'project_stages',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('project_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('stage_number', sa.Integer(), nullable=False),
|
|
sa.Column('status', sa.String(20), server_default='pending', nullable=False),
|
|
sa.Column('started_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('notes', sa.Text(), nullable=True),
|
|
sa.Column('metrics', postgresql.JSONB(), nullable=True),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['project_id'], ['lifecycle_projects.id'], ondelete='CASCADE')
|
|
)
|
|
op.create_index('idx_project_stages_project_id', 'project_stages', ['project_id'])
|
|
op.create_index('idx_project_stages_status', 'project_stages', ['status'])
|
|
op.create_index('idx_project_stages_project_stage', 'project_stages', ['project_id', 'stage_number'], unique=True)
|
|
|
|
# 6. agent_registry table
|
|
op.create_table(
|
|
'agent_registry',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('name', sa.String(50), nullable=False),
|
|
sa.Column('display_name', sa.String(100), nullable=True),
|
|
sa.Column('agent_type', sa.String(50), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('version', sa.String(20), nullable=True),
|
|
sa.Column('endpoint', sa.String(500), nullable=True),
|
|
sa.Column('status', sa.String(20), server_default='offline', nullable=False),
|
|
sa.Column('capabilities', postgresql.JSONB(), nullable=True),
|
|
sa.Column('last_heartbeat', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.UniqueConstraint('name')
|
|
)
|
|
op.create_index('idx_agent_registry_name', 'agent_registry', ['name'])
|
|
op.create_index('idx_agent_registry_agent_type', 'agent_registry', ['agent_type'])
|
|
op.create_index('idx_agent_registry_status', 'agent_registry', ['status'])
|
|
|
|
# 7. agent_configs table
|
|
op.create_table(
|
|
'agent_configs',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('agent_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('config_key', sa.String(100), nullable=False),
|
|
sa.Column('config_value', postgresql.JSONB(), nullable=False),
|
|
sa.Column('description', sa.String(500), nullable=True),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.Column('updated_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['agent_id'], ['agent_registry.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['updated_by'], ['users.id'], ondelete='SET NULL')
|
|
)
|
|
op.create_index('idx_agent_configs_agent_id', 'agent_configs', ['agent_id'])
|
|
op.create_index('idx_agent_configs_agent_key', 'agent_configs', ['agent_id', 'config_key'], unique=True)
|
|
|
|
# 8. agent_tasks table
|
|
op.create_table(
|
|
'agent_tasks',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('agent_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('task_type', sa.String(50), nullable=False),
|
|
sa.Column('status', sa.String(20), server_default='pending', nullable=False),
|
|
sa.Column('priority', sa.Integer(), server_default='0', nullable=False),
|
|
sa.Column('input_data', postgresql.JSONB(), nullable=True),
|
|
sa.Column('output_data', postgresql.JSONB(), nullable=True),
|
|
sa.Column('error_message', sa.Text(), nullable=True),
|
|
sa.Column('created_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('project_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('scheduled_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('started_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['agent_id'], ['agent_registry.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ondelete='SET NULL'),
|
|
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['project_id'], ['lifecycle_projects.id'], ondelete='SET NULL')
|
|
)
|
|
op.create_index('idx_agent_tasks_agent_id', 'agent_tasks', ['agent_id'])
|
|
op.create_index('idx_agent_tasks_status', 'agent_tasks', ['status'])
|
|
op.create_index('idx_agent_tasks_organization_id', 'agent_tasks', ['organization_id'])
|
|
op.create_index('idx_agent_tasks_project_id', 'agent_tasks', ['project_id'])
|
|
op.create_index('idx_agent_tasks_created_by', 'agent_tasks', ['created_by'])
|
|
op.create_index('idx_agent_tasks_task_type', 'agent_tasks', ['task_type'])
|
|
|
|
# 9. agent_task_logs table
|
|
op.create_table(
|
|
'agent_task_logs',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('task_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('agent_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('log_level', sa.String(10), nullable=False),
|
|
sa.Column('message', sa.Text(), nullable=False),
|
|
sa.Column('metadata', postgresql.JSONB(), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['task_id'], ['agent_tasks.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['agent_id'], ['agent_registry.id'], ondelete='CASCADE')
|
|
)
|
|
op.create_index('idx_agent_task_logs_task_id', 'agent_task_logs', ['task_id'])
|
|
op.create_index('idx_agent_task_logs_agent_id', 'agent_task_logs', ['agent_id'])
|
|
op.create_index('idx_agent_task_logs_created_at', 'agent_task_logs', ['created_at'])
|
|
|
|
# 10. contents table
|
|
op.create_table(
|
|
'contents',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('project_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('title', sa.String(500), nullable=False),
|
|
sa.Column('content_type', sa.String(50), nullable=False),
|
|
sa.Column('body', sa.Text(), nullable=True),
|
|
sa.Column('status', sa.String(20), server_default='draft', nullable=False),
|
|
sa.Column('target_platforms', postgresql.JSONB(), nullable=True),
|
|
sa.Column('keywords', postgresql.JSONB(), nullable=True),
|
|
sa.Column('metadata', postgresql.JSONB(), nullable=True),
|
|
sa.Column('created_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('current_version', sa.Integer(), server_default='1', nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['project_id'], ['lifecycle_projects.id'], ondelete='SET NULL'),
|
|
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ondelete='SET NULL')
|
|
)
|
|
op.create_index('idx_contents_organization_id', 'contents', ['organization_id'])
|
|
op.create_index('idx_contents_project_id', 'contents', ['project_id'])
|
|
op.create_index('idx_contents_status', 'contents', ['status'])
|
|
op.create_index('idx_contents_content_type', 'contents', ['content_type'])
|
|
op.create_index('idx_contents_created_by', 'contents', ['created_by'])
|
|
|
|
# 11. content_versions table
|
|
op.create_table(
|
|
'content_versions',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('content_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('version_number', sa.Integer(), nullable=False),
|
|
sa.Column('title', sa.String(500), nullable=True),
|
|
sa.Column('body', sa.Text(), nullable=True),
|
|
sa.Column('change_summary', sa.String(500), nullable=True),
|
|
sa.Column('created_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['content_id'], ['contents.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ondelete='SET NULL')
|
|
)
|
|
op.create_index('idx_content_versions_content_id', 'content_versions', ['content_id'])
|
|
op.create_index('idx_content_versions_content_version', 'content_versions', ['content_id', 'version_number'], unique=True)
|
|
|
|
# 12. content_reviews table
|
|
op.create_table(
|
|
'content_reviews',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('content_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('reviewer_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('status', sa.String(20), nullable=False),
|
|
sa.Column('comments', sa.Text(), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['content_id'], ['contents.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['reviewer_id'], ['users.id'], ondelete='CASCADE')
|
|
)
|
|
op.create_index('idx_content_reviews_content_id', 'content_reviews', ['content_id'])
|
|
op.create_index('idx_content_reviews_reviewer_id', 'content_reviews', ['reviewer_id'])
|
|
|
|
# 13. platform_rules table
|
|
op.create_table(
|
|
'platform_rules',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('platform', sa.String(50), nullable=False),
|
|
sa.Column('rule_category', sa.String(50), nullable=False),
|
|
sa.Column('rule_name', sa.String(200), nullable=False),
|
|
sa.Column('description', sa.Text(), nullable=True),
|
|
sa.Column('check_criteria', postgresql.JSONB(), nullable=True),
|
|
sa.Column('severity', sa.String(20), nullable=False),
|
|
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index('idx_platform_rules_platform', 'platform_rules', ['platform'])
|
|
op.create_index('idx_platform_rules_rule_category', 'platform_rules', ['rule_category'])
|
|
op.create_index('idx_platform_rules_is_active', 'platform_rules', ['is_active'])
|
|
op.create_index('idx_platform_rules_platform_category', 'platform_rules', ['platform', 'rule_category'])
|
|
|
|
# 14. brand_knowledge table
|
|
op.create_table(
|
|
'brand_knowledge',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('category', sa.String(50), nullable=False),
|
|
sa.Column('title', sa.String(200), nullable=False),
|
|
sa.Column('content', sa.Text(), nullable=False),
|
|
sa.Column('metadata', postgresql.JSONB(), nullable=True),
|
|
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
|
|
sa.Column('created_by', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ondelete='SET NULL')
|
|
)
|
|
op.create_index('idx_brand_knowledge_organization_id', 'brand_knowledge', ['organization_id'])
|
|
op.create_index('idx_brand_knowledge_category', 'brand_knowledge', ['category'])
|
|
op.create_index('idx_brand_knowledge_is_active', 'brand_knowledge', ['is_active'])
|
|
|
|
# 15. keywords table
|
|
op.create_table(
|
|
'keywords',
|
|
sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('gen_random_uuid()'), nullable=False),
|
|
sa.Column('organization_id', postgresql.UUID(as_uuid=True), nullable=False),
|
|
sa.Column('project_id', postgresql.UUID(as_uuid=True), nullable=True),
|
|
sa.Column('keyword', sa.String(200), nullable=False),
|
|
sa.Column('category', sa.String(50), nullable=False),
|
|
sa.Column('priority', sa.Integer(), server_default='0', nullable=False),
|
|
sa.Column('search_volume', sa.Integer(), nullable=True),
|
|
sa.Column('competition_level', sa.String(20), nullable=True),
|
|
sa.Column('status', sa.String(20), server_default='active', nullable=False),
|
|
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('NOW()'), nullable=False),
|
|
sa.PrimaryKeyConstraint('id'),
|
|
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ondelete='CASCADE'),
|
|
sa.ForeignKeyConstraint(['project_id'], ['lifecycle_projects.id'], ondelete='SET NULL')
|
|
)
|
|
op.create_index('idx_keywords_organization_id', 'keywords', ['organization_id'])
|
|
op.create_index('idx_keywords_project_id', 'keywords', ['project_id'])
|
|
op.create_index('idx_keywords_category', 'keywords', ['category'])
|
|
op.create_index('idx_keywords_status', 'keywords', ['status'])
|
|
op.create_index('idx_keywords_keyword', 'keywords', ['keyword'])
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Remove all GEO lifecycle tables and revert users table changes."""
|
|
|
|
# Drop tables in reverse order (respecting foreign key dependencies)
|
|
op.drop_index('idx_keywords_keyword', table_name='keywords')
|
|
op.drop_index('idx_keywords_status', table_name='keywords')
|
|
op.drop_index('idx_keywords_category', table_name='keywords')
|
|
op.drop_index('idx_keywords_project_id', table_name='keywords')
|
|
op.drop_index('idx_keywords_organization_id', table_name='keywords')
|
|
op.drop_table('keywords')
|
|
|
|
op.drop_index('idx_brand_knowledge_is_active', table_name='brand_knowledge')
|
|
op.drop_index('idx_brand_knowledge_category', table_name='brand_knowledge')
|
|
op.drop_index('idx_brand_knowledge_organization_id', table_name='brand_knowledge')
|
|
op.drop_table('brand_knowledge')
|
|
|
|
op.drop_index('idx_platform_rules_platform_category', table_name='platform_rules')
|
|
op.drop_index('idx_platform_rules_is_active', table_name='platform_rules')
|
|
op.drop_index('idx_platform_rules_rule_category', table_name='platform_rules')
|
|
op.drop_index('idx_platform_rules_platform', table_name='platform_rules')
|
|
op.drop_table('platform_rules')
|
|
|
|
op.drop_index('idx_content_reviews_reviewer_id', table_name='content_reviews')
|
|
op.drop_index('idx_content_reviews_content_id', table_name='content_reviews')
|
|
op.drop_table('content_reviews')
|
|
|
|
op.drop_index('idx_content_versions_content_version', table_name='content_versions')
|
|
op.drop_index('idx_content_versions_content_id', table_name='content_versions')
|
|
op.drop_table('content_versions')
|
|
|
|
op.drop_index('idx_contents_created_by', table_name='contents')
|
|
op.drop_index('idx_contents_content_type', table_name='contents')
|
|
op.drop_index('idx_contents_status', table_name='contents')
|
|
op.drop_index('idx_contents_project_id', table_name='contents')
|
|
op.drop_index('idx_contents_organization_id', table_name='contents')
|
|
op.drop_table('contents')
|
|
|
|
op.drop_index('idx_agent_task_logs_created_at', table_name='agent_task_logs')
|
|
op.drop_index('idx_agent_task_logs_agent_id', table_name='agent_task_logs')
|
|
op.drop_index('idx_agent_task_logs_task_id', table_name='agent_task_logs')
|
|
op.drop_table('agent_task_logs')
|
|
|
|
op.drop_index('idx_agent_tasks_task_type', table_name='agent_tasks')
|
|
op.drop_index('idx_agent_tasks_created_by', table_name='agent_tasks')
|
|
op.drop_index('idx_agent_tasks_project_id', table_name='agent_tasks')
|
|
op.drop_index('idx_agent_tasks_organization_id', table_name='agent_tasks')
|
|
op.drop_index('idx_agent_tasks_status', table_name='agent_tasks')
|
|
op.drop_index('idx_agent_tasks_agent_id', table_name='agent_tasks')
|
|
op.drop_table('agent_tasks')
|
|
|
|
op.drop_index('idx_agent_configs_agent_key', table_name='agent_configs')
|
|
op.drop_index('idx_agent_configs_agent_id', table_name='agent_configs')
|
|
op.drop_table('agent_configs')
|
|
|
|
op.drop_index('idx_agent_registry_status', table_name='agent_registry')
|
|
op.drop_index('idx_agent_registry_agent_type', table_name='agent_registry')
|
|
op.drop_index('idx_agent_registry_name', table_name='agent_registry')
|
|
op.drop_table('agent_registry')
|
|
|
|
op.drop_index('idx_project_stages_project_stage', table_name='project_stages')
|
|
op.drop_index('idx_project_stages_status', table_name='project_stages')
|
|
op.drop_index('idx_project_stages_project_id', table_name='project_stages')
|
|
op.drop_table('project_stages')
|
|
|
|
op.drop_index('idx_lifecycle_projects_brand_name', table_name='lifecycle_projects')
|
|
op.drop_index('idx_lifecycle_projects_status', table_name='lifecycle_projects')
|
|
op.drop_index('idx_lifecycle_projects_organization_id', table_name='lifecycle_projects')
|
|
op.drop_table('lifecycle_projects')
|
|
|
|
op.drop_index('idx_org_members_org_user', table_name='org_members')
|
|
op.drop_index('idx_org_members_user_id', table_name='org_members')
|
|
op.drop_index('idx_org_members_organization_id', table_name='org_members')
|
|
op.drop_table('org_members')
|
|
|
|
# Revert users table changes
|
|
op.drop_index('idx_users_organization_id', table_name='users')
|
|
op.drop_constraint('fk_users_organization_id', 'users', type_='foreignkey')
|
|
op.drop_column('users', 'role')
|
|
op.drop_column('users', 'organization_id')
|
|
|
|
op.drop_index('idx_organizations_slug', table_name='organizations')
|
|
op.drop_table('organizations')
|