Add REST API endpoints for games, runs, and encounters
Implement 13 endpoints: read-only reference data (games, routes, pokemon), run CRUD with cascading deletes, and encounter management. Uses Pydantic v2 with camelCase alias generation to match frontend types, and nested response schemas for detail views. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
82
backend/src/app/api/encounters.py
Normal file
82
backend/src/app/api/encounters.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Response
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.database import get_session
|
||||
from app.models.encounter import Encounter
|
||||
from app.models.nuzlocke_run import NuzlockeRun
|
||||
from app.models.pokemon import Pokemon
|
||||
from app.models.route import Route
|
||||
from app.schemas.encounter import EncounterCreate, EncounterResponse, EncounterUpdate
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post(
|
||||
"/runs/{run_id}/encounters",
|
||||
response_model=EncounterResponse,
|
||||
status_code=201,
|
||||
)
|
||||
async def create_encounter(
|
||||
run_id: int,
|
||||
data: EncounterCreate,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
# Validate run exists
|
||||
run = await session.get(NuzlockeRun, run_id)
|
||||
if run is None:
|
||||
raise HTTPException(status_code=404, detail="Run not found")
|
||||
|
||||
# Validate route exists
|
||||
route = await session.get(Route, data.route_id)
|
||||
if route is None:
|
||||
raise HTTPException(status_code=404, detail="Route not found")
|
||||
|
||||
# Validate pokemon exists
|
||||
pokemon = await session.get(Pokemon, data.pokemon_id)
|
||||
if pokemon is None:
|
||||
raise HTTPException(status_code=404, detail="Pokemon not found")
|
||||
|
||||
encounter = Encounter(
|
||||
run_id=run_id,
|
||||
route_id=data.route_id,
|
||||
pokemon_id=data.pokemon_id,
|
||||
nickname=data.nickname,
|
||||
status=data.status,
|
||||
catch_level=data.catch_level,
|
||||
)
|
||||
session.add(encounter)
|
||||
await session.commit()
|
||||
await session.refresh(encounter)
|
||||
return encounter
|
||||
|
||||
|
||||
@router.patch("/encounters/{encounter_id}", response_model=EncounterResponse)
|
||||
async def update_encounter(
|
||||
encounter_id: int,
|
||||
data: EncounterUpdate,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
encounter = await session.get(Encounter, encounter_id)
|
||||
if encounter is None:
|
||||
raise HTTPException(status_code=404, detail="Encounter not found")
|
||||
|
||||
update_data = data.model_dump(exclude_unset=True)
|
||||
for field, value in update_data.items():
|
||||
setattr(encounter, field, value)
|
||||
|
||||
await session.commit()
|
||||
await session.refresh(encounter)
|
||||
return encounter
|
||||
|
||||
|
||||
@router.delete("/encounters/{encounter_id}", status_code=204)
|
||||
async def delete_encounter(
|
||||
encounter_id: int, session: AsyncSession = Depends(get_session)
|
||||
):
|
||||
encounter = await session.get(Encounter, encounter_id)
|
||||
if encounter is None:
|
||||
raise HTTPException(status_code=404, detail="Encounter not found")
|
||||
|
||||
await session.delete(encounter)
|
||||
await session.commit()
|
||||
return Response(status_code=204)
|
||||
Reference in New Issue
Block a user