import type { Response } from "express"; import { prisma } from "../index"; import type { AppRequest } from "../types/context"; import { addGroupProgramSchema, createGroupSchema, inviteMemberSchema } from "../validators/group.validators"; // Créer un groupe export async function create(req: AppRequest, res: Response): Promise { const parsed = createGroupSchema.safeParse(req.body); if (!parsed.success) { res.status(400).json({ message: parsed.error.issues[0].message }); return; } const group = await prisma.group.create({ data: { ...parsed.data, members: { create: { userId: req.user!.id, role: "ADMIN" }, }, }, include: { members: { include: { user: { select: { id: true, username: true, avatar: true } } } } }, }); res.status(201).json(group); } // Mes groupes export async function getMyGroups(req: AppRequest, res: Response): Promise { const groups = await prisma.group.findMany({ where: { members: { some: { userId: req.user!.id } } }, include: { members: { include: { user: { select: { id: true, username: true, avatar: true } } } }, programs: { include: { program: true } }, }, }); res.json(groups); } // Détail d'un groupe export async function getOne(req: AppRequest, res: Response): Promise { const id = req.params.id as string; const group = await prisma.group.findFirst({ where: { id, OR: [{ isPublic: true }, { members: { some: { userId: req.user!.id } } }], }, include: { members: { include: { user: { select: { id: true, username: true, avatar: true } } } }, programs: { include: { program: { include: { exercises: { include: { exercise: true } } } } } }, }, }); if (!group) { res.status(404).json({ message: "Groupe introuvable." }); return; } res.json(group); } // Inviter un membre export async function inviteMember(req: AppRequest, res: Response): Promise { const groupId = req.params.id as string; const parsed = inviteMemberSchema.safeParse(req.body); if (!parsed.success) { res.status(400).json({ message: parsed.error.issues[0].message }); return; } // Vérifier que l'appelant est ADMIN ou COACH du groupe const membership = await prisma.groupMember.findUnique({ where: { groupId_userId: { groupId, userId: req.user!.id } }, }); if (!membership || membership.role === "MEMBER") { res.status(403).json({ message: "Accès refusé." }); return; } const already = await prisma.groupMember.findUnique({ where: { groupId_userId: { groupId, userId: parsed.data.userId } }, }); if (already) { res.status(409).json({ message: "Déjà membre du groupe." }); return; } const member = await prisma.groupMember.create({ data: { groupId, userId: parsed.data.userId, role: "MEMBER" }, include: { user: { select: { id: true, username: true, avatar: true } } }, }); res.status(201).json(member); } // Quitter un groupe export async function leaveGroup(req: AppRequest, res: Response): Promise { const groupId = req.params.id as string; const userId = req.user!.id; const membership = await prisma.groupMember.findUnique({ where: { groupId_userId: { groupId, userId } }, }); if (!membership) { res.status(404).json({ message: "Tu n'es pas membre de ce groupe." }); return; } await prisma.groupMember.delete({ where: { groupId_userId: { groupId, userId } }, }); res.status(204).send(); } // Ajouter un programme au groupe export async function addProgram(req: AppRequest, res: Response): Promise { const groupId = req.params.id as string; const parsed = addGroupProgramSchema.safeParse(req.body); if (!parsed.success) { res.status(400).json({ message: parsed.error.issues[0].message }); return; } const membership = await prisma.groupMember.findUnique({ where: { groupId_userId: { groupId, userId: req.user!.id } }, }); if (!membership || membership.role === "MEMBER") { res.status(403).json({ message: "Accès refusé." }); return; } const entry = await prisma.groupProgram.create({ data: { groupId, programId: parsed.data.programId }, include: { program: true }, }); res.status(201).json(entry); }