Skip to content

Budgets Module

Defines budget envelopes over time, connects budgets to wallets/categories, and supports collaborative budget memberships.

  • POST /api/v1/budgets
  • GET /api/v1/budgets
  • GET /api/v1/budgets/:budgetId
  • PATCH /api/v1/budgets/:budgetId
  • DELETE /api/v1/budgets/:budgetId
  • POST /api/v1/budgets/:budgetId/share
  • PATCH /api/v1/budgets/:budgetId/members/:memberId
  • DELETE /api/v1/budgets/:budgetId/members/:memberId
  • Create/update require valid period/currency/limit shape (limit > 0).
  • Share flow validates member email, optional role/share fields.
  • Invite response accepts only accepted or rejected.
  • Schema file: backend/src/Shared/Schemas/budgetSchema.ts.
RouteControllerUse caseRepository / Service chainRoute file trace
POST /budgetsBudgetController.createCreateBudgetImplBudgetRepositoryImpl, CategoryRepositoryImpl, WalletRepositoryImplbackend/src/Presentation/Routes/BudgetRoutes.ts
GET /budgetsBudgetController.listListBudgetsImplBudgetRepositoryImplbackend/src/Presentation/Routes/BudgetRoutes.ts
GET /budgets/:budgetIdBudgetController.getOneGetBudgetImplBudgetRepositoryImplbackend/src/Presentation/Routes/BudgetRoutes.ts
PATCH /budgets/:budgetIdBudgetController.updateUpdateBudgetImplBudgetRepositoryImplbackend/src/Presentation/Routes/BudgetRoutes.ts
DELETE /budgets/:budgetIdBudgetController.deleteDeleteBudgetImplBudgetRepositoryImplbackend/src/Presentation/Routes/BudgetRoutes.ts
POST /budgets/:budgetId/shareBudgetController.shareShareBudgetImplBudgetRepositoryImpl, UserRepositoryImplbackend/src/Presentation/Routes/BudgetRoutes.ts
PATCH /budgets/:budgetId/members/:memberIdBudgetController.respondInviteRespondBudgetInviteImplBudgetRepositoryImplbackend/src/Presentation/Routes/BudgetRoutes.ts
DELETE /budgets/:budgetId/members/:memberIdBudgetController.removeMemberRemoveBudgetMemberImplBudgetRepositoryImplbackend/src/Presentation/Routes/BudgetRoutes.ts

Controller: backend/src/Presentation/Controllers/BudgetController.ts.

  • BUDGET_NOT_FOUND (404).
  • BUDGET_ALREADY_EXISTS (409).
  • BUDGET_MEMBER_ALREADY_EXISTS (409).
  • INSUFFICIENT_PERMISSIONS (403).
  • INVALID_BUDGET_PERIOD / INVALID_BUDGET_TIMEFRAME (400).
  • E2E files:
    • backend/src/tests/e2e/budget/budget-crud.e2e.test.ts
    • backend/src/tests/e2e/budget/budget-sharing.e2e.test.ts
    • backend/src/tests/e2e/budget/budget-allocation.e2e.test.ts
  • Unit example: backend/src/tests/unit/share-budget-impl.test.ts.
Terminal window
curl -X POST "https://budgeti-backend.johandercampos.com/api/v1/budgets" \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"name": "March Budget",
"currency": "USD",
"limit": 1200,
"period": "monthly",
"startDate": "2026-03-01",
"walletId": "wlt_123",
"categoryIds": ["cat_food"]
}'
{
"code": "BUDGET_CREATED",
"message": "Budget created successfully",
"budget": {
"id": "bdg_123",
"name": "March Budget",
"currency": "USD",
"limit": 1200,
"period": "monthly",
"ownerId": "usr_123"
}
}
{
"code": "INSUFFICIENT_PERMISSIONS",
"message": "You do not have permission to perform this action",
"error": "You do not have permission to perform this action"
}
// BudgetController.create
const userId = req.user?.userId ?? req.userId;
const budget = await createBudget.execute(req.body, userId);
return res.status(201).json({
budget,
...buildSuccessResponse(SuccessCodes.BUDGET_CREATED),
});