"""Routes API — Base de données HSBG (héros, serviteurs, sorts).""" from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, delete from backend.database.db import get_db from backend.database.models import Hero, Minion, Spell router = APIRouter() # ─── Héros ──────────────────────────────────────────────────────────────────── @router.get("/heroes") async def list_heroes(search: str | None = None, db: AsyncSession = Depends(get_db)): q = select(Hero).where(Hero.is_active == True) if search: q = q.where(Hero.name.ilike(f"%{search}%")) r = await db.execute(q) return [ {"id": h.id, "card_id": h.card_id, "name": h.name, "hero_power": h.hero_power, "description": h.description, "strengths": h.strengths, "weaknesses": h.weaknesses, "synergies": h.synergies, "tier_rating": h.tier_rating, "patch_added": h.patch_added} for h in r.scalars().all() ] class HeroIn(BaseModel): card_id: str name: str hero_power: str = "" description: str = "" strengths: list = [] weaknesses: list = [] synergies: list = [] tier_rating: float = 5.0 patch_added: str = "" @router.post("/heroes", status_code=201) async def create_hero(data: HeroIn, db: AsyncSession = Depends(get_db)): hero = Hero(**data.model_dump()) db.add(hero) await db.flush() return {"id": hero.id, "name": hero.name} @router.put("/heroes/{hero_id}") async def update_hero(hero_id: int, data: HeroIn, db: AsyncSession = Depends(get_db)): hero = await db.get(Hero, hero_id) if not hero: raise HTTPException(404, "Héros introuvable") for k, v in data.model_dump().items(): setattr(hero, k, v) return {"id": hero.id, "name": hero.name} @router.delete("/heroes/{hero_id}") async def delete_hero(hero_id: int, db: AsyncSession = Depends(get_db)): hero = await db.get(Hero, hero_id) if not hero: raise HTTPException(404, "Héros introuvable") hero.is_active = False return {"status": "deactivated"} # ─── Serviteurs ─────────────────────────────────────────────────────────────── @router.get("/minions") async def list_minions( tier: int | None = None, race: str | None = None, search: str | None = None, db: AsyncSession = Depends(get_db), ): q = select(Minion).where(Minion.is_active == True) if tier: q = q.where(Minion.tier == str(tier)) if search: q = q.where(Minion.name.ilike(f"%{search}%")) r = await db.execute(q) minions = r.scalars().all() if race: minions = [m for m in minions if race in (m.race or [])] return [ {"id": m.id, "card_id": m.card_id, "name": m.name, "tier": m.tier, "race": m.race, "attack": m.attack, "health": m.health, "has_divine": m.has_divine, "has_taunt": m.has_taunt, "has_windfury": m.has_windfury, "has_poisonous": m.has_poisonous, "has_reborn": m.has_reborn, "battlecry": m.battlecry, "deathrattle": m.deathrattle, "passive": m.passive, "synergies": m.synergies, "keywords": m.keywords, "patch_added": m.patch_added} for m in minions ] class MinionIn(BaseModel): card_id: str name: str tier: str = "1" race: list = [] attack: int = 0 health: int = 0 tavern_cost: int = 3 has_divine: bool = False has_taunt: bool = False has_windfury: bool = False has_poisonous: bool = False has_reborn: bool = False battlecry: str = "" deathrattle: str = "" on_attack: str = "" passive: str = "" synergies: list = [] keywords: list = [] patch_added: str = "" @router.post("/minions", status_code=201) async def create_minion(data: MinionIn, db: AsyncSession = Depends(get_db)): minion = Minion(**data.model_dump()) db.add(minion) await db.flush() return {"id": minion.id, "name": minion.name} @router.put("/minions/{minion_id}") async def update_minion(minion_id: int, data: MinionIn, db: AsyncSession = Depends(get_db)): minion = await db.get(Minion, minion_id) if not minion: raise HTTPException(404, "Serviteur introuvable") for k, v in data.model_dump().items(): setattr(minion, k, v) return {"id": minion.id, "name": minion.name} # ─── Sorts ──────────────────────────────────────────────────────────────────── @router.get("/spells") async def list_spells(db: AsyncSession = Depends(get_db)): r = await db.execute(select(Spell).where(Spell.is_active == True)) return [ {"id": s.id, "card_id": s.card_id, "name": s.name, "tier": s.tier, "cost": s.cost, "effect": s.effect, "target": s.target} for s in r.scalars().all() ]