136 lines
5.7 KiB
JavaScript
136 lines
5.7 KiB
JavaScript
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;
|