Daedalus and Talos integration test
This commit is contained in:
151
backend/src/app/api/journal_entries.py
Normal file
151
backend/src/app/api/journal_entries.py
Normal file
@@ -0,0 +1,151 @@
|
||||
from datetime import UTC, datetime
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Response
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.database import get_session
|
||||
from app.models.boss_result import BossResult
|
||||
from app.models.journal_entry import JournalEntry
|
||||
from app.models.nuzlocke_run import NuzlockeRun
|
||||
from app.schemas.journal_entry import (
|
||||
JournalEntryCreate,
|
||||
JournalEntryResponse,
|
||||
JournalEntryUpdate,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/{run_id}/journal", response_model=list[JournalEntryResponse])
|
||||
async def list_journal_entries(
|
||||
run_id: int,
|
||||
boss_result_id: int | None = None,
|
||||
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")
|
||||
|
||||
query = select(JournalEntry).where(JournalEntry.run_id == run_id)
|
||||
|
||||
if boss_result_id is not None:
|
||||
query = query.where(JournalEntry.boss_result_id == boss_result_id)
|
||||
|
||||
query = query.order_by(JournalEntry.created_at.desc())
|
||||
|
||||
result = await session.execute(query)
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
@router.post("/{run_id}/journal", response_model=JournalEntryResponse, status_code=201)
|
||||
async def create_journal_entry(
|
||||
run_id: int,
|
||||
data: JournalEntryCreate,
|
||||
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 boss_result_id if provided
|
||||
if data.boss_result_id is not None:
|
||||
boss_result = await session.get(BossResult, data.boss_result_id)
|
||||
if boss_result is None:
|
||||
raise HTTPException(status_code=404, detail="Boss result not found")
|
||||
if boss_result.run_id != run_id:
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Boss result does not belong to this run"
|
||||
)
|
||||
|
||||
entry = JournalEntry(
|
||||
run_id=run_id,
|
||||
boss_result_id=data.boss_result_id,
|
||||
title=data.title,
|
||||
body=data.body,
|
||||
)
|
||||
session.add(entry)
|
||||
await session.commit()
|
||||
await session.refresh(entry)
|
||||
return entry
|
||||
|
||||
|
||||
@router.get("/{run_id}/journal/{entry_id}", response_model=JournalEntryResponse)
|
||||
async def get_journal_entry(
|
||||
run_id: int,
|
||||
entry_id: UUID,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
result = await session.execute(
|
||||
select(JournalEntry).where(
|
||||
JournalEntry.id == entry_id,
|
||||
JournalEntry.run_id == run_id,
|
||||
)
|
||||
)
|
||||
entry = result.scalar_one_or_none()
|
||||
if entry is None:
|
||||
raise HTTPException(status_code=404, detail="Journal entry not found")
|
||||
return entry
|
||||
|
||||
|
||||
@router.put("/{run_id}/journal/{entry_id}", response_model=JournalEntryResponse)
|
||||
async def update_journal_entry(
|
||||
run_id: int,
|
||||
entry_id: UUID,
|
||||
data: JournalEntryUpdate,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
result = await session.execute(
|
||||
select(JournalEntry).where(
|
||||
JournalEntry.id == entry_id,
|
||||
JournalEntry.run_id == run_id,
|
||||
)
|
||||
)
|
||||
entry = result.scalar_one_or_none()
|
||||
if entry is None:
|
||||
raise HTTPException(status_code=404, detail="Journal entry not found")
|
||||
|
||||
update_data = data.model_dump(exclude_unset=True)
|
||||
|
||||
# Validate boss_result_id if provided
|
||||
if "boss_result_id" in update_data and update_data["boss_result_id"] is not None:
|
||||
boss_result = await session.get(BossResult, update_data["boss_result_id"])
|
||||
if boss_result is None:
|
||||
raise HTTPException(status_code=404, detail="Boss result not found")
|
||||
if boss_result.run_id != run_id:
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Boss result does not belong to this run"
|
||||
)
|
||||
|
||||
for field, value in update_data.items():
|
||||
setattr(entry, field, value)
|
||||
|
||||
entry.updated_at = datetime.now(UTC)
|
||||
|
||||
await session.commit()
|
||||
await session.refresh(entry)
|
||||
return entry
|
||||
|
||||
|
||||
@router.delete("/{run_id}/journal/{entry_id}", status_code=204)
|
||||
async def delete_journal_entry(
|
||||
run_id: int,
|
||||
entry_id: UUID,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
result = await session.execute(
|
||||
select(JournalEntry).where(
|
||||
JournalEntry.id == entry_id,
|
||||
JournalEntry.run_id == run_id,
|
||||
)
|
||||
)
|
||||
entry = result.scalar_one_or_none()
|
||||
if entry is None:
|
||||
raise HTTPException(status_code=404, detail="Journal entry not found")
|
||||
|
||||
await session.delete(entry)
|
||||
await session.commit()
|
||||
return Response(status_code=204)
|
||||
@@ -8,6 +8,7 @@ from app.api import (
|
||||
games,
|
||||
genlockes,
|
||||
health,
|
||||
journal_entries,
|
||||
pokemon,
|
||||
runs,
|
||||
stats,
|
||||
@@ -19,6 +20,7 @@ api_router.include_router(games.router, prefix="/games", tags=["games"])
|
||||
api_router.include_router(pokemon.router, tags=["pokemon"])
|
||||
api_router.include_router(evolutions.router, tags=["evolutions"])
|
||||
api_router.include_router(runs.router, prefix="/runs", tags=["runs"])
|
||||
api_router.include_router(journal_entries.router, prefix="/runs", tags=["journal"])
|
||||
api_router.include_router(genlockes.router, prefix="/genlockes", tags=["genlockes"])
|
||||
api_router.include_router(encounters.router, tags=["encounters"])
|
||||
api_router.include_router(stats.router, prefix="/stats", tags=["stats"])
|
||||
|
||||
Reference in New Issue
Block a user