// FILE: backend/src/routes/correspondences.js import { Router } from "express"; import sql from "../db/index.js"; import { requirePerm } from "../middleware/requirePerm.js"; const r = Router(); // LIST r.get( "/", requirePerm("corr.view", { projectParam: "project_id" }), async (req, res) => { const { project_id, org_id, q, limit = 50, offset = 0 } = req.query; const p = req.principal; const params = []; const cond = []; if (!p.is_superadmin) { if (project_id) { if (!p.inProject(Number(project_id))) return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); cond.push("c.project_id=?"); params.push(Number(project_id)); } else if (p.project_ids?.length) { cond.push( `c.project_id IN (${p.project_ids.map(() => "?").join(",")})` ); params.push(...p.project_ids); } } else if (project_id) { cond.push("c.project_id=?"); params.push(Number(project_id)); } if (org_id) { cond.push("c.org_id=?"); params.push(Number(org_id)); } if (q) { cond.push("(c.corr_no LIKE ? OR c.subject LIKE ?)"); params.push(`%${q}%`, `%${q}%`); } const where = cond.length ? `WHERE ${cond.join(" AND ")}` : ""; const [rows] = await sql.query( `SELECT c.* FROM correspondences c ${where} ORDER BY c.id DESC LIMIT ? OFFSET ?`, [...params, Number(limit), Number(offset)] ); res.json(rows); } ); // GET r.get("/:id", requirePerm("corr.view"), async (req, res) => { const id = Number(req.params.id); const [[row]] = await sql.query("SELECT * FROM correspondences WHERE id=?", [ id, ]); if (!row) return res.status(404).json({ error: "Not found" }); const p = req.principal; if (!p.is_superadmin && !p.inProject(row.project_id)) return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); res.json(row); }); // CREATE r.post( "/", requirePerm("corr.manage", { projectParam: "project_id" }), async (req, res) => { const { org_id, project_id, corr_no, subject, status } = req.body || {}; if (!project_id || !corr_no) return res.status(400).json({ error: "project_id and corr_no required" }); const [rs] = await sql.query( `INSERT INTO correspondences (org_id, project_id, corr_no, subject, status, created_by) VALUES (?,?,?,?,?,?)`, [ org_id || null, project_id, corr_no, subject || null, status || null, req.principal.user_id, ] ); res.json({ id: rs.insertId }); } ); // UPDATE r.put("/:id", requirePerm("corr.manage"), async (req, res) => { const id = Number(req.params.id); const [[row]] = await sql.query("SELECT * FROM correspondences WHERE id=?", [ id, ]); if (!row) return res.status(404).json({ error: "Not found" }); const p = req.principal; if (!p.is_superadmin && !p.inProject(row.project_id)) return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); const { subject, status } = req.body || {}; await sql.query("UPDATE correspondences SET subject=?, status=? WHERE id=?", [ subject ?? row.subject, status ?? row.status, id, ]); res.json({ ok: 1 }); }); // DELETE r.delete("/:id", requirePerm("corr.manage"), async (req, res) => { const id = Number(req.params.id); const [[row]] = await sql.query("SELECT * FROM correspondences WHERE id=?", [ id, ]); if (!row) return res.status(404).json({ error: "Not found" }); const p = req.principal; if (!p.is_superadmin && !p.inProject(row.project_id)) return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); await sql.query("DELETE FROM correspondences WHERE id=?", [id]); res.json({ ok: 1 }); }); export default r;