"""add world_rooms, world_chunks, world_chunk_revisions tables Revision ID: 0005_add_world_content_tables Revises: 0004_add_avatar_loadouts_table Create Date: 2026-09-14 00:00:00.000000 See docs/architecture/world_persistence_impl.md ยง4. Chunk content (rooms, chunk payloads, chunk revisions) lives in Postgres, purely additive to the existing ``worlds`` table. """ 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 = "0005_add_world_content_tables" down_revision: Union[str, None] = "0004_add_avatar_loadouts_table" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.create_table( "world_rooms", sa.Column("id", sa.Integer(), primary_key=True, index=True), sa.Column( "world_id", sa.Integer(), sa.ForeignKey("worlds.id", ondelete="CASCADE"), nullable=False, ), sa.Column("slug", sa.String(64), nullable=False), sa.Column("name", sa.String(255), nullable=False), sa.Column( "grid", postgresql.JSONB(), nullable=False, server_default='{"size": [32, 32, 1], "origin": [0, 0, 0]}', ), sa.Column("bounds", postgresql.JSONB(), nullable=True), sa.Column("spawn", postgresql.JSONB(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False, ), sa.UniqueConstraint("world_id", "slug", name="uq_world_rooms_world_slug"), ) op.create_index("ix_world_rooms_world_id", "world_rooms", ["world_id"]) op.create_table( "world_chunks", sa.Column("id", sa.Integer(), primary_key=True, index=True), sa.Column( "world_id", sa.Integer(), sa.ForeignKey("worlds.id", ondelete="CASCADE"), nullable=False, ), sa.Column( "room_id", sa.Integer(), sa.ForeignKey("world_rooms.id", ondelete="CASCADE"), nullable=False, ), sa.Column("chunk_key", sa.String(160), nullable=False, unique=True), sa.Column("cx", sa.Integer(), nullable=False), sa.Column("cy", sa.Integer(), nullable=False), sa.Column("cz", sa.Integer(), nullable=False, server_default="0"), sa.Column("format_version", sa.Integer(), nullable=False, server_default="1"), sa.Column("payload", sa.LargeBinary(), nullable=False), sa.Column("payload_len", sa.Integer(), nullable=False), sa.Column("checksum", sa.String(64), nullable=False), sa.Column("revision", sa.Integer(), nullable=False, server_default="1"), sa.Column("content_flags", postgresql.JSONB(), nullable=False, server_default="{}"), sa.Column("is_mature", sa.Boolean(), nullable=False, server_default="false"), sa.Column( "updated_by_id", sa.Integer(), sa.ForeignKey("users.id", ondelete="SET NULL"), nullable=True, ), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False), sa.Column( "updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False, ), sa.UniqueConstraint("room_id", "cx", "cy", "cz", name="uq_world_chunks_coord"), ) op.create_index("ix_world_chunks_world_id", "world_chunks", ["world_id"]) op.create_index("ix_world_chunks_room_id", "world_chunks", ["room_id"]) op.create_index( "ix_world_chunks_room_coord", "world_chunks", ["room_id", "cx", "cy", "cz"], ) op.create_index( "ix_world_chunks_mature", "world_chunks", ["world_id"], postgresql_where=sa.text("is_mature"), ) op.create_table( "world_chunk_revisions", sa.Column("id", sa.Integer(), primary_key=True, index=True), sa.Column("chunk_key", sa.String(160), nullable=False), sa.Column("world_id", sa.Integer(), nullable=False), sa.Column("revision", sa.Integer(), nullable=False), sa.Column("action", sa.String(16), nullable=False), sa.Column( "actor_id", sa.Integer(), sa.ForeignKey("users.id", ondelete="SET NULL"), nullable=True, ), sa.Column("checksum", sa.String(64), nullable=False), sa.Column("payload", sa.LargeBinary(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False), ) op.create_index("ix_world_chunk_revisions_chunk_key", "world_chunk_revisions", ["chunk_key"]) op.create_index("ix_world_chunk_revisions_world_id", "world_chunk_revisions", ["world_id"]) op.create_index("ix_world_chunk_revisions_created_at", "world_chunk_revisions", ["created_at"]) def downgrade() -> None: op.drop_table("world_chunk_revisions") op.drop_table("world_chunks") op.drop_table("world_rooms")