import { Router } from 'express'; import { z } from 'zod'; import db from '../db/index.js'; import { HttpError } from '../middleware/errorHandler.js'; const router = Router(); // Monté sous requireAuth dans server.js /* ───────────────────────────────────────────────────────────── GET /api/categories-inv Retourne les catégories globales (user_id IS NULL) + privées de l'utilisateur connecté. Chaque entrée : { id, nom, is_global, nb_plateformes, nb_investissements } ───────────────────────────────────────────────────────────────*/ router.get('/', (req, res) => { const userId = req.user.id; const rows = db.prepare(` SELECT c.id, c.nom, CASE WHEN c.user_id IS NULL THEN 1 ELSE 0 END AS is_global, (SELECT COUNT(*) FROM plateforme_categories_inv pc WHERE pc.categorie_id = c.id AND pc.plateforme_id IN ( SELECT p.id FROM plateformes p JOIN investisseurs i ON i.id = p.investisseur_id WHERE i.user_id = ? ) ) AS nb_plateformes, (SELECT COUNT(*) FROM investissement_categories_inv ic WHERE ic.categorie_id = c.id AND ic.investissement_id IN ( SELECT inv.id FROM investissements inv JOIN investisseurs i ON i.id = inv.investisseur_id WHERE i.user_id = ? ) ) AS nb_investissements FROM categories_inv c WHERE c.user_id IS NULL OR c.user_id = ? ORDER BY is_global DESC, c.nom `).all(userId, userId, userId); res.json(rows); }); /* ───────────────────────────────────────────────────────────── POST /api/categories-inv — créer une catégorie privée ───────────────────────────────────────────────────────────────*/ router.post('/', (req, res, next) => { try { const { nom } = z.object({ nom: z.string().min(1).max(200) }).parse(req.body); const userId = req.user.id; const dup = db.prepare( 'SELECT id FROM categories_inv WHERE nom = ? AND (user_id IS NULL OR user_id = ?)' ).get(nom.trim(), userId); if (dup) throw new HttpError(409, `La catégorie "${nom.trim()}" existe déjà.`); const r = db.prepare( 'INSERT INTO categories_inv (nom, user_id) VALUES (?, ?)' ).run(nom.trim(), userId); res.status(201).json({ id: r.lastInsertRowid, nom: nom.trim(), is_global: 0, nb_plateformes: 0, nb_investissements: 0 }); } catch (e) { next(e); } }); /* ───────────────────────────────────────────────────────────── PUT /api/categories-inv/:id — renommer (uniquement les privées) ───────────────────────────────────────────────────────────────*/ router.put('/:id', (req, res, next) => { try { const { nom } = z.object({ nom: z.string().min(1).max(200) }).parse(req.body); const userId = req.user.id; const row = db.prepare('SELECT id, nom, user_id FROM categories_inv WHERE id = ?').get(req.params.id); if (!row) throw new HttpError(404, 'Catégorie introuvable'); if (row.user_id === null) throw new HttpError(403, 'Les catégories globales ne peuvent pas être modifiées.'); if (row.user_id !== userId) throw new HttpError(403, 'Cette catégorie ne vous appartient pas.'); const dup = db.prepare( 'SELECT id FROM categories_inv WHERE nom = ? AND (user_id IS NULL OR user_id = ?) AND id != ?' ).get(nom.trim(), userId, row.id); if (dup) throw new HttpError(409, `La catégorie "${nom.trim()}" existe déjà.`); db.prepare('UPDATE categories_inv SET nom = ? WHERE id = ?').run(nom.trim(), row.id); res.json({ id: row.id, nom: nom.trim(), is_global: 0 }); } catch (e) { next(e); } }); /* ───────────────────────────────────────────────────────────── DELETE /api/categories-inv/:id — supprimer (uniquement les privées) ───────────────────────────────────────────────────────────────*/ router.delete('/:id', (req, res, next) => { try { const userId = req.user.id; const row = db.prepare('SELECT id, user_id FROM categories_inv WHERE id = ?').get(req.params.id); if (!row) throw new HttpError(404, 'Catégorie introuvable'); if (row.user_id === null) throw new HttpError(403, 'Les catégories globales ne peuvent pas être supprimées.'); if (row.user_id !== userId) throw new HttpError(403, 'Cette catégorie ne vous appartient pas.'); // Retirer des associations avant suppression db.transaction(() => { db.prepare('DELETE FROM plateforme_categories_inv WHERE categorie_id = ?').run(row.id); db.prepare('DELETE FROM investissement_categories_inv WHERE categorie_id = ?').run(row.id); db.prepare('DELETE FROM categories_inv WHERE id = ?').run(row.id); })(); res.status(204).end(); } catch (e) { next(e); } }); export default router;