"""Routes G7 — Jumelage parrain/filleul (confidentiel).""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc from app.core.database import get_db from app.core.security import require_executif from app.models.jumelage import Jumelage from app.models.membre import Membre from app.schemas.phase8 import JumelageCreate, JumelageOut, JumelageUpdate router = APIRouter(prefix="/jumelages", tags=["G7 — Parrainage"]) async def _to_out(j: Jumelage, db: AsyncSession) -> JumelageOut: parrain = await db.get(Membre, j.parrain_id) filleul = await db.get(Membre, j.filleul_id) cree = await db.get(Membre, j.cree_par) if j.cree_par else None return JumelageOut( id=j.id, parrain_prenom=parrain.prenom if parrain else "?", filleul_prenom=filleul.prenom if filleul else "?", date_jumelage=j.date_jumelage, statut=j.statut, note=j.note, cree_par_prenom=cree.prenom if cree else None, ) @router.post("/", response_model=JumelageOut) async def creer_jumelage( req: JumelageCreate, membre=Depends(require_executif), db: AsyncSession = Depends(get_db), ): """G7 — Jumeler un parrain et un filleul.""" if req.parrain_id == req.filleul_id: raise HTTPException(status_code=400, detail="Le parrain et le filleul doivent être différents") parrain = await db.get(Membre, req.parrain_id) filleul = await db.get(Membre, req.filleul_id) if not parrain or not parrain.actif: raise HTTPException(status_code=404, detail="Parrain introuvable ou inactif") if not filleul or not filleul.actif: raise HTTPException(status_code=404, detail="Filleul introuvable ou inactif") jumelage = Jumelage( groupe_id=membre.groupe_id, parrain_id=req.parrain_id, filleul_id=req.filleul_id, date_jumelage=req.date_jumelage, note=req.note, cree_par=membre.id, ) db.add(jumelage) await db.flush() return await _to_out(jumelage, db) @router.get("/", response_model=list[JumelageOut]) async def liste_jumelages( statut: str | None = None, membre=Depends(require_executif), db: AsyncSession = Depends(get_db), ): """Liste des jumelages (confidentiel — exécutif seulement).""" query = select(Jumelage).where(Jumelage.groupe_id == membre.groupe_id) if statut: query = query.where(Jumelage.statut == statut) query = query.order_by(desc(Jumelage.date_jumelage)) result = await db.execute(query) jumelages = result.scalars().all() return [await _to_out(j, db) for j in jumelages] @router.patch("/{jumelage_id}", response_model=JumelageOut) async def modifier_jumelage( jumelage_id: str, req: JumelageUpdate, membre=Depends(require_executif), db: AsyncSession = Depends(get_db), ): """Modifier ou terminer un jumelage.""" result = await db.execute( select(Jumelage).where(Jumelage.id == jumelage_id, Jumelage.groupe_id == membre.groupe_id) ) jumelage = result.scalar_one_or_none() if not jumelage: raise HTTPException(status_code=404, detail="Jumelage introuvable") if req.statut and req.statut in ("actif", "termine"): jumelage.statut = req.statut if req.note is not None: jumelage.note = req.note await db.flush() return await _to_out(jumelage, db)