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;