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:
94
backend-api/src/controllers/DebtPaymentController.ts
Normal file
94
backend-api/src/controllers/DebtPaymentController.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import {FastifyRequest, FastifyReply} from 'fastify';
|
||||
import {DebtPaymentService} from '../services/DebtPaymentService';
|
||||
import {getUserId} from '../middleware/auth';
|
||||
import {z} from 'zod';
|
||||
|
||||
const createPaymentSchema = z.object({
|
||||
accountId: z.string().uuid(),
|
||||
amount: z.number().min(0.01),
|
||||
paymentDate: z.string().transform(str => new Date(str)),
|
||||
notes: z.string().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Controller for DebtPayment endpoints
|
||||
* Implements Single Responsibility Principle - handles only HTTP layer
|
||||
*/
|
||||
export class DebtPaymentController {
|
||||
constructor(private paymentService: DebtPaymentService) {}
|
||||
|
||||
/**
|
||||
* Create a new debt payment
|
||||
*/
|
||||
async create(request: FastifyRequest, reply: FastifyReply) {
|
||||
const userId = getUserId(request);
|
||||
const data = createPaymentSchema.parse(request.body);
|
||||
|
||||
const payment = await this.paymentService.create(userId, data);
|
||||
|
||||
return reply.status(201).send({payment});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all debt payments
|
||||
*/
|
||||
async getAll(request: FastifyRequest, reply: FastifyReply) {
|
||||
const userId = getUserId(request);
|
||||
const {accountId, startDate, endDate} = request.query as {
|
||||
accountId?: string;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
};
|
||||
|
||||
if (accountId) {
|
||||
const payments = await this.paymentService.getByAccount(accountId, userId);
|
||||
return reply.send({payments});
|
||||
}
|
||||
|
||||
if (startDate && endDate) {
|
||||
const payments = await this.paymentService.getByDateRange(
|
||||
userId,
|
||||
new Date(startDate),
|
||||
new Date(endDate)
|
||||
);
|
||||
return reply.send({payments});
|
||||
}
|
||||
|
||||
const payments = await this.paymentService.getAllByUser(userId);
|
||||
return reply.send({payments});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single debt payment
|
||||
*/
|
||||
async getOne(request: FastifyRequest, reply: FastifyReply) {
|
||||
const userId = getUserId(request);
|
||||
const {id} = request.params as {id: string};
|
||||
|
||||
const payment = await this.paymentService.getById(id, userId);
|
||||
|
||||
return reply.send({payment});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a debt payment
|
||||
*/
|
||||
async delete(request: FastifyRequest, reply: FastifyReply) {
|
||||
const userId = getUserId(request);
|
||||
const {id} = request.params as {id: string};
|
||||
|
||||
await this.paymentService.delete(id, userId);
|
||||
|
||||
return reply.status(204).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total payments
|
||||
*/
|
||||
async getTotalPayments(request: FastifyRequest, reply: FastifyReply) {
|
||||
const userId = getUserId(request);
|
||||
const totalPayments = await this.paymentService.getTotalPayments(userId);
|
||||
|
||||
return reply.send({totalPayments});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user