production hardening: future-date guard, per-day hour cap, totalHours in history, header cleanup
This commit is contained in:
@@ -7,6 +7,7 @@ const {
|
||||
copyWeekSchema,
|
||||
validateBody,
|
||||
validateQuery,
|
||||
validateIdParam,
|
||||
} = require('../utils/validation');
|
||||
|
||||
const router = express.Router();
|
||||
@@ -119,6 +120,18 @@ router.post('/', validateBody(createEntrySchema), async (req, res) => {
|
||||
return res.status(400).json({ error: 'Invalid or inactive homeowner' });
|
||||
}
|
||||
|
||||
// Check per-day hour cap (max 24h total across all entries)
|
||||
const existingHours = await req.prisma.timeEntry.aggregate({
|
||||
where: { userId: req.user.id, date: new Date(date + 'T00:00:00Z') },
|
||||
_sum: { hoursWorked: true },
|
||||
});
|
||||
const totalForDay = parseFloat(existingHours._sum.hoursWorked || 0) + hoursWorked;
|
||||
if (totalForDay > 24) {
|
||||
return res.status(400).json({
|
||||
error: `Total hours for this day would be ${totalForDay.toFixed(1)}. Maximum is 24.`,
|
||||
});
|
||||
}
|
||||
|
||||
const entry = await req.prisma.timeEntry.create({
|
||||
data: {
|
||||
userId: req.user.id,
|
||||
@@ -151,7 +164,7 @@ router.post('/', validateBody(createEntrySchema), async (req, res) => {
|
||||
});
|
||||
|
||||
// ─────────────── PUT /api/entries/:id ───────────────
|
||||
router.put('/:id', validateBody(updateEntrySchema), async (req, res) => {
|
||||
router.put('/:id', validateIdParam, validateBody(updateEntrySchema), async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
@@ -230,7 +243,7 @@ router.put('/:id', validateBody(updateEntrySchema), async (req, res) => {
|
||||
});
|
||||
|
||||
// ─────────────── DELETE /api/entries/:id ───────────────
|
||||
router.delete('/:id', async (req, res) => {
|
||||
router.delete('/:id', validateIdParam, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user