import express from 'express'; import multer from 'multer'; import path from 'path'; import { fileURLToPath } from 'url'; import * as timesheetController from '../controllers/timesheet.controller.js'; import { authenticate } from '../middlewares/auth/authMiddleware.js'; import { requireAdmin } from '../middlewares/auth/roleMiddleware.js'; import { validateBody, validateParams } from '../middlewares/security/validateInput.js'; import { z } from 'zod'; import fs from 'fs/promises'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const router = express.Router(); // Create uploads directory if it doesn't exist const uploadsDir = path.join(process.cwd(), 'uploads', 'timesheets'); await fs.mkdir(uploadsDir, { recursive: true }); // Configure multer for file uploads - use memory storage first const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 10 * 1024 * 1024, // 10MB limit }, fileFilter: (req, file, cb) => { const allowedTypes = ['application/pdf', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel']; if (allowedTypes.includes(file.mimetype)) { cb(null, true); } else { cb(new Error('Neplatný typ súboru. Povolené sú iba PDF a Excel súbory.'), false); } } }); /** * All timesheet routes require authentication */ router.use(authenticate); /** * Upload timesheet * POST /api/timesheets/upload */ router.post( '/upload', upload.single('file'), validateBody(z.object({ year: z.string().regex(/^\d{4}$/, 'Rok musí byť 4-miestne číslo'), month: z.string().regex(/^([1-9]|1[0-2])$/, 'Mesiac musí byť číslo od 1 do 12'), userId: z.string().uuid().optional(), // Optional: admin can upload for other users })), timesheetController.uploadTimesheet ); /** * Get user's timesheets * GET /api/timesheets/my */ router.get('/my', timesheetController.getMyTimesheets); /** * Get all timesheets (admin only) * GET /api/timesheets/all */ router.get('/all', requireAdmin, timesheetController.getAllTimesheets); /** * Download timesheet * GET /api/timesheets/:timesheetId/download */ router.get( '/:timesheetId/download', validateParams(z.object({ timesheetId: z.string().uuid() })), timesheetController.downloadTimesheet ); /** * Delete timesheet * DELETE /api/timesheets/:timesheetId */ router.delete( '/:timesheetId', validateParams(z.object({ timesheetId: z.string().uuid() })), timesheetController.deleteTimesheet ); export default router;