111 lines
3.3 KiB
JavaScript
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;
|