const router = require('express').Router(); const { body, query } = require('express-validator'); const prisma = require('../lib/prisma'); const auditMiddleware = require('../middleware/auditMiddleware'); const { validateRequest } = require('../middleware/errorHandler'); const statusValidation = [ body('animal_id').notEmpty().withMessage('animal_id is required').matches(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).withMessage('animal_id must be a valid UUID'), body('date').notEmpty().withMessage('date is required').isISO8601().withMessage('date must be a valid ISO 8601 date (YYYY-MM-DD)'), body('experiment_description').optional().isString(), body('vitals').optional().isString(), body('treatment').optional().isString(), body('notes').optional().isString(), ]; const statusUpdateValidation = [ body('date').optional().isISO8601().withMessage('date must be a valid ISO 8601 date'), body('experiment_description').optional().isString(), body('vitals').optional().isString(), body('treatment').optional().isString(), body('notes').optional().isString(), ]; // GET /api/daily-statuses?animalId= — list for animal router.get( '/', [query('animalId').optional().matches(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).withMessage('animalId must be a valid UUID')], validateRequest, async (req, res, next) => { try { const where = req.query.animalId ? { animal_id: req.query.animalId } : {}; const statuses = await prisma.dailyStatus.findMany({ where, orderBy: { date: 'desc' }, include: { animal: { select: { animal_name: true, animal_id_string: true } } }, }); res.json(statuses); } catch (err) { next(err); } } ); // GET /api/daily-statuses/:id — get one router.get('/:id', async (req, res, next) => { try { const status = await prisma.dailyStatus.findUnique({ where: { id: req.params.id }, include: { animal: true }, }); if (!status) return res.status(404).json({ error: 'Daily status not found' }); res.json(status); } catch (err) { next(err); } }); // POST /api/daily-statuses — create router.post('/', statusValidation, validateRequest, async (req, res, next) => { try { const { animal_id, date, experiment_description, vitals, treatment, notes } = req.body; const status = await prisma.dailyStatus.create({ data: { animal_id, date: new Date(date), experiment_description, vitals, treatment, notes, }, }); await prisma.auditLog.create({ data: { table_name: 'daily_statuses', record_id: status.id, action: 'CREATE', changes: { before: null, after: status }, }, }); res.status(201).json(status); } catch (err) { next(err); } }); // PUT /api/daily-statuses/:id — update router.put( '/:id', auditMiddleware('daily_statuses', prisma.dailyStatus), statusUpdateValidation, validateRequest, async (req, res, next) => { try { const { date, experiment_description, vitals, treatment, notes } = req.body; const data = {}; if (date !== undefined) data.date = new Date(date); if (experiment_description !== undefined) data.experiment_description = experiment_description; if (vitals !== undefined) data.vitals = vitals; if (treatment !== undefined) data.treatment = treatment; if (notes !== undefined) data.notes = notes; const status = await prisma.dailyStatus.update({ where: { id: req.params.id }, data, }); res.json(status); } catch (err) { next(err); } } ); // DELETE /api/daily-statuses/:id — delete router.delete( '/:id', auditMiddleware('daily_statuses', prisma.dailyStatus), async (req, res, next) => { try { await prisma.dailyStatus.delete({ where: { id: req.params.id } }); res.status(204).send(); } catch (err) { next(err); } } ); module.exports = router;