Files
dashboard/backend/routes/mortality.js
T
Alberto-Audrix 32a36cceff
CI / lint-and-test (push) Canceled after 0s
first commit
2026-07-28 08:55:05 +07:00

136 lines
5.4 KiB
JavaScript

const express = require('express');
const router = express.Router();
const Mortality = require('../models/Mortality');
const { captureAuditLog, filterAuditFields } = require('../middleware/auditLogger');
router.get('/:cycleId', async (req, res) => {
try {
const kandangId = req.query.kandangId ? parseInt(req.query.kandangId, 10) : null;
const records = await Mortality.getByCycle(req.params.cycleId, kandangId);
res.json({ success: true, data: records });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// GET aggregated totals across all kandangs
router.get('/:cycleId/totals', async (req, res) => {
try {
const totals = await Mortality.getTotalsByCycle(req.params.cycleId);
res.json({ success: true, data: totals });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
router.get('/:cycleId/:day', async (req, res) => {
try {
const day = parseInt(req.params.day, 10);
if (isNaN(day)) return res.status(400).json({ success: false, error: 'Day must be a number' });
const kandangId = req.query.kandangId ? parseInt(req.query.kandangId, 10) : null;
const record = await Mortality.getByDay(req.params.cycleId, day, kandangId);
if (!record) return res.status(404).json({ success: false, error: 'Mortality record not found' });
res.json({ success: true, data: record });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
router.put('/:cycleId/:day', async (req, res) => {
try {
const day = parseInt(req.params.day, 10);
const { mortalityCount, chickenCount, kandangId, panen, keterangan, afkir, beratPanen } = req.body;
// Validation
if (isNaN(day) || mortalityCount === undefined || mortalityCount < 0) {
return res.status(400).json({ success: false, error: 'Invalid mortality count' });
}
if (afkir !== undefined && afkir < 0) {
return res.status(400).json({ success: false, error: 'Afkir must be non-negative' });
}
if (panen !== undefined && panen < 0) {
return res.status(400).json({ success: false, error: 'Panen must be non-negative' });
}
if (beratPanen !== undefined && beratPanen < 0) {
return res.status(400).json({ success: false, error: 'Berat panen must be non-negative' });
}
if (keterangan && keterangan.length > 200) {
return res.status(400).json({ success: false, error: 'Keterangan must be 200 characters or less' });
}
const parsedKandangId = kandangId ? parseInt(kandangId, 10) : null;
const parsedAfkir = afkir !== undefined ? parseInt(afkir, 10) : 0;
const parsedPanen = panen !== undefined ? parseInt(panen, 10) : 0;
const parsedBeratPanen = beratPanen !== undefined ? parseFloat(beratPanen) : 0;
const parsedKeterangan = keterangan || null;
if (beratPanen !== undefined && Number.isNaN(parsedBeratPanen)) {
return res.status(400).json({ success: false, error: 'Berat panen must be a number' });
}
// Fetch old record for audit logging
const oldRecord = await Mortality.getByDay(req.params.cycleId, day, parsedKandangId);
const isCreate = !oldRecord;
// Perform update/insert
const record = await Mortality.upsert(
req.params.cycleId,
day,
mortalityCount,
true,
chickenCount,
parsedKandangId,
parsedPanen,
parsedKeterangan,
parsedAfkir,
parsedBeratPanen
);
// Capture audit log
const recordId = `${req.params.cycleId}-${day}${parsedKandangId ? `-${parsedKandangId}` : ''}`;
await captureAuditLog(
'mortality_records',
recordId,
isCreate ? 'CREATE' : 'UPDATE',
isCreate ? null : filterAuditFields(oldRecord),
filterAuditFields(record)
);
res.json({ success: true, data: record });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
router.delete('/:cycleId/:day', async (req, res) => {
try {
const day = parseInt(req.params.day, 10);
if (isNaN(day)) return res.status(400).json({ success: false, error: 'Day must be a number' });
const kandangId = req.query.kandangId ? parseInt(req.query.kandangId, 10) : null;
// Fetch record before deleting for audit log
const oldRecord = await Mortality.getByDay(req.params.cycleId, day, kandangId);
const deleted = await Mortality.delete(req.params.cycleId, day, kandangId);
if (!deleted) return res.status(404).json({ success: false, error: 'Mortality record not found' });
// Capture audit log
if (oldRecord) {
const recordId = `${req.params.cycleId}-${day}${kandangId ? `-${kandangId}` : ''}`;
await captureAuditLog(
'mortality_records',
recordId,
'DELETE',
filterAuditFields(oldRecord),
null
);
}
res.json({ success: true, message: 'Mortality record deleted successfully' });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
module.exports = router;