Checkpoint: Implémentation complète des restrictions d'accès pour les formateurs : (1) Ajout du rôle "formateur" dans le schéma de base de données avec champ formateurId pour lier un utilisateur à un formateur. (2) Modification du menu de navigation DashboardLayout pour masquer automatiquement les sections "Configuration", "Traçabilité" et "Analyses" aux utilisateurs ayant le rôle formateur. (3) Filtrage backend des données : création de getSequencesByFormateur, getFormationsByFormateur et getApprenantsByFormateur dans db.ts pour ne retourner que les données pertinentes. (4) Modification des procédures tRPC formations.list, sequences.list et apprenants.list pour utiliser protectedProcedure au lieu de adminProcedure et appliquer le filtrage selon le rôle (formateur vs admin). Les formateurs ne voient désormais que leurs propres formations (celles pour lesquelles ils ont des séquences), leurs propres séquences (où ils sont assignés comme formateur) et uniquement les apprenants inscrits à leurs séquences. Les administrateurs conservent l'accès complet à toutes les données. Cette implémentation garantit une séparation claire des accès et protège les données sensibles tout en permettant aux formateurs de gérer efficacement leurs formations.
This commit is contained in:
@@ -36,8 +36,15 @@ export const appRouter = router({
|
||||
|
||||
// ===== FORMATIONS =====
|
||||
formations: router({
|
||||
list: adminProcedure.query(async () => {
|
||||
return db.getFormations();
|
||||
list: protectedProcedure.query(async ({ ctx }) => {
|
||||
// Si l'utilisateur est formateur, ne montrer que les formations pour lesquelles il a des séquences
|
||||
if (ctx.user.role === 'formateur' && ctx.user.formateurId) {
|
||||
return db.getFormationsByFormateur(ctx.user.formateurId);
|
||||
} else if (ctx.user.role === 'admin') {
|
||||
return db.getFormations();
|
||||
} else {
|
||||
throw new TRPCError({ code: 'FORBIDDEN', message: 'Accès non autorisé' });
|
||||
}
|
||||
}),
|
||||
|
||||
getById: adminProcedure.input(z.object({ id: z.number() })).query(async ({ input }) => {
|
||||
@@ -140,8 +147,15 @@ export const appRouter = router({
|
||||
|
||||
// ===== APPRENANTS =====
|
||||
apprenants: router({
|
||||
list: adminProcedure.query(async () => {
|
||||
return db.getApprenants();
|
||||
list: protectedProcedure.query(async ({ ctx }) => {
|
||||
// Si l'utilisateur est formateur, ne montrer que les apprenants inscrits à ses séquences
|
||||
if (ctx.user.role === 'formateur' && ctx.user.formateurId) {
|
||||
return db.getApprenantsByFormateur(ctx.user.formateurId);
|
||||
} else if (ctx.user.role === 'admin') {
|
||||
return db.getApprenants();
|
||||
} else {
|
||||
throw new TRPCError({ code: 'FORBIDDEN', message: 'Accès non autorisé' });
|
||||
}
|
||||
}),
|
||||
|
||||
getById: adminProcedure.input(z.object({ id: z.number() })).query(async ({ input }) => {
|
||||
@@ -251,8 +265,17 @@ export const appRouter = router({
|
||||
|
||||
// ===== SÉQUENCES =====
|
||||
sequences: router({
|
||||
list: adminProcedure.query(async () => {
|
||||
const seqs = await db.getSequencesWithFormation();
|
||||
list: protectedProcedure.query(async ({ ctx }) => {
|
||||
let seqs;
|
||||
|
||||
// Si l'utilisateur est formateur, ne montrer que ses séquences
|
||||
if (ctx.user.role === 'formateur' && ctx.user.formateurId) {
|
||||
seqs = await db.getSequencesByFormateur(ctx.user.formateurId);
|
||||
} else if (ctx.user.role === 'admin') {
|
||||
seqs = await db.getSequencesWithFormation();
|
||||
} else {
|
||||
throw new TRPCError({ code: 'FORBIDDEN', message: 'Accès non autorisé' });
|
||||
}
|
||||
// Récupérer les dates et le nombre d'inscrits pour chaque séquence
|
||||
const sequencesAvecDates = await Promise.all(
|
||||
seqs.map(async (seq) => {
|
||||
|
||||
Reference in New Issue
Block a user