Initial commit

This commit is contained in:
2026-03-31 13:10:46 +02:00
commit f60d9628e0
52 changed files with 3383 additions and 0 deletions

View File

@@ -0,0 +1,146 @@
"""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()
]