Budgets Module
What this module solves
Section titled “What this module solves”Defines budget envelopes over time, connects budgets to wallets/categories, and supports collaborative budget memberships.
Endpoints
Section titled “Endpoints”POST /api/v1/budgetsGET /api/v1/budgetsGET /api/v1/budgets/:budgetIdPATCH /api/v1/budgets/:budgetIdDELETE /api/v1/budgets/:budgetIdPOST /api/v1/budgets/:budgetId/sharePATCH /api/v1/budgets/:budgetId/members/:memberIdDELETE /api/v1/budgets/:budgetId/members/:memberId
Validation rules
Section titled “Validation rules”- Create/update require valid period/currency/limit shape (
limit > 0). - Share flow validates member email, optional role/share fields.
- Invite response accepts only
acceptedorrejected. - Schema file:
backend/src/Shared/Schemas/budgetSchema.ts.
Internal flow
Section titled “Internal flow”| Route | Controller | Use case | Repository / Service chain | Route file trace |
|---|---|---|---|---|
POST /budgets | BudgetController.create | CreateBudgetImpl | BudgetRepositoryImpl, CategoryRepositoryImpl, WalletRepositoryImpl | backend/src/Presentation/Routes/BudgetRoutes.ts |
GET /budgets | BudgetController.list | ListBudgetsImpl | BudgetRepositoryImpl | backend/src/Presentation/Routes/BudgetRoutes.ts |
GET /budgets/:budgetId | BudgetController.getOne | GetBudgetImpl | BudgetRepositoryImpl | backend/src/Presentation/Routes/BudgetRoutes.ts |
PATCH /budgets/:budgetId | BudgetController.update | UpdateBudgetImpl | BudgetRepositoryImpl | backend/src/Presentation/Routes/BudgetRoutes.ts |
DELETE /budgets/:budgetId | BudgetController.delete | DeleteBudgetImpl | BudgetRepositoryImpl | backend/src/Presentation/Routes/BudgetRoutes.ts |
POST /budgets/:budgetId/share | BudgetController.share | ShareBudgetImpl | BudgetRepositoryImpl, UserRepositoryImpl | backend/src/Presentation/Routes/BudgetRoutes.ts |
PATCH /budgets/:budgetId/members/:memberId | BudgetController.respondInvite | RespondBudgetInviteImpl | BudgetRepositoryImpl | backend/src/Presentation/Routes/BudgetRoutes.ts |
DELETE /budgets/:budgetId/members/:memberId | BudgetController.removeMember | RemoveBudgetMemberImpl | BudgetRepositoryImpl | backend/src/Presentation/Routes/BudgetRoutes.ts |
Controller: backend/src/Presentation/Controllers/BudgetController.ts.
Common errors
Section titled “Common errors”BUDGET_NOT_FOUND(404).BUDGET_ALREADY_EXISTS(409).BUDGET_MEMBER_ALREADY_EXISTS(409).INSUFFICIENT_PERMISSIONS(403).INVALID_BUDGET_PERIOD/INVALID_BUDGET_TIMEFRAME(400).
Testing notes
Section titled “Testing notes”- E2E files:
backend/src/tests/e2e/budget/budget-crud.e2e.test.tsbackend/src/tests/e2e/budget/budget-sharing.e2e.test.tsbackend/src/tests/e2e/budget/budget-allocation.e2e.test.ts
- Unit example:
backend/src/tests/unit/share-budget-impl.test.ts.
Quick snippets
Section titled “Quick snippets”1) cURL request example
Section titled “1) cURL request example”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"] }'2) Success JSON response example
Section titled “2) Success JSON response example”{ "code": "BUDGET_CREATED", "message": "Budget created successfully", "budget": { "id": "bdg_123", "name": "March Budget", "currency": "USD", "limit": 1200, "period": "monthly", "ownerId": "usr_123" }}3) Common error JSON response example
Section titled “3) Common error JSON response example”{ "code": "INSUFFICIENT_PERMISSIONS", "message": "You do not have permission to perform this action", "error": "You do not have permission to perform this action"}4) Tiny internal trace snippet
Section titled “4) Tiny internal trace snippet”// BudgetController.createconst userId = req.user?.userId ?? req.userId;const budget = await createBudget.execute(req.body, userId);
return res.status(201).json({ budget, ...buildSuccessResponse(SuccessCodes.BUDGET_CREATED),});