Add admin panel with CRUD endpoints and management UI

Add admin API endpoints for games, routes, pokemon, and route encounters
with full CRUD operations including bulk import. Build admin frontend
with game/route/pokemon management pages, navigation, and data tables.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-05 18:36:19 +01:00
parent a911259ef5
commit 55e6650e0e
28 changed files with 2140 additions and 10 deletions

View File

@@ -4,25 +4,51 @@ from app.schemas.encounter import (
EncounterResponse,
EncounterUpdate,
)
from app.schemas.game import GameDetailResponse, GameResponse, RouteResponse
from app.schemas.game import (
GameCreate,
GameDetailResponse,
GameResponse,
GameUpdate,
RouteCreate,
RouteReorderRequest,
RouteResponse,
RouteUpdate,
)
from app.schemas.pokemon import (
BulkImportItem,
BulkImportResult,
PokemonCreate,
PokemonResponse,
PokemonUpdate,
RouteEncounterCreate,
RouteEncounterDetailResponse,
RouteEncounterResponse,
RouteEncounterUpdate,
)
from app.schemas.run import RunCreate, RunDetailResponse, RunResponse, RunUpdate
__all__ = [
"BulkImportItem",
"BulkImportResult",
"EncounterCreate",
"EncounterDetailResponse",
"EncounterResponse",
"EncounterUpdate",
"GameCreate",
"GameDetailResponse",
"GameResponse",
"RouteResponse",
"GameUpdate",
"PokemonCreate",
"PokemonResponse",
"PokemonUpdate",
"RouteCreate",
"RouteEncounterCreate",
"RouteEncounterDetailResponse",
"RouteEncounterResponse",
"RouteEncounterUpdate",
"RouteReorderRequest",
"RouteResponse",
"RouteUpdate",
"RunCreate",
"RunDetailResponse",
"RunResponse",

View File

@@ -20,3 +20,43 @@ class GameResponse(CamelModel):
class GameDetailResponse(GameResponse):
routes: list[RouteResponse] = []
# --- Admin schemas ---
class GameCreate(CamelModel):
name: str
slug: str
generation: int
region: str
box_art_url: str | None = None
release_year: int | None = None
class GameUpdate(CamelModel):
name: str | None = None
slug: str | None = None
generation: int | None = None
region: str | None = None
box_art_url: str | None = None
release_year: int | None = None
class RouteCreate(CamelModel):
name: str
order: int
class RouteUpdate(CamelModel):
name: str | None = None
order: int | None = None
class RouteReorderItem(CamelModel):
id: int
order: int
class RouteReorderRequest(CamelModel):
routes: list[RouteReorderItem]

View File

@@ -1,3 +1,5 @@
from pydantic import BaseModel
from app.schemas.base import CamelModel
@@ -21,3 +23,48 @@ class RouteEncounterResponse(CamelModel):
class RouteEncounterDetailResponse(RouteEncounterResponse):
pokemon: PokemonResponse
# --- Admin schemas ---
class PokemonCreate(CamelModel):
national_dex: int
name: str
types: list[str]
sprite_url: str | None = None
class PokemonUpdate(CamelModel):
national_dex: int | None = None
name: str | None = None
types: list[str] | None = None
sprite_url: str | None = None
class RouteEncounterCreate(CamelModel):
pokemon_id: int
encounter_method: str
encounter_rate: int
min_level: int
max_level: int
class RouteEncounterUpdate(CamelModel):
encounter_method: str | None = None
encounter_rate: int | None = None
min_level: int | None = None
max_level: int | None = None
class BulkImportItem(BaseModel):
national_dex: int
name: str
types: list[str]
sprite_url: str | None = None
class BulkImportResult(CamelModel):
created: int
updated: int
errors: list[str]