71 lines
2.6 KiB
JavaScript
71 lines
2.6 KiB
JavaScript
'use strict';
|
|
|
|
const express = require('express');
|
|
const db = require('../../db');
|
|
const requireAuth = require('../middleware/requireAuth');
|
|
const verifyCsrf = require('../middleware/csrf');
|
|
const { ownerOfProject, projectIdOfKpi } = require('../middleware/requireOwnerOrAdmin');
|
|
|
|
const router = express.Router();
|
|
router.use(requireAuth);
|
|
|
|
const getKpi = db.prepare('SELECT * FROM kpis WHERE id = ?');
|
|
const insertKpi = db.prepare(
|
|
`INSERT INTO kpis (project_id, name, description, unit, goal_text, sort_order)
|
|
VALUES (@project_id, @name, @description, @unit, @goal_text, @sort_order)`
|
|
);
|
|
const nextSort = db.prepare(
|
|
'SELECT COALESCE(MAX(sort_order), -1) + 1 AS n FROM kpis WHERE project_id = ?'
|
|
);
|
|
|
|
// POST /api/kpis — body.project_id authorizes against the owning project.
|
|
router.post(
|
|
'/',
|
|
verifyCsrf,
|
|
ownerOfProject((req) => Number(req.body && req.body.project_id)),
|
|
(req, res) => {
|
|
const name = (req.body.name || '').trim();
|
|
if (!name) return res.status(400).json({ error: 'KPI name is required' });
|
|
const info = insertKpi.run({
|
|
project_id: req.project.id,
|
|
name,
|
|
description: (req.body.description || '').trim() || null,
|
|
unit: (req.body.unit || '').trim() || null,
|
|
goal_text: (req.body.goal_text || '').trim() || null,
|
|
sort_order: nextSort.get(req.project.id).n,
|
|
});
|
|
res.status(201).json({ kpi: getKpi.get(info.lastInsertRowid) });
|
|
}
|
|
);
|
|
|
|
// Authorize :id routes via the KPI's owning project.
|
|
const kpiProject = (req) => projectIdOfKpi(Number(req.params.id));
|
|
|
|
// PATCH /api/kpis/:id
|
|
router.patch('/:id', verifyCsrf, ownerOfProject(kpiProject), (req, res) => {
|
|
const id = Number(req.params.id);
|
|
const kpi = getKpi.get(id);
|
|
const { name, description, unit, goal_text, sort_order } = req.body || {};
|
|
const next = {
|
|
name: name !== undefined ? (name.trim() || kpi.name) : kpi.name,
|
|
description: description !== undefined ? (description || null) : kpi.description,
|
|
unit: unit !== undefined ? (unit || null) : kpi.unit,
|
|
goal_text: goal_text !== undefined ? (goal_text || null) : kpi.goal_text,
|
|
sort_order: sort_order !== undefined ? Number(sort_order) : kpi.sort_order,
|
|
id,
|
|
};
|
|
db.prepare(
|
|
`UPDATE kpis SET name=@name, description=@description, unit=@unit,
|
|
goal_text=@goal_text, sort_order=@sort_order WHERE id=@id`
|
|
).run(next);
|
|
res.json({ kpi: getKpi.get(id) });
|
|
});
|
|
|
|
// DELETE /api/kpis/:id (cascades to entries)
|
|
router.delete('/:id', verifyCsrf, ownerOfProject(kpiProject), (req, res) => {
|
|
db.prepare('DELETE FROM kpis WHERE id = ?').run(Number(req.params.id));
|
|
res.json({ ok: true });
|
|
});
|
|
|
|
module.exports = router;
|