From c0b8a942100212639705801b83b682fd4de520ae Mon Sep 17 00:00:00 2001 From: BOHA Date: Mon, 23 Mar 2026 09:11:04 +0100 Subject: [PATCH] fix: resolve TypeScript compilation errors from service extraction Co-Authored-By: Claude Opus 4.6 (1M context) --- src/routes/admin/attendance.ts | 24 ++++++++++++------------ src/routes/admin/company-settings.ts | 3 ++- src/routes/admin/orders.ts | 12 ++++++------ src/routes/admin/projects.ts | 2 +- src/routes/admin/users.ts | 12 ++++++++---- src/schemas/common.ts | 6 +++--- src/services/orders.service.ts | 2 +- src/services/projects.service.ts | 2 +- 8 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/routes/admin/attendance.ts b/src/routes/admin/attendance.ts index b15f831..e432e86 100644 --- a/src/routes/admin/attendance.ts +++ b/src/routes/admin/attendance.ts @@ -34,7 +34,7 @@ export default async function attendanceRoutes(fastify: FastifyInstance): Promis const body = parsed.data; const result = await attendanceService.saveNotes(authData.userId, body.notes ? String(body.notes) : null); - if ('error' in result) return error(reply, result.error, 400); + if ('error' in result) return error(reply, result.error!, 400); return success(reply, null, 200, 'Poznámka uložena'); }); @@ -46,7 +46,7 @@ export default async function attendanceRoutes(fastify: FastifyInstance): Promis const body = parsed.data; const result = await attendanceService.updateAddress(authData.userId, body.address ?? null, body.punch_action); - if ('error' in result) return error(reply, result.error, 404); + if ('error' in result) return error(reply, result.error!, 404); return success(reply, null, 200, 'Adresa aktualizována'); }); @@ -59,7 +59,7 @@ export default async function attendanceRoutes(fastify: FastifyInstance): Promis const newProjectId = body.project_id ? Number(body.project_id) : null; const result = await attendanceService.switchProject(authData.userId, newProjectId); - if ('error' in result) return error(reply, result.error, 400); + if ('error' in result) return error(reply, result.error!, 400); return success(reply, null, 200, 'Projekt přepnut'); }); @@ -169,7 +169,7 @@ export default async function attendanceRoutes(fastify: FastifyInstance): Promis sick_used: balBody.sick_used, }); - if ('error' in result) return error(reply, result.error, 400); + if ('error' in result) return error(reply, result.error!, 400); await logAudit({ request, authData, action: 'update', entityType: 'leave_balance', @@ -220,10 +220,10 @@ export default async function attendanceRoutes(fastify: FastifyInstance): Promis date_to: leaveBody.date_to, leave_type: leaveBody.leave_type, leave_hours: leaveBody.leave_hours, - notes: leaveBody.notes, + notes: leaveBody.notes ?? undefined, }, authData.userId); - if ('error' in result) return error(reply, result.error, 400); + if ('error' in result) return error(reply, result.error!, 400); return success(reply, { created: result.created }, 200, result.message!); } @@ -241,7 +241,7 @@ export default async function attendanceRoutes(fastify: FastifyInstance): Promis address: punchBody.address, }); - if ('error' in result) return error(reply, result.error, 400); + if ('error' in result) return error(reply, result.error!, 400); await logAudit({ request, authData, action: result.auditAction, entityType: 'attendance', @@ -303,14 +303,14 @@ export default async function attendanceRoutes(fastify: FastifyInstance): Promis departure_time: body.departure_time, break_start: body.break_start, break_end: body.break_end, - notes: body.notes, - project_id: body.project_id, + notes: body.notes ?? undefined, + project_id: body.project_id != null ? Number(body.project_id) : (body.project_id as number | null | undefined), leave_type: body.leave_type, - leave_hours: body.leave_hours, + leave_hours: body.leave_hours != null ? Number(body.leave_hours) : (body.leave_hours as number | null | undefined), project_logs: body.project_logs, }, authData.userId, isAdmin); - if ('error' in result) return error(reply, result.error, result.status!); + if ('error' in result) return error(reply, result.error!, result.status!); await logAudit({ request, @@ -330,7 +330,7 @@ export default async function attendanceRoutes(fastify: FastifyInstance): Promis if (id === null) return; const result = await attendanceService.deleteAttendance(id); - if ('error' in result) return error(reply, result.error, 404); + if ('error' in result) return error(reply, result.error!, 404); await logAudit({ request, diff --git a/src/routes/admin/company-settings.ts b/src/routes/admin/company-settings.ts index c91be02..a060d56 100644 --- a/src/routes/admin/company-settings.ts +++ b/src/routes/admin/company-settings.ts @@ -153,8 +153,9 @@ export default async function companySettingsRoutes(fastify: FastifyInstance): P const data: Record = { modified_at: new Date() }; const strFields = ['company_name', 'street', 'city', 'postal_code', 'country', 'company_id', 'vat_id', 'quotation_prefix', 'default_currency', 'order_type_code', 'invoice_type_code']; + const bodyRec = body as Record; for (const f of strFields) { - if (body[f] !== undefined) data[f] = body[f] ? String(body[f]) : null; + if (bodyRec[f] !== undefined) data[f] = bodyRec[f] ? String(bodyRec[f]) : null; } if (body.default_vat_rate !== undefined) data.default_vat_rate = Number(body.default_vat_rate); if (body.require_2fa !== undefined) data.require_2fa = body.require_2fa === true || body.require_2fa === 1 || body.require_2fa === '1'; diff --git a/src/routes/admin/orders.ts b/src/routes/admin/orders.ts index e5ed63f..f0a7beb 100644 --- a/src/routes/admin/orders.ts +++ b/src/routes/admin/orders.ts @@ -89,7 +89,7 @@ export default async function ordersRoutes(fastify: FastifyInstance): Promise(schema: ZodSchema, body: unknown): { data: T } | { error: string } { try { return { data: schema.parse(body) }; } catch (e) { - if (e instanceof ZodError) { - return { error: e.errors.map(err => err.message).join(', ') }; + if (e instanceof z.ZodError) { + return { error: e.issues.map((err: z.ZodIssue) => err.message).join(', ') }; } return { error: 'Neplatný požadavek' }; } diff --git a/src/services/orders.service.ts b/src/services/orders.service.ts index 365e3c0..4286f52 100644 --- a/src/services/orders.service.ts +++ b/src/services/orders.service.ts @@ -1,7 +1,7 @@ import prisma from '../config/database'; import { generateSharedNumber } from './numbering.service'; -interface OrderItemInput { description?: string; item_description?: string; quantity?: number; unit?: string; unit_price?: number; is_included_in_total?: boolean; position?: number } +interface OrderItemInput { description?: string | null; item_description?: string | null; quantity?: number; unit?: string | null; unit_price?: number; is_included_in_total?: boolean; position?: number } interface OrderSectionInput { title?: string; title_cz?: string; content?: string; position?: number } // Status transition rules matching PHP diff --git a/src/services/projects.service.ts b/src/services/projects.service.ts index 436fb80..92791b7 100644 --- a/src/services/projects.service.ts +++ b/src/services/projects.service.ts @@ -39,7 +39,7 @@ export async function listProjects(params: ListProjectsParams) { ...p, customer_name: p.customers?.name || null, responsible_user_name: p.users ? `${p.users.first_name} ${p.users.last_name}`.trim() : null, - order_number: p.orders?.[0]?.order_number || null, + order_number: (p.orders as any)?.order_number || null, })); return { data: enriched, total, page, limit };