Create 20260503_0016_add_choose_your_own_adventure.py
This commit is contained in:
parent
4ea67fda13
commit
24dd4e7053
1 changed files with 208 additions and 0 deletions
|
|
@ -0,0 +1,208 @@
|
|||
"""add choose_your_own_adventure tables
|
||||
|
||||
Revision ID: 0016
|
||||
Revises: 0015
|
||||
Create Date: 2026-05-03
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
revision: str = "0016"
|
||||
down_revision: Union[str, None] = "0015"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
"choose_your_own_adventure",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
|
||||
sa.Column(
|
||||
"user_id",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
sa.ForeignKey("users.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("status", sa.Text(), nullable=False, server_default="awaiting_first_entry"),
|
||||
sa.Column("language", sa.Text(), nullable=False),
|
||||
sa.Column("source_language", sa.Text(), nullable=False),
|
||||
sa.Column("competencies", postgresql.JSONB(), nullable=False, server_default="[]"),
|
||||
sa.Column("max_entry_count", sa.Integer(), nullable=False, server_default="6"),
|
||||
sa.Column(
|
||||
"entry_story_text_target_length",
|
||||
postgresql.JSONB(),
|
||||
nullable=False,
|
||||
server_default='{"min": 700, "max": 800}',
|
||||
),
|
||||
sa.Column("title", sa.Text(), nullable=False, server_default="Untitled adventure"),
|
||||
sa.Column("description", sa.Text(), nullable=True),
|
||||
sa.Column("plot_summary", sa.Text(), nullable=True),
|
||||
sa.Column("genres", postgresql.JSONB(), nullable=False, server_default="[]"),
|
||||
sa.Column("setting", postgresql.JSONB(), nullable=False, server_default="[]"),
|
||||
sa.Column("vibes", postgresql.JSONB(), nullable=False, server_default="[]"),
|
||||
sa.Column("protagonist", postgresql.JSONB(), nullable=False, server_default="[]"),
|
||||
sa.Column(
|
||||
"created_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
),
|
||||
sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True),
|
||||
)
|
||||
op.create_index("ix_cyoa_user_id", "choose_your_own_adventure", ["user_id"])
|
||||
op.create_index("ix_cyoa_status", "choose_your_own_adventure", ["status"])
|
||||
|
||||
# Entry table — generated_from_choice_id FK added after possible_choice table is created
|
||||
op.create_table(
|
||||
"choose_your_own_adventure_entry",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
|
||||
sa.Column(
|
||||
"adventure_id",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
sa.ForeignKey("choose_your_own_adventure.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("generated_from_choice_id", postgresql.UUID(as_uuid=True), nullable=True),
|
||||
sa.Column("status", sa.Text(), nullable=False, server_default="generating"),
|
||||
sa.Column("entry_index", sa.Integer(), nullable=False),
|
||||
sa.Column("story_text", sa.Text(), nullable=True),
|
||||
sa.Column("gamemaster_notes", sa.Text(), nullable=True),
|
||||
sa.Column("llm_data", postgresql.JSONB(), nullable=True),
|
||||
sa.Column(
|
||||
"created_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
),
|
||||
sa.UniqueConstraint("adventure_id", "entry_index", name="uq_cyoa_entry_adventure_index"),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_cyoa_entry_adventure_id", "choose_your_own_adventure_entry", ["adventure_id"]
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"choose_your_own_adventure_entry_possible_choice",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
|
||||
sa.Column(
|
||||
"entry_id",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
sa.ForeignKey("choose_your_own_adventure_entry.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("index", sa.Integer(), nullable=False),
|
||||
sa.Column("label", sa.Text(), nullable=False),
|
||||
sa.Column("text", sa.Text(), nullable=False),
|
||||
sa.UniqueConstraint("entry_id", "index", name="uq_cyoa_choice_entry_index"),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_cyoa_choice_entry_id",
|
||||
"choose_your_own_adventure_entry_possible_choice",
|
||||
["entry_id"],
|
||||
)
|
||||
|
||||
# Resolve circular FK: entry → possible_choice
|
||||
op.create_foreign_key(
|
||||
"fk_cyoa_entry_generated_from_choice",
|
||||
"choose_your_own_adventure_entry",
|
||||
"choose_your_own_adventure_entry_possible_choice",
|
||||
["generated_from_choice_id"],
|
||||
["id"],
|
||||
ondelete="SET NULL",
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"choose_your_own_adventure_entry_possible_choice_decision",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
|
||||
sa.Column(
|
||||
"choice_id",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
sa.ForeignKey(
|
||||
"choose_your_own_adventure_entry_possible_choice.id", ondelete="CASCADE"
|
||||
),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column(
|
||||
"user_id",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
sa.ForeignKey("users.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column(
|
||||
"created_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_cyoa_decision_choice_id",
|
||||
"choose_your_own_adventure_entry_possible_choice_decision",
|
||||
["choice_id"],
|
||||
)
|
||||
op.create_index(
|
||||
"ix_cyoa_decision_user_id",
|
||||
"choose_your_own_adventure_entry_possible_choice_decision",
|
||||
["user_id"],
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"choose_your_own_adventure_entry_translation",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
|
||||
sa.Column(
|
||||
"entry_id",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
sa.ForeignKey("choose_your_own_adventure_entry.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("component_type", sa.Text(), nullable=False, server_default="story_text"),
|
||||
sa.Column("target_language", sa.Text(), nullable=False),
|
||||
sa.Column("translated_text", sa.Text(), nullable=False),
|
||||
sa.UniqueConstraint(
|
||||
"entry_id", "component_type", "target_language",
|
||||
name="uq_cyoa_translation_entry_component_lang",
|
||||
),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_cyoa_translation_entry_id",
|
||||
"choose_your_own_adventure_entry_translation",
|
||||
["entry_id"],
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
"choose_your_own_adventure_entry_audio",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
|
||||
sa.Column(
|
||||
"entry_id",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
sa.ForeignKey("choose_your_own_adventure_entry.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("component_type", sa.Text(), nullable=False, server_default="story_text"),
|
||||
sa.Column("tts_provider", sa.Text(), nullable=False, server_default="google_gemini"),
|
||||
sa.Column("tts_options", postgresql.JSONB(), nullable=True),
|
||||
sa.Column("file_name", sa.Text(), nullable=False),
|
||||
sa.UniqueConstraint("entry_id", "component_type", name="uq_cyoa_audio_entry_component"),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_cyoa_audio_entry_id",
|
||||
"choose_your_own_adventure_entry_audio",
|
||||
["entry_id"],
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table("choose_your_own_adventure_entry_audio")
|
||||
op.drop_table("choose_your_own_adventure_entry_translation")
|
||||
op.drop_table("choose_your_own_adventure_entry_possible_choice_decision")
|
||||
op.drop_constraint(
|
||||
"fk_cyoa_entry_generated_from_choice",
|
||||
"choose_your_own_adventure_entry",
|
||||
type_="foreignkey",
|
||||
)
|
||||
op.drop_table("choose_your_own_adventure_entry_possible_choice")
|
||||
op.drop_table("choose_your_own_adventure_entry")
|
||||
op.drop_table("choose_your_own_adventure")
|
||||
Loading…
Reference in a new issue