Fix run deletion crash and transfer modal initialization error

Run deletion now properly cleans up boss_results, genlocke_transfers,
and genlocke_leg references before deleting the run. Also fix
showTransferModal being referenced before initialization in
RunEncounters by moving its useState declaration above useLegSurvivors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Julian Tabel
2026-02-09 11:28:22 +01:00
parent c5910ec75c
commit e1dac10d27
3 changed files with 35 additions and 4 deletions

View File

@@ -1,11 +1,11 @@
--- ---
# nuzlocke-tracker-p74f # nuzlocke-tracker-p74f
title: Genlocke transfer UI title: Genlocke transfer UI
status: in-progress status: completed
type: feature type: feature
priority: normal priority: normal
created_at: 2026-02-09T07:42:33Z created_at: 2026-02-09T07:42:33Z
updated_at: 2026-02-09T10:14:34Z updated_at: 2026-02-09T10:20:53Z
parent: nuzlocke-tracker-25mh parent: nuzlocke-tracker-25mh
blocking: blocking:
- nuzlocke-tracker-lsc2 - nuzlocke-tracker-lsc2

View File

@@ -6,9 +6,11 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload, selectinload from sqlalchemy.orm import joinedload, selectinload
from app.core.database import get_session from app.core.database import get_session
from app.models.boss_result import BossResult
from app.models.encounter import Encounter from app.models.encounter import Encounter
from app.models.game import Game from app.models.game import Game
from app.models.genlocke import Genlocke, GenlockeLeg from app.models.genlocke import Genlocke, GenlockeLeg
from app.models.genlocke_transfer import GenlockeTransfer
from app.models.nuzlocke_run import NuzlockeRun from app.models.nuzlocke_run import NuzlockeRun
from app.schemas.run import RunCreate, RunDetailResponse, RunGenlockeContext, RunResponse, RunUpdate from app.schemas.run import RunCreate, RunDetailResponse, RunGenlockeContext, RunResponse, RunUpdate
@@ -198,13 +200,42 @@ async def delete_run(
if run is None: if run is None:
raise HTTPException(status_code=404, detail="Run not found") raise HTTPException(status_code=404, detail="Run not found")
# Delete associated encounters first # Delete associated boss results first
boss_results = await session.execute(
select(BossResult).where(BossResult.run_id == run_id)
)
for br in boss_results.scalars():
await session.delete(br)
# Delete genlocke transfers referencing this run's encounters
encounter_ids_result = await session.execute(
select(Encounter.id).where(Encounter.run_id == run_id)
)
encounter_ids = [row[0] for row in encounter_ids_result]
if encounter_ids:
transfers = await session.execute(
select(GenlockeTransfer).where(
GenlockeTransfer.source_encounter_id.in_(encounter_ids)
| GenlockeTransfer.target_encounter_id.in_(encounter_ids)
)
)
for t in transfers.scalars():
await session.delete(t)
# Delete associated encounters
encounters = await session.execute( encounters = await session.execute(
select(Encounter).where(Encounter.run_id == run_id) select(Encounter).where(Encounter.run_id == run_id)
) )
for enc in encounters.scalars(): for enc in encounters.scalars():
await session.delete(enc) await session.delete(enc)
# Unlink from any genlocke leg
leg_result = await session.execute(
select(GenlockeLeg).where(GenlockeLeg.run_id == run_id)
)
for leg in leg_result.scalars():
leg.run_id = None
await session.delete(run) await session.delete(run)
await session.commit() await session.commit()
return Response(status_code=204) return Response(status_code=204)

View File

@@ -396,6 +396,7 @@ export function RunEncounters() {
const runIdNum = Number(runId) const runIdNum = Number(runId)
const { data: run, isLoading, error } = useRun(runIdNum) const { data: run, isLoading, error } = useRun(runIdNum)
const advanceLeg = useAdvanceLeg() const advanceLeg = useAdvanceLeg()
const [showTransferModal, setShowTransferModal] = useState(false)
const { data: survivors } = useLegSurvivors( const { data: survivors } = useLegSurvivors(
run?.genlocke?.genlockeId ?? 0, run?.genlocke?.genlockeId ?? 0,
run?.genlocke?.legOrder ?? 0, run?.genlocke?.legOrder ?? 0,
@@ -423,7 +424,6 @@ export function RunEncounters() {
const [showHofModal, setShowHofModal] = useState(false) const [showHofModal, setShowHofModal] = useState(false)
const [showShinyModal, setShowShinyModal] = useState(false) const [showShinyModal, setShowShinyModal] = useState(false)
const [showEggModal, setShowEggModal] = useState(false) const [showEggModal, setShowEggModal] = useState(false)
const [showTransferModal, setShowTransferModal] = useState(false)
const [expandedBosses, setExpandedBosses] = useState<Set<number>>(new Set()) const [expandedBosses, setExpandedBosses] = useState<Set<number>>(new Set())
const [showTeam, setShowTeam] = useState(true) const [showTeam, setShowTeam] = useState(true)
const [filter, setFilter] = useState<'all' | RouteStatus>('all') const [filter, setFilter] = useState<'all' | RouteStatus>('all')