feat: Team leader role permissions, certificate generation, and bug fixes

- Add team_leader access to /admin/users endpoint for user list viewing
- Add PDF certificate generation for AI Kurzy with Puppeteer
- Add certificate assets (background, signatures)
- Add getPrilohaById and download endpoint for attachments
- Fix time tracking service permissions for team_leader
- Fix timesheet controller/service permissions for team_leader
- Fix calendar badge to include reminders in count
- Add lastSeen to message service for online indicator

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
richardtekula
2026-01-29 10:58:42 +01:00
parent a4a81ef88e
commit 225936e64a
18 changed files with 1229 additions and 54 deletions

View File

@@ -1,7 +1,7 @@
import express from 'express';
import * as adminController from '../controllers/admin.controller.js';
import { authenticate } from '../middlewares/auth/authMiddleware.js';
import { requireAdmin } from '../middlewares/auth/roleMiddleware.js';
import { requireAdmin, requireTeamLeaderOrAdmin } from '../middlewares/auth/roleMiddleware.js';
import { validateBody, validateParams } from '../middlewares/security/validateInput.js';
import { createUserSchema, changeRoleSchema } from '../validators/auth.validators.js';
import { z } from 'zod';
@@ -9,13 +9,15 @@ import { z } from 'zod';
const router = express.Router();
/**
* All admin routes require authentication and admin role
* All admin routes require authentication
*/
router.use(authenticate);
router.use(requireAdmin);
// Zoznam všetkých userov (admin only)
router.get('/users', adminController.getAllUsers);
// Zoznam všetkých userov (admin + team_leader)
router.get('/users', requireTeamLeaderOrAdmin, adminController.getAllUsers);
// All other routes require admin role
router.use(requireAdmin);
/**
* User management
@@ -46,7 +48,7 @@ router.patch(
router.patch(
'/users/:userId/role',
validateParams(z.object({ userId: z.string().uuid() })),
validateBody(z.object({ role: z.enum(['admin', 'member']) })),
validateBody(z.object({ role: z.enum(['admin', 'team_leader', 'member']) })),
adminController.changeUserRole
);

View File

@@ -160,4 +160,18 @@ router.delete(
aiKurzyController.deletePriloha
);
router.get(
'/prilohy/:prilohaId/download',
validateParams(prilohaIdSchema),
aiKurzyController.downloadPriloha
);
// ==================== CERTIFICATE ====================
router.post(
'/registracie/:registraciaId/certificate',
validateParams(registraciaIdSchema),
aiKurzyController.generateCertificate
);
export default router;