// FILE: backend/src/routes/maps.js // Map ความสัมพันธ์ระหว่าง RFA<->Drawing และ Correspondence<->Document import { Router } from "express"; import sql from "../db/index.js"; import { requirePerm } from "../middleware/requirePerm.js"; const r = Router(); // ========= RFA <-> Drawing ========= // LIST r.get( "/maps/rfa/:rfa_id/drawings", requirePerm("rfas.view", { projectParam: "project_id" }), // ABAC enforced เมื่อส่ง query project_id; ถ้าไม่ส่งเราจะตรวจจากเรคคอร์ด async (req, res) => { const rfa_id = Number(req.params.rfa_id); const [[rfa]] = await sql.query("SELECT project_id FROM rfas WHERE id=?", [ rfa_id, ]); if (!rfa) return res.status(404).json({ error: "RFA not found" }); if ( !req.principal.is_superadmin && !req.principal.inProject(rfa.project_id) ) { return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); } const [rows] = await sql.query( `SELECT m.* FROM rfa_drawing_map m WHERE m.rfa_id=? ORDER BY m.id DESC`, [rfa_id] ); res.json(rows); } ); // ADD r.post( "/maps/rfa/:rfa_id/drawings/:drawing_id", requirePerm("rfas.respond", { projectParam: "project_id" }), async (req, res) => { const rfa_id = Number(req.params.rfa_id); const drawing_id = Number(req.params.drawing_id); const [[rfa]] = await sql.query("SELECT project_id FROM rfas WHERE id=?", [ rfa_id, ]); if (!rfa) return res.status(404).json({ error: "RFA not found" }); if ( !req.principal.is_superadmin && !req.principal.inProject(rfa.project_id) ) { return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); } await sql.query( "INSERT IGNORE INTO rfa_drawing_map (rfa_id, drawing_id, created_by) VALUES (?,?,?)", [rfa_id, drawing_id, req.principal.user_id] ); res.status(201).json({ ok: true }); } ); // REMOVE r.delete( "/maps/rfa/:rfa_id/drawings/:drawing_id", requirePerm("rfas.respond"), async (req, res) => { const rfa_id = Number(req.params.rfa_id); const drawing_id = Number(req.params.drawing_id); const [[rfa]] = await sql.query("SELECT project_id FROM rfas WHERE id=?", [ rfa_id, ]); if (!rfa) return res.status(404).json({ error: "RFA not found" }); if ( !req.principal.is_superadmin && !req.principal.inProject(rfa.project_id) ) { return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); } const [rs] = await sql.query( "DELETE FROM rfa_drawing_map WHERE rfa_id=? AND drawing_id=?", [rfa_id, drawing_id] ); res.json({ ok: rs.affectedRows > 0 }); } ); // ========= Correspondence <-> Document ========= r.get( "/maps/correspondence/:corr_id/documents", requirePerm("corr.view", { projectParam: "project_id" }), async (req, res) => { const corr_id = Number(req.params.corr_id); const [[corr]] = await sql.query( "SELECT project_id FROM correspondences WHERE id=?", [corr_id] ); if (!corr) return res.status(404).json({ error: "Correspondence not found" }); if ( !req.principal.is_superadmin && !req.principal.inProject(corr.project_id) ) { return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); } const [rows] = await sql.query( `SELECT m.* FROM corr_document_map m WHERE m.correspondence_id=? ORDER BY m.id DESC`, [corr_id] ); res.json(rows); } ); r.post( "/maps/correspondence/:corr_id/documents/:doc_id", requirePerm("corr.manage", { projectParam: "project_id" }), async (req, res) => { const corr_id = Number(req.params.corr_id); const doc_id = Number(req.params.doc_id); const [[corr]] = await sql.query( "SELECT project_id FROM correspondences WHERE id=?", [corr_id] ); if (!corr) return res.status(404).json({ error: "Correspondence not found" }); if ( !req.principal.is_superadmin && !req.principal.inProject(corr.project_id) ) { return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); } await sql.query( "INSERT IGNORE INTO corr_document_map (correspondence_id, document_id, created_by) VALUES (?,?,?)", [corr_id, doc_id, req.principal.user_id] ); res.status(201).json({ ok: true }); } ); r.delete( "/maps/correspondence/:corr_id/documents/:doc_id", requirePerm("corr.manage"), async (req, res) => { const corr_id = Number(req.params.corr_id); const doc_id = Number(req.params.doc_id); const [[corr]] = await sql.query( "SELECT project_id FROM correspondences WHERE id=?", [corr_id] ); if (!corr) return res.status(404).json({ error: "Correspondence not found" }); if ( !req.principal.is_superadmin && !req.principal.inProject(corr.project_id) ) { return res.status(403).json({ error: "FORBIDDEN_PROJECT" }); } const [rs] = await sql.query( "DELETE FROM corr_document_map WHERE correspondence_id=? AND document_id=?", [corr_id, doc_id] ); res.json({ ok: rs.affectedRows > 0 }); } ); export default r;