"""Routes d'administration reservees au sysadmin.""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import func, select from pydantic import BaseModel from app.core.database import get_db from app.core.security import create_token, get_current_membre, is_sysadmin, verify_pin from app.services.admin_database import ( creer_groupe, initialiser_demo, modifier_groupe, reinitialiser_demo, remettre_a_zero, supprimer_groupe, ) from app.models.groupe import Groupe from app.models.membre import Membre from app.models.reunion import Reunion from app.models.historique_modification import HistoriqueModification from app.schemas.schemas import MembrePublic, TokenResponse router = APIRouter(prefix="/admin", tags=["Administration"]) class SysadminLoginRequest(BaseModel): pin: str class GroupeAdminRequest(BaseModel): nom: str district: str = "87-16" region: str = "87" adresse_local: str | None = None jour_reunion: str | None = "mardi" heure_reunion: str | None = "19:30" assemblee_affaires_ordre: str = "premiere" format_reunion: str | None = "Discussion ouverte" lien_aa87: str = "https://aa87.org" async def require_sysadmin(membre=Depends(get_current_membre)): if not is_sysadmin(membre): raise HTTPException(status_code=403, detail="Réservé au sysadmin") return membre @router.post("/sysadmin-login", response_model=TokenResponse) async def sysadmin_login(req: SysadminLoginRequest, db: AsyncSession = Depends(get_db)): result = await db.execute(select(Membre).where(Membre.courriel == "sysadmin", Membre.actif == True)) for membre in result.scalars().all(): if verify_pin(req.pin, membre.pin_hash): token = create_token(str(membre.id), str(membre.groupe_id), expire_jours=1) return TokenResponse(access_token=token, membre=MembrePublic.model_validate(membre)) raise HTTPException(status_code=401, detail="PIN Sysadmin invalide") @router.post("/reset") async def reset_database( _sysadmin=Depends(require_sysadmin), db: AsyncSession = Depends(get_db), ): return await remettre_a_zero(db) @router.post("/demo") async def demo_database( _sysadmin=Depends(require_sysadmin), db: AsyncSession = Depends(get_db), ): return await initialiser_demo(db) @router.post("/demo/reset") async def reset_demo_database( _sysadmin=Depends(require_sysadmin), db: AsyncSession = Depends(get_db), ): return await reinitialiser_demo(db) @router.get("/groupes") async def liste_groupes_admin( _sysadmin=Depends(require_sysadmin), db: AsyncSession = Depends(get_db), ): await initialiser_demo(db) groupes = (await db.execute(select(Groupe).order_by(Groupe.nom))).scalars().all() out = [] for groupe in groupes: nb_membres = (await db.execute( select(func.count()).select_from(Membre).where(Membre.groupe_id == groupe.id) )).scalar_one() nb_reunions = (await db.execute( select(func.count()).select_from(Reunion).where(Reunion.groupe_id == groupe.id) )).scalar_one() nb_traces = (await db.execute( select(func.count()).select_from(HistoriqueModification).where(HistoriqueModification.groupe_id == groupe.id) )).scalar_one() out.append({ "id": str(groupe.id), "nom": groupe.nom, "district": groupe.district, "region": groupe.region, "adresse_local": groupe.adresse_local, "jour_reunion": groupe.jour_reunion, "heure_reunion": groupe.heure_reunion.strftime("%H:%M") if groupe.heure_reunion else None, "assemblee_affaires_ordre": groupe.assemblee_affaires_ordre, "format_reunion": groupe.format_reunion, "lien_aa87": groupe.lien_aa87, "cree_le": groupe.cree_le, "membres": nb_membres, "reunions": nb_reunions, "traces": nb_traces, "demo": groupe.nom == "Groupe Résilience", "protege": groupe.nom == "Groupe Résilience", }) return out @router.post("/groupes") async def creer_groupe_admin( req: GroupeAdminRequest, _sysadmin=Depends(require_sysadmin), db: AsyncSession = Depends(get_db), ): try: groupe = await creer_groupe(db, req.model_dump()) return {"message": "Groupe créé", "id": str(groupe.id)} except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) @router.patch("/groupes/{groupe_id}") async def modifier_groupe_admin( groupe_id: str, req: GroupeAdminRequest, _sysadmin=Depends(require_sysadmin), db: AsyncSession = Depends(get_db), ): try: groupe = await modifier_groupe(db, groupe_id, req.model_dump()) return {"message": "Groupe modifié", "id": str(groupe.id)} except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) @router.delete("/groupes/{groupe_id}") async def supprimer_groupe_admin( groupe_id: str, _sysadmin=Depends(require_sysadmin), db: AsyncSession = Depends(get_db), ): try: return await supprimer_groupe(db, groupe_id) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc))