Initial commit
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import { Router } from 'express';
|
||||
import db from '../db/index.js';
|
||||
import { HttpError } from '../middleware/errorHandler.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
const TYPES_VALIDES = ['etoiles', 'lettres', 'score', 'custom'];
|
||||
|
||||
/** Valide et normalise un critère entrant */
|
||||
function parseBody(body) {
|
||||
const { plateforme_id, nom, type = 'etoiles', valeurs, min_val, max_val, description, ordre } = body;
|
||||
if (!plateforme_id) throw new HttpError(400, 'plateforme_id est requis');
|
||||
if (!nom?.trim()) throw new HttpError(400, 'nom est requis');
|
||||
if (!TYPES_VALIDES.includes(type)) throw new HttpError(400, `type invalide — attendu : ${TYPES_VALIDES.join(', ')}`);
|
||||
|
||||
// Validation selon le type
|
||||
if (type === 'score') {
|
||||
if (min_val === undefined || max_val === undefined) throw new HttpError(400, 'min_val et max_val requis pour le type score');
|
||||
if (Number(min_val) >= Number(max_val)) throw new HttpError(400, 'min_val doit être inférieur à max_val');
|
||||
}
|
||||
if ((type === 'lettres' || type === 'custom') && (!valeurs || !valeurs.length)) {
|
||||
throw new HttpError(400, `valeurs est requis pour le type ${type}`);
|
||||
}
|
||||
|
||||
return {
|
||||
plateforme_id: Number(plateforme_id),
|
||||
nom: nom.trim(),
|
||||
type,
|
||||
valeurs: (type === 'lettres' || type === 'custom')
|
||||
? JSON.stringify(Array.isArray(valeurs) ? valeurs : valeurs.split(',').map(v => v.trim()).filter(Boolean))
|
||||
: null,
|
||||
min_val: type === 'score' ? Number(min_val) : null,
|
||||
max_val: type === 'score' ? Number(max_val) : null,
|
||||
description: description?.trim() || null,
|
||||
ordre: Number(ordre ?? 0),
|
||||
};
|
||||
}
|
||||
|
||||
/** Enrichit les lignes DB (parse valeurs JSON) */
|
||||
function enrich(row) {
|
||||
return {
|
||||
...row,
|
||||
valeurs: row.valeurs ? JSON.parse(row.valeurs) : null,
|
||||
};
|
||||
}
|
||||
|
||||
/* ── GET /api/notation?plateforme_id=X ───────────────────────── */
|
||||
router.get('/', (req, res) => {
|
||||
const { plateforme_id } = req.query;
|
||||
if (plateforme_id) {
|
||||
const rows = db.prepare(`
|
||||
SELECT nc.* FROM notation_criteres nc
|
||||
JOIN plateformes p ON p.id = nc.plateforme_id
|
||||
WHERE nc.plateforme_id = ? AND p.user_id = ?
|
||||
ORDER BY nc.ordre, nc.id
|
||||
`).all(Number(plateforme_id), req.user.id);
|
||||
return res.json(rows.map(enrich));
|
||||
}
|
||||
// Tous les critères de l'utilisateur (toutes plateformes)
|
||||
const rows = db.prepare(`
|
||||
SELECT nc.*, p.nom AS plateforme_nom FROM notation_criteres nc
|
||||
JOIN plateformes p ON p.id = nc.plateforme_id
|
||||
WHERE p.user_id = ?
|
||||
ORDER BY p.nom, nc.ordre, nc.id
|
||||
`).all(req.user.id);
|
||||
res.json(rows.map(enrich));
|
||||
});
|
||||
|
||||
/* ── POST /api/notation ──────────────────────────────────────── */
|
||||
router.post('/', (req, res, next) => {
|
||||
try {
|
||||
const data = parseBody(req.body);
|
||||
// Vérifie que la plateforme appartient à l'utilisateur
|
||||
const plat = db.prepare('SELECT id FROM plateformes WHERE id = ? AND user_id = ?')
|
||||
.get(data.plateforme_id, req.user.id);
|
||||
if (!plat) throw new HttpError(404, 'Plateforme introuvable');
|
||||
|
||||
const r = db.prepare(`
|
||||
INSERT INTO notation_criteres (plateforme_id, nom, type, valeurs, min_val, max_val, description, ordre)
|
||||
VALUES (?,?,?,?,?,?,?,?)
|
||||
`).run(data.plateforme_id, data.nom, data.type, data.valeurs, data.min_val, data.max_val, data.description, data.ordre);
|
||||
|
||||
const created = enrich(db.prepare('SELECT * FROM notation_criteres WHERE id = ?').get(r.lastInsertRowid));
|
||||
res.status(201).json(created);
|
||||
} catch (e) { next(e); }
|
||||
});
|
||||
|
||||
/* ── PUT /api/notation/:id ───────────────────────────────────── */
|
||||
router.put('/:id', (req, res, next) => {
|
||||
try {
|
||||
const existing = db.prepare(`
|
||||
SELECT nc.* FROM notation_criteres nc
|
||||
JOIN plateformes p ON p.id = nc.plateforme_id
|
||||
WHERE nc.id = ? AND p.user_id = ?
|
||||
`).get(req.params.id, req.user.id);
|
||||
if (!existing) throw new HttpError(404, 'Critère introuvable');
|
||||
|
||||
const data = parseBody({ ...req.body, plateforme_id: existing.plateforme_id });
|
||||
db.prepare(`
|
||||
UPDATE notation_criteres
|
||||
SET nom=?, type=?, valeurs=?, min_val=?, max_val=?, description=?, ordre=?
|
||||
WHERE id=?
|
||||
`).run(data.nom, data.type, data.valeurs, data.min_val, data.max_val, data.description, data.ordre, req.params.id);
|
||||
|
||||
res.json(enrich(db.prepare('SELECT * FROM notation_criteres WHERE id = ?').get(req.params.id)));
|
||||
} catch (e) { next(e); }
|
||||
});
|
||||
|
||||
/* ── DELETE /api/notation/:id ────────────────────────────────── */
|
||||
router.delete('/:id', (req, res, next) => {
|
||||
try {
|
||||
const existing = db.prepare(`
|
||||
SELECT nc.id FROM notation_criteres nc
|
||||
JOIN plateformes p ON p.id = nc.plateforme_id
|
||||
WHERE nc.id = ? AND p.user_id = ?
|
||||
`).get(req.params.id, req.user.id);
|
||||
if (!existing) throw new HttpError(404, 'Critère introuvable');
|
||||
db.prepare('DELETE FROM notation_criteres WHERE id = ?').run(req.params.id);
|
||||
res.json({ deleted: true });
|
||||
} catch (e) { next(e); }
|
||||
});
|
||||
|
||||
/* ── PUT /api/notation/reorder ───────────────────────────────── */
|
||||
router.put('/reorder', (req, res, next) => {
|
||||
try {
|
||||
const { ids } = req.body; // tableau d'ids dans le nouvel ordre
|
||||
if (!Array.isArray(ids)) throw new HttpError(400, 'ids[] requis');
|
||||
const upd = db.prepare('UPDATE notation_criteres SET ordre = ? WHERE id = ?');
|
||||
const tx = db.transaction(() => ids.forEach((id, i) => upd.run(i, id)));
|
||||
tx();
|
||||
res.json({ reordered: true });
|
||||
} catch (e) { next(e); }
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user