refactor: Move inline Zod schemas from routes to validator files

Create ai-kurzy.validators.js and service.validators.js with schemas
extracted from their respective route files. Routes now import schemas
instead of defining them inline.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
richardtekula
2026-01-28 07:22:33 +01:00
parent f463467264
commit 4629f1903b
4 changed files with 115 additions and 95 deletions

View File

@@ -4,8 +4,21 @@ import * as aiKurzyController from '../controllers/ai-kurzy.controller.js';
import { authenticate } from '../middlewares/auth/authMiddleware.js'; import { authenticate } from '../middlewares/auth/authMiddleware.js';
import { requireAdmin } from '../middlewares/auth/roleMiddleware.js'; import { requireAdmin } from '../middlewares/auth/roleMiddleware.js';
import { validateBody, validateParams, validateQuery } from '../middlewares/security/validateInput.js'; import { validateBody, validateParams, validateQuery } from '../middlewares/security/validateInput.js';
import { z } from 'zod';
import { createUpload, ALLOWED_FILE_TYPES } from '../config/upload.js'; import { createUpload, ALLOWED_FILE_TYPES } from '../config/upload.js';
import {
kurzIdSchema,
ucastnikIdSchema,
registraciaIdSchema,
createKurzSchema,
updateKurzSchema,
createUcastnikSchema,
updateUcastnikSchema,
createRegistraciaSchema,
updateRegistraciaSchema,
registracieQuerySchema,
updateFieldSchema,
prilohaIdSchema,
} from '../validators/ai-kurzy.validators.js';
const router = express.Router(); const router = express.Router();
@@ -16,69 +29,6 @@ const upload = createUpload({
diskPath: path.join(process.cwd(), 'uploads', 'ai-kurzy'), diskPath: path.join(process.cwd(), 'uploads', 'ai-kurzy'),
}); });
// Validation schemas
const kurzIdSchema = z.object({
kurzId: z.string().regex(/^\d+$/),
});
const ucastnikIdSchema = z.object({
ucastnikId: z.string().regex(/^\d+$/),
});
const registraciaIdSchema = z.object({
registraciaId: z.string().regex(/^\d+$/),
});
const createKurzSchema = z.object({
nazov: z.string().min(1).max(255),
typKurzu: z.string().min(1).max(100),
popis: z.string().optional().nullable(),
cena: z.string().or(z.number()),
maxKapacita: z.number().int().positive().optional().nullable(),
aktivny: z.boolean().optional(),
farba: z.string().max(20).optional().nullable(),
});
const updateKurzSchema = createKurzSchema.partial();
const createUcastnikSchema = z.object({
titul: z.string().max(50).optional().nullable(),
meno: z.string().min(1).max(100),
priezvisko: z.string().min(1).max(100),
email: z.string().email().max(255),
telefon: z.string().max(50).optional().nullable(),
firma: z.string().max(255).optional().nullable(),
firmaIco: z.string().max(20).optional().nullable(),
firmaDic: z.string().max(20).optional().nullable(),
firmaIcDph: z.string().max(25).optional().nullable(),
firmaSidlo: z.string().optional().nullable(),
mesto: z.string().max(100).optional().nullable(),
ulica: z.string().max(255).optional().nullable(),
psc: z.string().max(10).optional().nullable(),
});
const updateUcastnikSchema = createUcastnikSchema.partial();
const createRegistraciaSchema = z.object({
kurzId: z.number().int().positive(),
ucastnikId: z.number().int().positive(),
datumOd: z.string().optional().nullable(),
datumDo: z.string().optional().nullable(),
formaKurzu: z.enum(['prezencne', 'online', 'hybridne']).optional(),
pocetUcastnikov: z.number().int().positive().optional(),
fakturaCislo: z.string().max(100).optional().nullable(),
fakturaVystavena: z.boolean().optional(),
zaplatene: z.boolean().optional(),
stav: z.enum(['potencialny', 'registrovany', 'potvrdeny', 'absolvoval', 'zruseny']).optional(),
poznamka: z.string().optional().nullable(),
});
const updateRegistraciaSchema = createRegistraciaSchema.partial();
const registracieQuerySchema = z.object({
kurzId: z.string().regex(/^\d+$/).optional(),
});
// All routes require authentication and admin role // All routes require authentication and admin role
router.use(authenticate); router.use(authenticate);
router.use(requireAdmin); router.use(requireAdmin);
@@ -182,11 +132,6 @@ router.delete(
router.get('/table', aiKurzyController.getCombinedTable); router.get('/table', aiKurzyController.getCombinedTable);
const updateFieldSchema = z.object({
field: z.string(),
value: z.any(),
});
router.patch( router.patch(
'/table/:registraciaId/field', '/table/:registraciaId/field',
validateParams(registraciaIdSchema), validateParams(registraciaIdSchema),
@@ -196,10 +141,6 @@ router.patch(
// ==================== PRILOHY (Documents) ==================== // ==================== PRILOHY (Documents) ====================
const prilohaIdSchema = z.object({
prilohaId: z.string().regex(/^\d+$/),
});
router.get( router.get(
'/registracie/:registraciaId/prilohy', '/registracie/:registraciaId/prilohy',
validateParams(registraciaIdSchema), validateParams(registraciaIdSchema),

View File

@@ -6,34 +6,19 @@ import { authenticate } from '../middlewares/auth/authMiddleware.js';
import { requireAdmin } from '../middlewares/auth/roleMiddleware.js'; import { requireAdmin } from '../middlewares/auth/roleMiddleware.js';
import { validateBody, validateParams } from '../middlewares/security/validateInput.js'; import { validateBody, validateParams } from '../middlewares/security/validateInput.js';
import { createServiceSchema, updateServiceSchema } from '../validators/crm.validators.js'; import { createServiceSchema, updateServiceSchema } from '../validators/crm.validators.js';
import { z } from 'zod';
import { createUpload } from '../config/upload.js'; import { createUpload } from '../config/upload.js';
import {
serviceIdSchema,
folderIdSchema,
folderDocumentIdSchema,
createFolderSchema,
updateFolderSchema,
} from '../validators/service.validators.js';
const router = express.Router(); const router = express.Router();
const upload = createUpload({ maxSizeMB: 50 }); const upload = createUpload({ maxSizeMB: 50 });
const serviceIdSchema = z.object({
serviceId: z.string().uuid(),
});
const folderIdSchema = z.object({
folderId: z.string().uuid(),
});
const folderDocumentIdSchema = z.object({
folderId: z.string().uuid(),
documentId: z.string().uuid(),
});
const createFolderSchema = z.object({
name: z.string().min(1).max(255),
});
const updateFolderSchema = z.object({
name: z.string().min(1).max(255),
});
// All service routes require authentication // All service routes require authentication
router.use(authenticate); router.use(authenticate);

View File

@@ -0,0 +1,72 @@
import { z } from 'zod';
export const kurzIdSchema = z.object({
kurzId: z.string().regex(/^\d+$/),
});
export const ucastnikIdSchema = z.object({
ucastnikId: z.string().regex(/^\d+$/),
});
export const registraciaIdSchema = z.object({
registraciaId: z.string().regex(/^\d+$/),
});
export const createKurzSchema = z.object({
nazov: z.string().min(1).max(255),
typKurzu: z.string().min(1).max(100),
popis: z.string().optional().nullable(),
cena: z.string().or(z.number()),
maxKapacita: z.number().int().positive().optional().nullable(),
aktivny: z.boolean().optional(),
farba: z.string().max(20).optional().nullable(),
});
export const updateKurzSchema = createKurzSchema.partial();
export const createUcastnikSchema = z.object({
titul: z.string().max(50).optional().nullable(),
meno: z.string().min(1).max(100),
priezvisko: z.string().min(1).max(100),
email: z.string().email().max(255),
telefon: z.string().max(50).optional().nullable(),
firma: z.string().max(255).optional().nullable(),
firmaIco: z.string().max(20).optional().nullable(),
firmaDic: z.string().max(20).optional().nullable(),
firmaIcDph: z.string().max(25).optional().nullable(),
firmaSidlo: z.string().optional().nullable(),
mesto: z.string().max(100).optional().nullable(),
ulica: z.string().max(255).optional().nullable(),
psc: z.string().max(10).optional().nullable(),
});
export const updateUcastnikSchema = createUcastnikSchema.partial();
export const createRegistraciaSchema = z.object({
kurzId: z.number().int().positive(),
ucastnikId: z.number().int().positive(),
datumOd: z.string().optional().nullable(),
datumDo: z.string().optional().nullable(),
formaKurzu: z.enum(['prezencne', 'online', 'hybridne']).optional(),
pocetUcastnikov: z.number().int().positive().optional(),
fakturaCislo: z.string().max(100).optional().nullable(),
fakturaVystavena: z.boolean().optional(),
zaplatene: z.boolean().optional(),
stav: z.enum(['potencialny', 'registrovany', 'potvrdeny', 'absolvoval', 'zruseny']).optional(),
poznamka: z.string().optional().nullable(),
});
export const updateRegistraciaSchema = createRegistraciaSchema.partial();
export const registracieQuerySchema = z.object({
kurzId: z.string().regex(/^\d+$/).optional(),
});
export const updateFieldSchema = z.object({
field: z.string(),
value: z.any(),
});
export const prilohaIdSchema = z.object({
prilohaId: z.string().regex(/^\d+$/),
});

View File

@@ -0,0 +1,22 @@
import { z } from 'zod';
export const serviceIdSchema = z.object({
serviceId: z.string().uuid(),
});
export const folderIdSchema = z.object({
folderId: z.string().uuid(),
});
export const folderDocumentIdSchema = z.object({
folderId: z.string().uuid(),
documentId: z.string().uuid(),
});
export const createFolderSchema = z.object({
name: z.string().min(1).max(255),
});
export const updateFolderSchema = z.object({
name: z.string().min(1).max(255),
});