Add optional specialty type field to boss battles
Gym leaders, Elite Four, and champions can now have a Pokemon type specialty (e.g. Rock, Water). Shown as a type image badge on boss cards in the run view, and editable via dropdown in the admin form. Includes migration, export, and seed pipeline support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
"""add specialty_type to boss battles
|
||||
|
||||
Revision ID: a6b7c8d9e0f1
|
||||
Revises: f5a6b7c8d9e0
|
||||
Create Date: 2026-02-08 21:00:00.000000
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'a6b7c8d9e0f1'
|
||||
down_revision: Union[str, Sequence[str], None] = 'f5a6b7c8d9e0'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column('boss_battles', sa.Column('specialty_type', sa.String(20), nullable=True))
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column('boss_battles', 'specialty_type')
|
||||
@@ -138,6 +138,7 @@ async def export_game_bosses(
|
||||
{
|
||||
"name": b.name,
|
||||
"boss_type": b.boss_type,
|
||||
"specialty_type": b.specialty_type,
|
||||
"badge_name": b.badge_name,
|
||||
"badge_image_url": b.badge_image_url,
|
||||
"level_cap": b.level_cap,
|
||||
|
||||
@@ -16,6 +16,7 @@ class BossBattle(Base):
|
||||
)
|
||||
name: Mapped[str] = mapped_column(String(100))
|
||||
boss_type: Mapped[str] = mapped_column(String(20)) # gym_leader, elite_four, champion, rival, evil_team, other
|
||||
specialty_type: Mapped[str | None] = mapped_column(String(20), default=None) # pokemon type specialty (e.g. rock, water)
|
||||
badge_name: Mapped[str | None] = mapped_column(String(100))
|
||||
badge_image_url: Mapped[str | None] = mapped_column(String(500))
|
||||
level_cap: Mapped[int] = mapped_column(SmallInteger)
|
||||
|
||||
@@ -17,6 +17,7 @@ class BossBattleResponse(CamelModel):
|
||||
version_group_id: int
|
||||
name: str
|
||||
boss_type: str
|
||||
specialty_type: str | None
|
||||
badge_name: str | None
|
||||
badge_image_url: str | None
|
||||
level_cap: int
|
||||
@@ -43,6 +44,7 @@ class BossResultResponse(CamelModel):
|
||||
class BossBattleCreate(CamelModel):
|
||||
name: str
|
||||
boss_type: str
|
||||
specialty_type: str | None = None
|
||||
badge_name: str | None = None
|
||||
badge_image_url: str | None = None
|
||||
level_cap: int
|
||||
@@ -56,6 +58,7 @@ class BossBattleCreate(CamelModel):
|
||||
class BossBattleUpdate(CamelModel):
|
||||
name: str | None = None
|
||||
boss_type: str | None = None
|
||||
specialty_type: str | None = None
|
||||
badge_name: str | None = None
|
||||
badge_image_url: str | None = None
|
||||
level_cap: int | None = None
|
||||
|
||||
@@ -220,6 +220,7 @@ async def upsert_bosses(
|
||||
version_group_id=version_group_id,
|
||||
name=boss["name"],
|
||||
boss_type=boss["boss_type"],
|
||||
specialty_type=boss.get("specialty_type"),
|
||||
badge_name=boss.get("badge_name"),
|
||||
badge_image_url=boss.get("badge_image_url"),
|
||||
level_cap=boss["level_cap"],
|
||||
@@ -232,6 +233,7 @@ async def upsert_bosses(
|
||||
set_={
|
||||
"name": boss["name"],
|
||||
"boss_type": boss["boss_type"],
|
||||
"specialty_type": boss.get("specialty_type"),
|
||||
"badge_name": boss.get("badge_name"),
|
||||
"badge_image_url": boss.get("badge_image_url"),
|
||||
"level_cap": boss["level_cap"],
|
||||
|
||||
@@ -429,6 +429,7 @@ async def _export_bosses(session: AsyncSession, vg_data: dict):
|
||||
{
|
||||
"name": b.name,
|
||||
"boss_type": b.boss_type,
|
||||
"specialty_type": b.specialty_type,
|
||||
"badge_name": b.badge_name,
|
||||
"badge_image_url": b.badge_image_url,
|
||||
"level_cap": b.level_cap,
|
||||
|
||||
Reference in New Issue
Block a user