bowler-chart/src/routes/entries.routes.js

55 lines
1.8 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 STATUSES = new Set(['green', 'amber', 'red', 'none']);
const upsert = db.prepare(
`INSERT INTO entries (kpi_id, year, month, value, status, note, updated_by, updated_at)
VALUES (@kpi_id, @year, @month, @value, @status, @note, @updated_by, datetime('now'))
ON CONFLICT (kpi_id, year, month) DO UPDATE SET
value = excluded.value,
status = excluded.status,
note = excluded.note,
updated_by = excluded.updated_by,
updated_at = datetime('now')`
);
const getEntry = db.prepare(
'SELECT month, value, status, note FROM entries WHERE kpi_id = ? AND year = ? AND month = ?'
);
// PUT /api/entries — upsert one monthly cell; authorized via the KPI's project.
router.put(
'/',
verifyCsrf,
ownerOfProject((req) => projectIdOfKpi(Number(req.body && req.body.kpi_id))),
(req, res) => {
const { kpi_id, year, month, value, status, note } = req.body || {};
const m = Number(month);
const y = Number(year);
if (!(m >= 1 && m <= 12) || !y) {
return res.status(400).json({ error: 'Valid year and month (1-12) are required' });
}
const safeStatus = STATUSES.has(status) ? status : 'none';
upsert.run({
kpi_id: Number(kpi_id),
year: y,
month: m,
value: value === '' || value === undefined ? null : String(value),
status: safeStatus,
note: note ? String(note) : null,
updated_by: req.session.userId,
});
res.json({ entry: getEntry.get(Number(kpi_id), y, m) });
}
);
module.exports = router;