Enforce Dupes Clause and Shiny Clause rules
Dupes Clause greys out Pokemon in the encounter modal whose evolution family has already been caught, preventing duplicate selections. Shiny Clause adds a dedicated Shiny Box and lets shiny catches bypass the one-per-route lock via a new is_shiny column on encounters and a /pokemon/families endpoint that computes evolution family groups. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ from app.schemas.pokemon import (
|
||||
BulkImportItem,
|
||||
BulkImportResult,
|
||||
EvolutionResponse,
|
||||
FamiliesResponse,
|
||||
PaginatedPokemonResponse,
|
||||
PokemonCreate,
|
||||
PokemonResponse,
|
||||
@@ -109,6 +110,44 @@ async def create_pokemon(
|
||||
return pokemon
|
||||
|
||||
|
||||
@router.get("/pokemon/families", response_model=FamiliesResponse)
|
||||
async def get_pokemon_families(
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
"""Return evolution families as connected components of Pokemon IDs."""
|
||||
from collections import deque
|
||||
|
||||
result = await session.execute(select(Evolution))
|
||||
evolutions = result.scalars().all()
|
||||
|
||||
# Build undirected adjacency list
|
||||
adj: dict[int, set[int]] = {}
|
||||
for evo in evolutions:
|
||||
adj.setdefault(evo.from_pokemon_id, set()).add(evo.to_pokemon_id)
|
||||
adj.setdefault(evo.to_pokemon_id, set()).add(evo.from_pokemon_id)
|
||||
|
||||
# BFS to find connected components
|
||||
visited: set[int] = set()
|
||||
families: list[list[int]] = []
|
||||
for node in adj:
|
||||
if node in visited:
|
||||
continue
|
||||
component: list[int] = []
|
||||
queue = deque([node])
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
if current in visited:
|
||||
continue
|
||||
visited.add(current)
|
||||
component.append(current)
|
||||
for neighbor in adj.get(current, set()):
|
||||
if neighbor not in visited:
|
||||
queue.append(neighbor)
|
||||
families.append(sorted(component))
|
||||
|
||||
return FamiliesResponse(families=families)
|
||||
|
||||
|
||||
@router.get("/pokemon/{pokemon_id}", response_model=PokemonResponse)
|
||||
async def get_pokemon(
|
||||
pokemon_id: int, session: AsyncSession = Depends(get_session)
|
||||
|
||||
Reference in New Issue
Block a user