"""add discovery metadata to worlds and create world_visits table Revision ID: 0015_add_discovery_metadata Revises: 0014_add_payout_requests Create Date: 2026-09-15 00:00:00.000000 docs/planning/discovery.md (task b377353b8167). """ 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 = "0015_add_discovery_metadata" down_revision: Union[str, None] = "0014_add_payout_requests" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # 1. Add discovery metadata columns to worlds table op.add_column("worlds", sa.Column("category", sa.String(length=100), nullable=True)) op.add_column("worlds", sa.Column("tags", postgresql.ARRAY(sa.String()), server_default="{}", nullable=True)) op.add_column("worlds", sa.Column("play_count", sa.Integer(), server_default="0", nullable=False)) op.add_column("worlds", sa.Column("last_played_at", sa.DateTime(timezone=True), nullable=True)) op.create_index("ix_worlds_category", "worlds", ["category"], unique=False) op.create_index("ix_worlds_tags", "worlds", ["tags"], unique=False, postgresql_using="gin") # 2. Create world_visits table op.create_table( "world_visits", sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), sa.Column("world_id", sa.Integer(), nullable=False), sa.Column("user_id", sa.Integer(), nullable=True), sa.Column("anonymous_token", sa.String(length=255), nullable=True), sa.Column("visited_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False), sa.ForeignKeyConstraint(["world_id"], ["worlds.id"], ondelete="CASCADE"), sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="SET NULL"), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_world_visits_world_id", "world_visits", ["world_id"], unique=False) op.create_index("ix_world_visits_user_id", "world_visits", ["user_id"], unique=False) op.create_index("ix_world_visits_visited_at", "world_visits", ["visited_at"], unique=False) op.create_index("ix_world_visits_world_visited_at", "world_visits", ["world_id", "visited_at"], unique=False) def downgrade() -> None: op.drop_index("ix_world_visits_world_visited_at", table_name="world_visits") op.drop_index("ix_world_visits_visited_at", table_name="world_visits") op.drop_index("ix_world_visits_user_id", table_name="world_visits") op.drop_index("ix_world_visits_world_id", table_name="world_visits") op.drop_table("world_visits") op.drop_index("ix_worlds_tags", table_name="worlds", postgresql_using="gin") op.drop_index("ix_worlds_category", table_name="worlds") op.drop_column("worlds", "last_played_at") op.drop_column("worlds", "play_count") op.drop_column("worlds", "tags") op.drop_column("worlds", "category")