From 4629f1903b6fcdc628d8e7c6155a237fddc808b7 Mon Sep 17 00:00:00 2001 From: richardtekula Date: Wed, 28 Jan 2026 07:22:33 +0100 Subject: [PATCH] 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 --- src/routes/ai-kurzy.routes.js | 87 +++++---------------------- src/routes/service.routes.js | 29 +++------ src/validators/ai-kurzy.validators.js | 72 ++++++++++++++++++++++ src/validators/service.validators.js | 22 +++++++ 4 files changed, 115 insertions(+), 95 deletions(-) create mode 100644 src/validators/ai-kurzy.validators.js create mode 100644 src/validators/service.validators.js diff --git a/src/routes/ai-kurzy.routes.js b/src/routes/ai-kurzy.routes.js index cd90bfb..389e15c 100644 --- a/src/routes/ai-kurzy.routes.js +++ b/src/routes/ai-kurzy.routes.js @@ -4,8 +4,21 @@ import * as aiKurzyController from '../controllers/ai-kurzy.controller.js'; import { authenticate } from '../middlewares/auth/authMiddleware.js'; import { requireAdmin } from '../middlewares/auth/roleMiddleware.js'; import { validateBody, validateParams, validateQuery } from '../middlewares/security/validateInput.js'; -import { z } from 'zod'; 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(); @@ -16,69 +29,6 @@ const upload = createUpload({ 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 router.use(authenticate); router.use(requireAdmin); @@ -182,11 +132,6 @@ router.delete( router.get('/table', aiKurzyController.getCombinedTable); -const updateFieldSchema = z.object({ - field: z.string(), - value: z.any(), -}); - router.patch( '/table/:registraciaId/field', validateParams(registraciaIdSchema), @@ -196,10 +141,6 @@ router.patch( // ==================== PRILOHY (Documents) ==================== -const prilohaIdSchema = z.object({ - prilohaId: z.string().regex(/^\d+$/), -}); - router.get( '/registracie/:registraciaId/prilohy', validateParams(registraciaIdSchema), diff --git a/src/routes/service.routes.js b/src/routes/service.routes.js index 74abaa7..5fcdc9c 100644 --- a/src/routes/service.routes.js +++ b/src/routes/service.routes.js @@ -6,34 +6,19 @@ import { authenticate } from '../middlewares/auth/authMiddleware.js'; import { requireAdmin } from '../middlewares/auth/roleMiddleware.js'; import { validateBody, validateParams } from '../middlewares/security/validateInput.js'; import { createServiceSchema, updateServiceSchema } from '../validators/crm.validators.js'; -import { z } from 'zod'; import { createUpload } from '../config/upload.js'; +import { + serviceIdSchema, + folderIdSchema, + folderDocumentIdSchema, + createFolderSchema, + updateFolderSchema, +} from '../validators/service.validators.js'; const router = express.Router(); 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 router.use(authenticate); diff --git a/src/validators/ai-kurzy.validators.js b/src/validators/ai-kurzy.validators.js new file mode 100644 index 0000000..209cd05 --- /dev/null +++ b/src/validators/ai-kurzy.validators.js @@ -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+$/), +}); diff --git a/src/validators/service.validators.js b/src/validators/service.validators.js new file mode 100644 index 0000000..d4a8c64 --- /dev/null +++ b/src/validators/service.validators.js @@ -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), +});