Add drag-and-drop boss reordering and new feature beans
Adds boss battle reorder API endpoint with two-phase order update to avoid unique constraint violations. Includes frontend mutation hook and API client. Also adds draft beans for progression dividers and conditional boss battle teams features. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ from app.schemas.boss import (
|
||||
BossBattleResponse,
|
||||
BossBattleUpdate,
|
||||
BossPokemonInput,
|
||||
BossReorderRequest,
|
||||
BossResultCreate,
|
||||
BossResultResponse,
|
||||
)
|
||||
@@ -50,6 +51,45 @@ async def list_bosses(
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
@router.put("/games/{game_id}/bosses/reorder", response_model=list[BossBattleResponse])
|
||||
async def reorder_bosses(
|
||||
game_id: int,
|
||||
data: BossReorderRequest,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
vg_id = await _get_version_group_id(session, game_id)
|
||||
|
||||
boss_ids = [item.id for item in data.bosses]
|
||||
result = await session.execute(
|
||||
select(BossBattle).where(
|
||||
BossBattle.id.in_(boss_ids), BossBattle.version_group_id == vg_id
|
||||
)
|
||||
)
|
||||
bosses = {b.id: b for b in result.scalars().all()}
|
||||
|
||||
if len(bosses) != len(boss_ids):
|
||||
raise HTTPException(status_code=400, detail="Some boss IDs not found in this game")
|
||||
|
||||
# Phase 1: set temporary negative orders to avoid unique constraint violations
|
||||
for i, item in enumerate(data.bosses):
|
||||
bosses[item.id].order = -(i + 1)
|
||||
await session.flush()
|
||||
|
||||
# Phase 2: set real orders
|
||||
for item in data.bosses:
|
||||
bosses[item.id].order = item.order
|
||||
await session.commit()
|
||||
|
||||
# Re-fetch with eager loading
|
||||
result = await session.execute(
|
||||
select(BossBattle)
|
||||
.where(BossBattle.version_group_id == vg_id)
|
||||
.options(selectinload(BossBattle.pokemon).selectinload(BossPokemon.pokemon))
|
||||
.order_by(BossBattle.order)
|
||||
)
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
@router.post("/games/{game_id}/bosses", response_model=BossBattleResponse, status_code=201)
|
||||
async def create_boss(
|
||||
game_id: int,
|
||||
|
||||
Reference in New Issue
Block a user