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:
263
backend-api/src/routes/liability.routes.ts
Normal file
263
backend-api/src/routes/liability.routes.ts
Normal file
@@ -0,0 +1,263 @@
|
||||
import {FastifyInstance} from 'fastify';
|
||||
import {LiabilityController} from '../controllers/LiabilityController';
|
||||
import {LiabilityService} from '../services/LiabilityService';
|
||||
import {LiabilityRepository} from '../repositories/LiabilityRepository';
|
||||
import {authenticate} from '../middleware/auth';
|
||||
|
||||
const liabilityRepository = new LiabilityRepository();
|
||||
const liabilityService = new LiabilityService(liabilityRepository);
|
||||
const liabilityController = new LiabilityController(liabilityService);
|
||||
|
||||
export async function liabilityRoutes(fastify: FastifyInstance) {
|
||||
// Apply authentication to all routes
|
||||
fastify.addHook('onRequest', authenticate);
|
||||
|
||||
/**
|
||||
* Get all liabilities
|
||||
*/
|
||||
fastify.get(
|
||||
'/',
|
||||
{
|
||||
schema: {
|
||||
description: 'Get all liabilities for the authenticated user',
|
||||
tags: ['Liabilities'],
|
||||
security: [{bearerAuth: []}],
|
||||
response: {
|
||||
200: {
|
||||
description: 'List of liabilities',
|
||||
type: 'object',
|
||||
properties: {
|
||||
liabilities: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {type: 'string'},
|
||||
name: {type: 'string'},
|
||||
type: {type: 'string'},
|
||||
currentBalance: {type: 'number'},
|
||||
interestRate: {type: 'number', nullable: true},
|
||||
minimumPayment: {type: 'number', nullable: true},
|
||||
dueDate: {type: 'string', nullable: true},
|
||||
creditor: {type: 'string', nullable: true},
|
||||
notes: {type: 'string', nullable: true},
|
||||
createdAt: {type: 'string'},
|
||||
updatedAt: {type: 'string'},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
liabilityController.getAll.bind(liabilityController)
|
||||
);
|
||||
|
||||
/**
|
||||
* Get total liability value
|
||||
*/
|
||||
fastify.get(
|
||||
'/total',
|
||||
{
|
||||
schema: {
|
||||
description: 'Get total value of all liabilities',
|
||||
tags: ['Liabilities'],
|
||||
security: [{bearerAuth: []}],
|
||||
response: {
|
||||
200: {
|
||||
description: 'Total liability value',
|
||||
type: 'object',
|
||||
properties: {
|
||||
totalValue: {type: 'number'},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
liabilityController.getTotalValue.bind(liabilityController)
|
||||
);
|
||||
|
||||
/**
|
||||
* Get liabilities by type
|
||||
*/
|
||||
fastify.get(
|
||||
'/by-type',
|
||||
{
|
||||
schema: {
|
||||
description: 'Get liabilities grouped by type',
|
||||
tags: ['Liabilities'],
|
||||
security: [{bearerAuth: []}],
|
||||
response: {
|
||||
200: {
|
||||
description: 'Liabilities grouped by type',
|
||||
type: 'object',
|
||||
properties: {
|
||||
liabilitiesByType: {
|
||||
type: 'object',
|
||||
additionalProperties: {
|
||||
type: 'array',
|
||||
items: {type: 'object'},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
liabilityController.getByType.bind(liabilityController)
|
||||
);
|
||||
|
||||
/**
|
||||
* Get single liability
|
||||
*/
|
||||
fastify.get(
|
||||
'/:id',
|
||||
{
|
||||
schema: {
|
||||
description: 'Get a single liability by ID',
|
||||
tags: ['Liabilities'],
|
||||
security: [{bearerAuth: []}],
|
||||
params: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {type: 'string'},
|
||||
},
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
description: 'Liability details',
|
||||
type: 'object',
|
||||
properties: {
|
||||
liability: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {type: 'string'},
|
||||
name: {type: 'string'},
|
||||
type: {type: 'string'},
|
||||
currentBalance: {type: 'number'},
|
||||
interestRate: {type: 'number', nullable: true},
|
||||
minimumPayment: {type: 'number', nullable: true},
|
||||
dueDate: {type: 'string', nullable: true},
|
||||
creditor: {type: 'string', nullable: true},
|
||||
notes: {type: 'string', nullable: true},
|
||||
createdAt: {type: 'string'},
|
||||
updatedAt: {type: 'string'},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
liabilityController.getOne.bind(liabilityController)
|
||||
);
|
||||
|
||||
/**
|
||||
* Create liability
|
||||
*/
|
||||
fastify.post(
|
||||
'/',
|
||||
{
|
||||
schema: {
|
||||
description: 'Create a new liability',
|
||||
tags: ['Liabilities'],
|
||||
security: [{bearerAuth: []}],
|
||||
body: {
|
||||
type: 'object',
|
||||
required: ['name', 'type', 'currentBalance'],
|
||||
properties: {
|
||||
name: {type: 'string', minLength: 1, maxLength: 255},
|
||||
type: {type: 'string'},
|
||||
currentBalance: {type: 'number', minimum: 0},
|
||||
interestRate: {type: 'number', minimum: 0, maximum: 100},
|
||||
minimumPayment: {type: 'number', minimum: 0},
|
||||
dueDate: {type: 'string', format: 'date-time'},
|
||||
creditor: {type: 'string', maxLength: 255},
|
||||
notes: {type: 'string'},
|
||||
},
|
||||
},
|
||||
response: {
|
||||
201: {
|
||||
description: 'Liability created successfully',
|
||||
type: 'object',
|
||||
properties: {
|
||||
liability: {type: 'object'},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
liabilityController.create.bind(liabilityController)
|
||||
);
|
||||
|
||||
/**
|
||||
* Update liability
|
||||
*/
|
||||
fastify.put(
|
||||
'/:id',
|
||||
{
|
||||
schema: {
|
||||
description: 'Update a liability',
|
||||
tags: ['Liabilities'],
|
||||
security: [{bearerAuth: []}],
|
||||
params: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {type: 'string'},
|
||||
},
|
||||
},
|
||||
body: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {type: 'string', minLength: 1, maxLength: 255},
|
||||
type: {type: 'string'},
|
||||
currentBalance: {type: 'number', minimum: 0},
|
||||
interestRate: {type: 'number', minimum: 0, maximum: 100},
|
||||
minimumPayment: {type: 'number', minimum: 0},
|
||||
dueDate: {type: 'string', format: 'date-time'},
|
||||
creditor: {type: 'string', maxLength: 255},
|
||||
notes: {type: 'string'},
|
||||
},
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
description: 'Liability updated successfully',
|
||||
type: 'object',
|
||||
properties: {
|
||||
liability: {type: 'object'},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
liabilityController.update.bind(liabilityController)
|
||||
);
|
||||
|
||||
/**
|
||||
* Delete liability
|
||||
*/
|
||||
fastify.delete(
|
||||
'/:id',
|
||||
{
|
||||
schema: {
|
||||
description: 'Delete a liability',
|
||||
tags: ['Liabilities'],
|
||||
security: [{bearerAuth: []}],
|
||||
params: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {type: 'string'},
|
||||
},
|
||||
},
|
||||
response: {
|
||||
204: {
|
||||
description: 'Liability deleted successfully',
|
||||
type: 'null',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
liabilityController.delete.bind(liabilityController)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user