geo/backend/alembic/versions/g1h2i3j4kl56_add_missing_ta...

158 lines
8.9 KiB
Python

"""Add missing tables: brands, competitors, api_keys, usage_records, platform_rule_versions, detection_tasks
Revision ID: g1h2i3j4kl56
Revises: f7a8b9c0de56
Create Date: 2026-05-26 10:00:00.000000
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
revision: str = "g1h2i3j4kl56"
down_revision: Union[str, Sequence[str], None] = "f7a8b9c0de56"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table(
"brands",
sa.Column("id", postgresql.UUID(as_uuid=True), server_default=sa.text("gen_random_uuid()"), nullable=False),
sa.Column("user_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("name", sa.String(50), nullable=False),
sa.Column("aliases", postgresql.JSONB(), server_default="[]", nullable=False),
sa.Column("website", sa.String(500), nullable=True),
sa.Column("industry", sa.String(50), nullable=True),
sa.Column("platforms", postgresql.JSONB(), server_default="[]", nullable=False),
sa.Column("frequency", sa.String(20), server_default="weekly", nullable=False),
sa.Column("status", sa.String(20), server_default="active", nullable=False),
sa.Column("last_queried_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("next_query_at", 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"),
)
op.create_index("idx_brands_user_id", "brands", ["user_id"])
op.create_table(
"competitors",
sa.Column("id", postgresql.UUID(as_uuid=True), server_default=sa.text("gen_random_uuid()"), nullable=False),
sa.Column("brand_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("name", sa.String(50), nullable=False),
sa.Column("aliases", postgresql.JSONB(), server_default="[]", nullable=False),
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False),
sa.PrimaryKeyConstraint("id"),
sa.ForeignKeyConstraint(["brand_id"], ["brands.id"], ondelete="CASCADE"),
)
op.create_index("idx_competitors_brand_id", "competitors", ["brand_id"])
op.create_table(
"api_keys",
sa.Column("id", postgresql.UUID(as_uuid=True), server_default=sa.text("gen_random_uuid()"), nullable=False),
sa.Column("user_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("engine_type", sa.String(20), nullable=False),
sa.Column("encrypted_key", sa.String(500), nullable=False),
sa.Column("key_hint", sa.String(50), nullable=False),
sa.Column("key_source", sa.String(10), server_default="user", nullable=True),
sa.Column("status", sa.String(20), server_default="active", nullable=True),
sa.Column("priority", sa.Integer(), server_default="0", nullable=True),
sa.Column("last_verified_at", 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"),
)
op.create_index("idx_api_keys_user_id", "api_keys", ["user_id"])
op.create_index("idx_api_keys_user_engine", "api_keys", ["user_id", "engine_type"])
op.create_index("idx_api_keys_engine_status", "api_keys", ["engine_type", "status"])
op.create_table(
"usage_records",
sa.Column("id", postgresql.UUID(as_uuid=True), server_default=sa.text("gen_random_uuid()"), nullable=False),
sa.Column("user_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("brand_id", postgresql.UUID(as_uuid=True), nullable=True),
sa.Column("engine_type", sa.String(20), nullable=False),
sa.Column("query", sa.String(500), nullable=False),
sa.Column("input_tokens", sa.Integer(), server_default="0", nullable=True),
sa.Column("output_tokens", sa.Integer(), server_default="0", nullable=True),
sa.Column("cost", sa.Float(), server_default="0.0", nullable=True),
sa.Column("extra_data", postgresql.JSONB(), server_default="{}", nullable=True),
sa.Column("timestamp", 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(["brand_id"], ["brands.id"], ondelete="SET NULL"),
)
op.create_index("idx_usage_records_user_id", "usage_records", ["user_id"])
op.create_index("idx_usage_records_timestamp", "usage_records", ["timestamp"])
op.create_index("idx_usage_records_user_engine", "usage_records", ["user_id", "engine_type"])
op.create_index("idx_usage_records_user_timestamp", "usage_records", ["user_id", "timestamp"])
op.create_index("idx_usage_records_engine_timestamp", "usage_records", ["engine_type", "timestamp"])
op.create_table(
"platform_rule_versions",
sa.Column("id", postgresql.UUID(as_uuid=True), server_default=sa.text("gen_random_uuid()"), nullable=False),
sa.Column("rule_id", sa.String(100), nullable=False),
sa.Column("platform", sa.String(50), nullable=False),
sa.Column("version", sa.Integer(), nullable=False),
sa.Column("rule_data", postgresql.JSONB(), nullable=False),
sa.Column("change_summary", sa.String(500), nullable=True),
sa.Column("created_by", sa.String(100), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=True),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("idx_rule_versions_rule_id", "platform_rule_versions", ["rule_id"])
op.create_index("idx_rule_versions_platform", "platform_rule_versions", ["platform"])
op.create_table(
"detection_tasks",
sa.Column("id", postgresql.UUID(as_uuid=True), server_default=sa.text("gen_random_uuid()"), nullable=False),
sa.Column("brand_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("user_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("name", sa.String(200), nullable=False),
sa.Column("frequency", sa.String(20), nullable=False),
sa.Column("engines", postgresql.JSONB(), server_default="[]", nullable=False),
sa.Column("queries", postgresql.JSONB(), server_default="[]", nullable=False),
sa.Column("competitor_names", postgresql.JSONB(), nullable=True),
sa.Column("is_active", sa.Boolean(), server_default="true", nullable=False),
sa.Column("last_run_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("next_run_at", 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.ForeignKeyConstraint(["brand_id"], ["brands.id"], ondelete="CASCADE"),
)
op.create_index("idx_detection_tasks_brand_id", "detection_tasks", ["brand_id"])
op.create_index("idx_detection_tasks_user_id", "detection_tasks", ["user_id"])
op.create_index("idx_detection_tasks_is_active", "detection_tasks", ["is_active"])
def downgrade() -> None:
op.drop_index("idx_detection_tasks_is_active", table_name="detection_tasks")
op.drop_index("idx_detection_tasks_user_id", table_name="detection_tasks")
op.drop_index("idx_detection_tasks_brand_id", table_name="detection_tasks")
op.drop_table("detection_tasks")
op.drop_index("idx_rule_versions_platform", table_name="platform_rule_versions")
op.drop_index("idx_rule_versions_rule_id", table_name="platform_rule_versions")
op.drop_table("platform_rule_versions")
op.drop_index("idx_usage_records_engine_timestamp", table_name="usage_records")
op.drop_index("idx_usage_records_user_timestamp", table_name="usage_records")
op.drop_index("idx_usage_records_user_engine", table_name="usage_records")
op.drop_index("idx_usage_records_timestamp", table_name="usage_records")
op.drop_index("idx_usage_records_user_id", table_name="usage_records")
op.drop_table("usage_records")
op.drop_index("idx_api_keys_engine_status", table_name="api_keys")
op.drop_index("idx_api_keys_user_engine", table_name="api_keys")
op.drop_index("idx_api_keys_user_id", table_name="api_keys")
op.drop_table("api_keys")
op.drop_index("idx_competitors_brand_id", table_name="competitors")
op.drop_table("competitors")
op.drop_index("idx_brands_user_id", table_name="brands")
op.drop_table("brands")