164 lines
5.1 KiB
JavaScript
164 lines
5.1 KiB
JavaScript
// 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;
|