feat: add auth system, boss pokemon details, moves/abilities API, and run ownership
Add user authentication with login/signup/protected routes, boss pokemon detail fields and result team tracking, moves and abilities selector components and API, run ownership and visibility controls, and various UI improvements across encounters, run list, and journal pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
"""add boss pokemon details
|
||||
|
||||
Revision ID: l3a4b5c6d7e8
|
||||
Revises: k2f3a4b5c6d7
|
||||
Create Date: 2026-03-20 19:30:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "l3a4b5c6d7e8"
|
||||
down_revision: str | Sequence[str] | None = "k2f3a4b5c6d7"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Add ability reference
|
||||
op.add_column(
|
||||
"boss_pokemon",
|
||||
sa.Column(
|
||||
"ability_id", sa.Integer(), sa.ForeignKey("abilities.id"), nullable=True
|
||||
),
|
||||
)
|
||||
op.create_index("ix_boss_pokemon_ability_id", "boss_pokemon", ["ability_id"])
|
||||
|
||||
# Add held item (plain string)
|
||||
op.add_column(
|
||||
"boss_pokemon",
|
||||
sa.Column("held_item", sa.String(50), nullable=True),
|
||||
)
|
||||
|
||||
# Add nature (plain string)
|
||||
op.add_column(
|
||||
"boss_pokemon",
|
||||
sa.Column("nature", sa.String(20), nullable=True),
|
||||
)
|
||||
|
||||
# Add move references (up to 4 moves)
|
||||
for i in range(1, 5):
|
||||
op.add_column(
|
||||
"boss_pokemon",
|
||||
sa.Column(
|
||||
f"move{i}_id", sa.Integer(), sa.ForeignKey("moves.id"), nullable=True
|
||||
),
|
||||
)
|
||||
op.create_index(f"ix_boss_pokemon_move{i}_id", "boss_pokemon", [f"move{i}_id"])
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
for i in range(1, 5):
|
||||
op.drop_index(f"ix_boss_pokemon_move{i}_id", "boss_pokemon")
|
||||
op.drop_column("boss_pokemon", f"move{i}_id")
|
||||
|
||||
op.drop_column("boss_pokemon", "nature")
|
||||
op.drop_column("boss_pokemon", "held_item")
|
||||
op.drop_index("ix_boss_pokemon_ability_id", "boss_pokemon")
|
||||
op.drop_column("boss_pokemon", "ability_id")
|
||||
@@ -0,0 +1,44 @@
|
||||
"""add boss result team
|
||||
|
||||
Revision ID: m4b5c6d7e8f9
|
||||
Revises: l3a4b5c6d7e8
|
||||
Create Date: 2026-03-20 20:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "m4b5c6d7e8f9"
|
||||
down_revision: str | Sequence[str] | None = "l3a4b5c6d7e8"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
"boss_result_team",
|
||||
sa.Column("id", sa.Integer(), primary_key=True),
|
||||
sa.Column(
|
||||
"boss_result_id",
|
||||
sa.Integer(),
|
||||
sa.ForeignKey("boss_results.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
index=True,
|
||||
),
|
||||
sa.Column(
|
||||
"encounter_id",
|
||||
sa.Integer(),
|
||||
sa.ForeignKey("encounters.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
index=True,
|
||||
),
|
||||
sa.Column("level", sa.SmallInteger(), nullable=False),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table("boss_result_team")
|
||||
@@ -0,0 +1,37 @@
|
||||
"""create users table
|
||||
|
||||
Revision ID: n5c6d7e8f9a0
|
||||
Revises: m4b5c6d7e8f9
|
||||
Create Date: 2026-03-20 22:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "n5c6d7e8f9a0"
|
||||
down_revision: str | Sequence[str] | None = "m4b5c6d7e8f9"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
"users",
|
||||
sa.Column("id", sa.UUID(), primary_key=True),
|
||||
sa.Column("email", sa.String(255), nullable=False, unique=True, index=True),
|
||||
sa.Column("display_name", sa.String(100), nullable=True),
|
||||
sa.Column(
|
||||
"created_at",
|
||||
sa.DateTime(timezone=True),
|
||||
nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table("users")
|
||||
@@ -0,0 +1,60 @@
|
||||
"""add owner_id and visibility to runs
|
||||
|
||||
Revision ID: o6d7e8f9a0b1
|
||||
Revises: n5c6d7e8f9a0
|
||||
Create Date: 2026-03-20 22:01:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "o6d7e8f9a0b1"
|
||||
down_revision: str | Sequence[str] | None = "n5c6d7e8f9a0"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Create visibility enum
|
||||
visibility_enum = sa.Enum("public", "private", name="run_visibility")
|
||||
visibility_enum.create(op.get_bind(), checkfirst=True)
|
||||
|
||||
# Add owner_id (nullable FK to users)
|
||||
op.add_column(
|
||||
"nuzlocke_runs",
|
||||
sa.Column("owner_id", sa.UUID(), nullable=True),
|
||||
)
|
||||
op.create_foreign_key(
|
||||
"fk_nuzlocke_runs_owner_id",
|
||||
"nuzlocke_runs",
|
||||
"users",
|
||||
["owner_id"],
|
||||
["id"],
|
||||
ondelete="SET NULL",
|
||||
)
|
||||
op.create_index("ix_nuzlocke_runs_owner_id", "nuzlocke_runs", ["owner_id"])
|
||||
|
||||
# Add visibility column with default 'public'
|
||||
op.add_column(
|
||||
"nuzlocke_runs",
|
||||
sa.Column(
|
||||
"visibility",
|
||||
visibility_enum,
|
||||
nullable=False,
|
||||
server_default="public",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column("nuzlocke_runs", "visibility")
|
||||
op.drop_index("ix_nuzlocke_runs_owner_id", table_name="nuzlocke_runs")
|
||||
op.drop_constraint("fk_nuzlocke_runs_owner_id", "nuzlocke_runs", type_="foreignkey")
|
||||
op.drop_column("nuzlocke_runs", "owner_id")
|
||||
|
||||
# Drop the enum type
|
||||
sa.Enum(name="run_visibility").drop(op.get_bind(), checkfirst=True)
|
||||
Reference in New Issue
Block a user