// FILE: backend/src/routes/view.js // Saved Views: อ่านด้วย reports.view (GLOBAL); เขียนด้วย settings.manage import { Router } from "express"; import sql from "../db/index.js"; import { requirePerm } from "../middleware/requirePerm.js"; const r = Router(); // LIST (ทุกคนที่มี reports.view) r.get("/", requirePerm("reports.view"), async (req, res) => { const { project_id, shared = "1", q, limit = 50, offset = 0 } = req.query; const p = req.principal; const cond = []; const params = []; // ให้เห็นของตัวเองเสมอ + shared cond.push("(v.is_shared=1 OR v.owner_user_id=?)"); params.push(p.user_id); if (project_id) { cond.push("v.project_id=?"); params.push(Number(project_id)); } if (q) { cond.push("v.name LIKE ?"); params.push(`%${q}%`); } if (shared === "0") { cond.push("v.is_shared=0"); } const where = `WHERE ${cond.join(" AND ")}`; const [rows] = await sql.query( `SELECT v.* FROM saved_views v ${where} ORDER BY v.id DESC LIMIT ? OFFSET ?`, [...params, Number(limit), Number(offset)] ); res.json(rows); }); // GET r.get("/:id", requirePerm("reports.view"), async (req, res) => { const id = Number(req.params.id); const [[row]] = await sql.query("SELECT * FROM saved_views WHERE id=?", [id]); if (!row) return res.status(404).json({ error: "Not found" }); if ( !( row.is_shared || row.owner_user_id === req.principal.user_id || req.principal.is_superadmin ) ) { return res.status(403).json({ error: "FORBIDDEN" }); } res.json(row); }); // CREATE / UPDATE / DELETE (ต้องมี settings.manage) r.post("/", requirePerm("settings.manage"), async (req, res) => { const { org_id, project_id, name, payload_json, is_shared = 0, } = req.body || {}; const [rs] = await sql.query( `INSERT INTO saved_views (org_id, project_id, name, payload_json, is_shared, owner_user_id) VALUES (?,?,?,?,?,?)`, [ org_id ?? null, project_id ?? null, name ?? "", JSON.stringify(payload_json ?? {}), Number(is_shared) ? 1 : 0, req.principal.user_id, ] ); res.status(201).json({ id: rs.insertId }); }); r.put("/:id", requirePerm("settings.manage"), async (req, res) => { const id = Number(req.params.id); const { name, payload_json, is_shared } = req.body || {}; await sql.query( "UPDATE saved_views SET name=?, payload_json=?, is_shared=? WHERE id=?", [ name ?? null, JSON.stringify(payload_json ?? {}), Number(is_shared) ? 1 : 0, id, ] ); res.json({ ok: 1 }); }); r.delete("/:id", requirePerm("settings.manage"), async (req, res) => { const id = Number(req.params.id); await sql.query("DELETE FROM saved_views WHERE id=?", [id]); res.json({ ok: 1 }); }); export default r;