diff options
Diffstat (limited to 'api/src/modules/recurring-expenses/recurring-expenses.routes.ts')
| -rw-r--r-- | api/src/modules/recurring-expenses/recurring-expenses.routes.ts | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/api/src/modules/recurring-expenses/recurring-expenses.routes.ts b/api/src/modules/recurring-expenses/recurring-expenses.routes.ts new file mode 100644 index 0000000..73594e8 --- /dev/null +++ b/api/src/modules/recurring-expenses/recurring-expenses.routes.ts @@ -0,0 +1,108 @@ +import type { FastifyPluginAsync } from 'fastify'; +import { ZodError } from 'zod'; +import { + createRecurringExpenseSchema, + recurringExpenseParamsSchema, + recurringExpenseUserParamsSchema, + updateRecurringExpenseSchema, +} from './recurring-expenses.schema'; +import * as recurringService from './recurring-expenses.service'; + +const recurringExpensesRoutes: FastifyPluginAsync = async (fastify) => { + /** GET /users/:userId/recurring-expenses — Lista todos os gastos recorrentes */ + fastify.get<{ Params: { userId: string } }>( + '/users/:userId/recurring-expenses', + async (request, reply) => { + const { userId } = recurringExpenseUserParamsSchema.parse(request.params); + const result = await recurringService.findRecurringExpensesByUser(userId); + return reply.send({ data: result }); + }, + ); + + /** GET /users/:userId/recurring-expenses/:id — Busca um gasto recorrente específico */ + fastify.get<{ Params: { userId: string; id: string } }>( + '/users/:userId/recurring-expenses/:id', + async (request, reply) => { + const { userId, id } = recurringExpenseParamsSchema.parse(request.params); + const expense = await recurringService.findRecurringExpenseById(userId, id); + + if (!expense) { + return reply.status(404).send({ error: 'Gasto recorrente não encontrado.' }); + } + return reply.send({ data: expense }); + }, + ); + + /** POST /users/:userId/recurring-expenses — Cadastra um novo gasto fixo */ + fastify.post<{ Params: { userId: string } }>( + '/users/:userId/recurring-expenses', + async (request, reply) => { + try { + const { userId } = recurringExpenseUserParamsSchema.parse(request.params); + const body = createRecurringExpenseSchema.parse(request.body); + const expense = await recurringService.createRecurringExpense(userId, body); + return reply.status(201).send({ data: expense }); + } catch (err) { + if (err instanceof ZodError) { + return reply.status(400).send({ error: 'Dados inválidos.', details: err.errors }); + } + throw err; + } + }, + ); + + /** PUT /users/:userId/recurring-expenses/:id — Atualiza um gasto recorrente */ + fastify.put<{ Params: { userId: string; id: string } }>( + '/users/:userId/recurring-expenses/:id', + async (request, reply) => { + try { + const { userId, id } = recurringExpenseParamsSchema.parse(request.params); + const body = updateRecurringExpenseSchema.parse(request.body); + const expense = await recurringService.updateRecurringExpense(userId, id, body); + + if (!expense) { + return reply.status(404).send({ error: 'Gasto recorrente não encontrado.' }); + } + return reply.send({ data: expense }); + } catch (err) { + if (err instanceof ZodError) { + return reply.status(400).send({ error: 'Dados inválidos.', details: err.errors }); + } + throw err; + } + }, + ); + + /** + * PATCH /users/:userId/recurring-expenses/:id/toggle + * Ativa ou desativa um gasto recorrente sem precisar deletar. + */ + fastify.patch<{ Params: { userId: string; id: string } }>( + '/users/:userId/recurring-expenses/:id/toggle', + async (request, reply) => { + const { userId, id } = recurringExpenseParamsSchema.parse(request.params); + const expense = await recurringService.toggleRecurringExpense(userId, id); + + if (!expense) { + return reply.status(404).send({ error: 'Gasto recorrente não encontrado.' }); + } + return reply.send({ data: expense }); + }, + ); + + /** DELETE /users/:userId/recurring-expenses/:id — Remove um gasto recorrente */ + fastify.delete<{ Params: { userId: string; id: string } }>( + '/users/:userId/recurring-expenses/:id', + async (request, reply) => { + const { userId, id } = recurringExpenseParamsSchema.parse(request.params); + const deleted = await recurringService.deleteRecurringExpense(userId, id); + + if (!deleted) { + return reply.status(404).send({ error: 'Gasto recorrente não encontrado.' }); + } + return reply.status(200).send({ data: deleted, message: 'Gasto recorrente removido com sucesso.' }); + }, + ); +}; + +export default recurringExpensesRoutes; |