Files
planlinked/server/src/routes/boards.js
T

81 lines
2.8 KiB
JavaScript

const express = require("express");
const { query, getOne } = require("../db/queries");
const { requireAuth } = require("../middleware/auth");
const router = express.Router();
async function canAccessProject(userId, projectId) {
const row = await getOne(
"SELECT 1 FROM project_members WHERE project_id = ? AND user_id = ?",
[projectId, userId]
);
return Boolean(row);
}
async function getProjectRole(userId, projectId) {
const row = await getOne(
"SELECT role FROM project_members WHERE project_id = ? AND user_id = ?",
[projectId, userId]
);
return row?.role || null;
}
router.get("/", requireAuth, async (req, res) => {
const projectId = req.query.projectId ? Number(req.query.projectId) : null;
let items;
if (projectId) {
const ok = await canAccessProject(req.user.id, projectId);
if (!ok) return res.status(403).json({ ok: false, message: "forbidden" });
items = await query("SELECT * FROM boards WHERE project_id = ? ORDER BY position ASC", [projectId]);
} else {
items = await query(
`SELECT b.*\n FROM boards b\n JOIN project_members pm ON pm.project_id = b.project_id\n WHERE pm.user_id = ?\n ORDER BY b.created_at DESC`,
[req.user.id]
);
}
res.json({ ok: true, items });
});
router.post("/", requireAuth, async (req, res) => {
const { projectId, name, description } = req.body || {};
if (!projectId || !name) return res.status(400).json({ ok: false, message: "missing fields" });
const ok = await canAccessProject(req.user.id, projectId);
if (!ok) return res.status(403).json({ ok: false, message: "forbidden" });
const role = await getProjectRole(req.user.id, projectId);
if (role === "member") {
return res.status(403).json({ ok: false, message: "insufficient role" });
}
const result = await query(
"INSERT INTO boards (project_id, name, description, position) VALUES (?, ?, ?, ?)",
[projectId, name, description || null, 0]
);
const board = await getOne("SELECT * FROM boards WHERE id = ?", [result.insertId]);
res.status(201).json({ ok: true, item: board });
});
router.get("/:id/activity", requireAuth, async (req, res) => {
const boardId = Number(req.params.id);
const board = await getOne("SELECT project_id FROM boards WHERE id = ?", [boardId]);
if (!board) return res.status(404).json({ ok: false, message: "not found" });
const ok = await canAccessProject(req.user.id, board.project_id);
if (!ok) return res.status(403).json({ ok: false, message: "forbidden" });
const items = await query(
`SELECT a.id, a.type, a.payload, a.created_at, u.name as actor_name
FROM activities a
JOIN users u ON u.id = a.actor_id
WHERE a.board_id = ?
ORDER BY a.created_at DESC
LIMIT 200`,
[boardId]
);
res.json({ ok: true, items });
});
module.exports = router;