Add backend API for personal finance management application
- Introduced a comprehensive backend API using TypeScript, Fastify, and PostgreSQL. - Added essential files including architecture documentation, environment configuration, and Docker setup. - Implemented RESTful routes for managing assets, liabilities, clients, invoices, and cashflow. - Established a robust database schema with Prisma for data management. - Integrated middleware for authentication and error handling. - Created service and repository layers to adhere to SOLID principles and clean architecture. - Included example environment variables for development, staging, and production setups.
This commit is contained in:
231
backend-api/src/routes/client.routes.ts
Normal file
231
backend-api/src/routes/client.routes.ts
Normal file
@@ -0,0 +1,231 @@
|
||||
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)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user