Files
dashboard/backend/routes/dashboardReportSnapshots.js
T

111 lines
3.3 KiB
JavaScript

const express = require('express');
const router = express.Router();
const DashboardReportSnapshot = require('../models/DashboardReportSnapshot');
const ALLOWED_REPORT_TYPES = new Set(['daily', 'end_cycle']);
const parseKandangId = (value) => {
if (value === null || value === undefined || value === '') return null;
const parsed = Number(value);
return Number.isInteger(parsed) ? parsed : null;
};
const parseReportType = (value) => {
if (value === null || value === undefined || value === '') return 'daily';
if (ALLOWED_REPORT_TYPES.has(value)) return value;
return null;
};
/**
* GET /api/dashboard-report-snapshots/:cycleId?kandangId=&reportType=
* Latest snapshot for this cycle+kandang+type. 404 when none.
*/
router.get('/:cycleId', async (req, res) => {
try {
const { cycleId } = req.params;
const kandangId = parseKandangId(req.query.kandangId);
const reportType = parseReportType(req.query.reportType);
if (!cycleId || kandangId === null) {
return res.status(400).json({
success: false,
error: 'cycleId and kandangId are required',
});
}
if (reportType === null) {
return res.status(400).json({
success: false,
error: 'reportType must be daily or end_cycle',
});
}
const snapshot = await DashboardReportSnapshot.getByCycleAndKandang(
cycleId,
kandangId,
reportType
);
if (!snapshot) {
return res.status(404).json({
success: false,
data: null,
message: 'No snapshot found',
});
}
res.json({ success: true, data: snapshot });
} catch (error) {
console.error('Error fetching dashboard report snapshot:', error);
res.status(500).json({ success: false, error: error.message });
}
});
/**
* POST /api/dashboard-report-snapshots
* Upsert frozen snapshot for cycle+kandang+reportType. Overwrites the previous row of that type.
*/
router.post('/', async (req, res) => {
try {
const { cycleId, kandangId, upToDay, payload, generatedAt, reportType } = req.body || {};
const parsedKandangId = parseKandangId(kandangId);
const parsedReportType = parseReportType(reportType);
if (!cycleId || parsedKandangId === null) {
return res.status(400).json({
success: false,
error: 'cycleId and kandangId are required',
});
}
if (parsedReportType === null) {
return res.status(400).json({
success: false,
error: 'reportType must be daily or end_cycle',
});
}
if (upToDay === null || upToDay === undefined || !Number.isFinite(Number(upToDay))) {
return res.status(400).json({
success: false,
error: 'upToDay is required',
});
}
const snapshot = await DashboardReportSnapshot.upsert({
cycleId,
kandangId: parsedKandangId,
upToDay: Number(upToDay),
payload: payload ?? {},
generatedAt,
reportType: parsedReportType,
});
res.json({ success: true, data: snapshot });
} catch (error) {
if (error.code === 'INVALID_REPORT_TYPE') {
return res.status(400).json({ success: false, error: error.message });
}
console.error('Error saving dashboard report snapshot:', error);
res.status(500).json({ success: false, error: error.message });
}
});
module.exports = router;