groupe-meditation/backend/app/routers/jumelages.py

100 lines
3.4 KiB
Python
Raw Normal View History

2026-03-04 14:01:00 -05:00
"""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)