/** * @ai-summary Fastify route handlers for ownership costs API * @ai-context HTTP request/response handling with Fastify reply methods */ import { FastifyRequest, FastifyReply } from 'fastify'; import { OwnershipCostsService } from '../domain/ownership-costs.service'; import { pool } from '../../../core/config/database'; import { logger } from '../../../core/logging/logger'; import { OwnershipCostParams, VehicleParams, CreateOwnershipCostBody, UpdateOwnershipCostBody } from '../domain/ownership-costs.types'; export class OwnershipCostsController { private service: OwnershipCostsService; constructor() { this.service = new OwnershipCostsService(pool); } async create(request: FastifyRequest<{ Body: CreateOwnershipCostBody }>, reply: FastifyReply) { try { // eslint-disable-next-line @typescript-eslint/no-explicit-any const userId = (request as any).user.sub; const cost = await this.service.create(request.body, userId); return reply.code(201).send(cost); } catch (error: unknown) { const err = error as Error; // eslint-disable-next-line @typescript-eslint/no-explicit-any logger.error('Error creating ownership cost', { error: err, userId: (request as any).user?.sub }); if (err.message.includes('not found')) { return reply.code(404).send({ error: 'Not Found', message: err.message }); } if (err.message.includes('Unauthorized')) { return reply.code(403).send({ error: 'Forbidden', message: err.message }); } return reply.code(500).send({ error: 'Internal server error', message: 'Failed to create ownership cost' }); } } async getByVehicle(request: FastifyRequest<{ Params: VehicleParams }>, reply: FastifyReply) { try { // eslint-disable-next-line @typescript-eslint/no-explicit-any const userId = (request as any).user.sub; const { vehicleId } = request.params; const costs = await this.service.getByVehicleId(vehicleId, userId); return reply.code(200).send(costs); } catch (error: unknown) { const err = error as Error; // eslint-disable-next-line @typescript-eslint/no-explicit-any logger.error('Error listing ownership costs', { error: err, vehicleId: request.params.vehicleId, userId: (request as any).user?.sub }); if (err.message.includes('not found')) { return reply.code(404).send({ error: 'Not Found', message: err.message }); } if (err.message.includes('Unauthorized')) { return reply.code(403).send({ error: 'Forbidden', message: err.message }); } return reply.code(500).send({ error: 'Internal server error', message: 'Failed to get ownership costs' }); } } async getById(request: FastifyRequest<{ Params: OwnershipCostParams }>, reply: FastifyReply) { try { // eslint-disable-next-line @typescript-eslint/no-explicit-any const userId = (request as any).user.sub; const { id } = request.params; const cost = await this.service.getById(id, userId); return reply.code(200).send(cost); } catch (error: unknown) { const err = error as Error; // eslint-disable-next-line @typescript-eslint/no-explicit-any logger.error('Error getting ownership cost', { error: err, costId: request.params.id, userId: (request as any).user?.sub }); if (err.message.includes('not found')) { return reply.code(404).send({ error: 'Not Found', message: err.message }); } if (err.message.includes('Unauthorized')) { return reply.code(403).send({ error: 'Forbidden', message: err.message }); } return reply.code(500).send({ error: 'Internal server error', message: 'Failed to get ownership cost' }); } } async update(request: FastifyRequest<{ Params: OwnershipCostParams; Body: UpdateOwnershipCostBody }>, reply: FastifyReply) { try { // eslint-disable-next-line @typescript-eslint/no-explicit-any const userId = (request as any).user.sub; const { id } = request.params; const updatedCost = await this.service.update(id, request.body, userId); return reply.code(200).send(updatedCost); } catch (error: unknown) { const err = error as Error; // eslint-disable-next-line @typescript-eslint/no-explicit-any logger.error('Error updating ownership cost', { error: err, costId: request.params.id, userId: (request as any).user?.sub }); if (err.message.includes('not found')) { return reply.code(404).send({ error: 'Not Found', message: err.message }); } if (err.message.includes('Unauthorized')) { return reply.code(403).send({ error: 'Forbidden', message: err.message }); } return reply.code(500).send({ error: 'Internal server error', message: 'Failed to update ownership cost' }); } } async delete(request: FastifyRequest<{ Params: OwnershipCostParams }>, reply: FastifyReply) { try { // eslint-disable-next-line @typescript-eslint/no-explicit-any const userId = (request as any).user.sub; const { id } = request.params; await this.service.delete(id, userId); return reply.code(204).send(); } catch (error: unknown) { const err = error as Error; // eslint-disable-next-line @typescript-eslint/no-explicit-any logger.error('Error deleting ownership cost', { error: err, costId: request.params.id, userId: (request as any).user?.sub }); if (err.message.includes('not found')) { return reply.code(404).send({ error: 'Not Found', message: err.message }); } if (err.message.includes('Unauthorized')) { return reply.code(403).send({ error: 'Forbidden', message: err.message }); } return reply.code(500).send({ error: 'Internal server error', message: 'Failed to delete ownership cost' }); } } async getVehicleStats(request: FastifyRequest<{ Params: VehicleParams }>, reply: FastifyReply) { try { // eslint-disable-next-line @typescript-eslint/no-explicit-any const userId = (request as any).user.sub; const { vehicleId } = request.params; const stats = await this.service.getVehicleCostStats(vehicleId, userId); return reply.code(200).send(stats); } catch (error: unknown) { const err = error as Error; // eslint-disable-next-line @typescript-eslint/no-explicit-any logger.error('Error getting ownership cost stats', { error: err, vehicleId: request.params.vehicleId, userId: (request as any).user?.sub }); if (err.message.includes('not found')) { return reply.code(404).send({ error: 'Not Found', message: err.message }); } if (err.message.includes('Unauthorized')) { return reply.code(403).send({ error: 'Forbidden', message: err.message }); } return reply.code(500).send({ error: 'Internal server error', message: 'Failed to get ownership cost stats' }); } } }