import {FastifyInstance} from 'fastify'; import {ClientController} from '../controllers/ClientController'; import {ClientService} from '../services/ClientService'; import {ClientRepository} from '../repositories/ClientRepository'; import {authenticate} from '../middleware/auth'; const clientRepository = new ClientRepository(); const clientService = new ClientService(clientRepository); const clientController = new ClientController(clientService); export async function clientRoutes(fastify: FastifyInstance) { // Apply authentication to all routes fastify.addHook('onRequest', authenticate); /** * Get all clients */ fastify.get( '/', { schema: { description: 'Get all clients for the authenticated user', tags: ['Clients'], security: [{bearerAuth: []}], querystring: { type: 'object', properties: { withStats: { type: 'string', enum: ['true', 'false'], description: 'Include invoice statistics for each client' } } }, response: { 200: { description: 'List of clients', type: 'object', properties: { clients: { type: 'array', items: { type: 'object', properties: { id: {type: 'string'}, name: {type: 'string'}, email: {type: 'string'}, phone: {type: 'string', nullable: true}, address: {type: 'string', nullable: true}, notes: {type: 'string', nullable: true}, createdAt: {type: 'string'}, updatedAt: {type: 'string'} } } } } } } } }, clientController.getAll.bind(clientController) ); /** * Get total revenue */ fastify.get( '/revenue/total', { schema: { description: 'Get total revenue from all paid client invoices', tags: ['Clients'], security: [{bearerAuth: []}], response: { 200: { description: 'Total revenue', type: 'object', properties: { totalRevenue: {type: 'number'} } } } } }, clientController.getTotalRevenue.bind(clientController) ); /** * Get single client */ fastify.get( '/:id', { schema: { description: 'Get a single client by ID', tags: ['Clients'], security: [{bearerAuth: []}], params: { type: 'object', properties: { id: {type: 'string'} } }, response: { 200: { description: 'Client details', type: 'object', properties: { client: { type: 'object', properties: { id: {type: 'string'}, name: {type: 'string'}, email: {type: 'string'}, phone: {type: 'string', nullable: true}, address: {type: 'string', nullable: true}, notes: {type: 'string', nullable: true}, createdAt: {type: 'string'}, updatedAt: {type: 'string'} } } } } } } }, clientController.getOne.bind(clientController) ); /** * Create client */ fastify.post( '/', { schema: { description: 'Create a new client', tags: ['Clients'], security: [{bearerAuth: []}], body: { type: 'object', required: ['name', 'email'], properties: { name: {type: 'string', minLength: 1, maxLength: 255}, email: {type: 'string', format: 'email'}, phone: {type: 'string', maxLength: 50}, address: {type: 'string'}, notes: {type: 'string'} } }, response: { 201: { description: 'Client created successfully', type: 'object', properties: { client: {type: 'object'} } } } } }, clientController.create.bind(clientController) ); /** * Update client */ fastify.put( '/:id', { schema: { description: 'Update a client', tags: ['Clients'], security: [{bearerAuth: []}], params: { type: 'object', properties: { id: {type: 'string'} } }, body: { type: 'object', properties: { name: {type: 'string', minLength: 1, maxLength: 255}, email: {type: 'string', format: 'email'}, phone: {type: 'string', maxLength: 50}, address: {type: 'string'}, notes: {type: 'string'} } }, response: { 200: { description: 'Client updated successfully', type: 'object', properties: { client: {type: 'object'} } } } } }, clientController.update.bind(clientController) ); /** * Delete client */ fastify.delete( '/:id', { schema: { description: 'Delete a client', tags: ['Clients'], security: [{bearerAuth: []}], params: { type: 'object', properties: { id: {type: 'string'} } }, response: { 204: { description: 'Client deleted successfully', type: 'null' } } } }, clientController.delete.bind(clientController) ); }