feat(backend): add GET /api/materiels catalogue endpoint
This commit is contained in:
@@ -6,6 +6,7 @@ import { logger } from './utils/logger';
|
||||
import { requestLogger } from './middlewares/request-logger';
|
||||
import { notFoundHandler } from './middlewares/not-found';
|
||||
import { errorHandler } from './middlewares/error-handler';
|
||||
import { apiRouter } from './routes';
|
||||
|
||||
const app = express();
|
||||
|
||||
@@ -17,6 +18,8 @@ app.get('/health', (_req, res) => {
|
||||
res.json({ status: 'ok', app: 'EME API' });
|
||||
});
|
||||
|
||||
app.use('/api', apiRouter);
|
||||
|
||||
/* notFoundHandler et errorHandler doivent rester après toutes les routes :
|
||||
le premier capture les URL non gérées, le second clôt la chaîne Express. */
|
||||
app.use(notFoundHandler);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { AppError } from '../errors/app-error';
|
||||
import { listerCatalogue } from '../services/materiel.service';
|
||||
|
||||
function parseCategorieId(value: unknown): number | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const parsed = Number(value);
|
||||
if (!Number.isInteger(parsed) || parsed <= 0) {
|
||||
throw new AppError(400, 'categorieId invalide');
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
export async function getCatalogue(req: Request, res: Response): Promise<void> {
|
||||
const user = req.user;
|
||||
if (!user) {
|
||||
throw new AppError(401, 'Authentification requise');
|
||||
}
|
||||
|
||||
const recherche = typeof req.query.q === 'string' ? req.query.q : undefined;
|
||||
const categorieId = parseCategorieId(req.query.categorieId);
|
||||
|
||||
const materiels = await listerCatalogue(user.campusId, { categorieId, recherche });
|
||||
res.json({ data: materiels });
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { prisma } from '../db/prisma';
|
||||
|
||||
export type MaterielAvecCategorie = Prisma.MaterielGetPayload<{ include: { categorie: true } }>;
|
||||
|
||||
export interface CatalogueFiltres {
|
||||
categorieId?: number;
|
||||
recherche?: string;
|
||||
}
|
||||
|
||||
export function findDisponiblesParCampus(
|
||||
campusId: number,
|
||||
filtres: CatalogueFiltres,
|
||||
): Promise<MaterielAvecCategorie[]> {
|
||||
const { categorieId, recherche } = filtres;
|
||||
|
||||
return prisma.materiel.findMany({
|
||||
where: {
|
||||
campusId,
|
||||
actif: true,
|
||||
statut: 'DISPONIBLE',
|
||||
...(categorieId !== undefined ? { categorieId } : {}),
|
||||
...(recherche
|
||||
? {
|
||||
OR: [
|
||||
{ nom: { contains: recherche } },
|
||||
{ marque: { contains: recherche } },
|
||||
{ modele: { contains: recherche } },
|
||||
{ reference: { contains: recherche } },
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
include: { categorie: true },
|
||||
orderBy: { nom: 'asc' },
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Router } from 'express';
|
||||
import { currentUser } from '../middlewares/current-user';
|
||||
import { materielRoutes } from './materiel.routes';
|
||||
|
||||
export const apiRouter: Router = Router();
|
||||
|
||||
apiRouter.use(currentUser);
|
||||
apiRouter.use('/materiels', materielRoutes);
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Router } from 'express';
|
||||
import { getCatalogue } from '../controllers/materiel.controller';
|
||||
|
||||
export const materielRoutes: Router = Router();
|
||||
|
||||
materielRoutes.get('/', getCatalogue);
|
||||
@@ -0,0 +1,14 @@
|
||||
import {
|
||||
findDisponiblesParCampus,
|
||||
CatalogueFiltres,
|
||||
MaterielAvecCategorie,
|
||||
} from '../repositories/materiel.repository';
|
||||
|
||||
/* RG10 : après identification, seuls les matériels disponibles du campus de
|
||||
l'étudiant sont affichés. */
|
||||
export function listerCatalogue(
|
||||
campusId: number,
|
||||
filtres: CatalogueFiltres,
|
||||
): Promise<MaterielAvecCategorie[]> {
|
||||
return findDisponiblesParCampus(campusId, filtres);
|
||||
}
|
||||
Reference in New Issue
Block a user