Skip to content

Categories Module

Allows users to organize transactions with personal categories and keep analytics meaningful.

  • Canonical base: /api/v1/categories
    • POST /api/v1/categories
    • GET /api/v1/categories
    • PATCH /api/v1/categories/:categoryId
    • DELETE /api/v1/categories/:categoryId
  • Compatibility alias base: /api/v1/category (same handlers and behavior).
  • name is required, min 2 chars, max 10 chars.
  • Schema file: backend/src/Shared/Schemas/categorySchema.ts.
RouteControllerUse caseRepositoryRoute file trace
POST /categoriesCategoryController.createCreateCategoryImplCategoryRepositoryImplbackend/src/Presentation/Routes/CategoryRoutes.ts
GET /categoriesCategoryController.getGetUserCategoriesImplCategoryRepositoryImplbackend/src/Presentation/Routes/CategoryRoutes.ts
PATCH /categories/:categoryIdCategoryController.updateUpdateCategoryImplCategoryRepositoryImplbackend/src/Presentation/Routes/CategoryRoutes.ts
DELETE /categories/:categoryIdCategoryController.deleteDeleteCategoryImplCategoryRepositoryImplbackend/src/Presentation/Routes/CategoryRoutes.ts

Alias wiring (/category) lives in backend/src/Presentation/Routes/Index.ts.

  • CATEGORY_NAME_REQUIRED (400).
  • CATEGORY_ALREADY_EXISTS or CATEGORY_NAME_ALREADY_EXIST (409).
  • CATEGORY_ID_REQUIRED (400).
  • USER_NOT_AUTHENTICATED (401).
  • E2E file: backend/src/tests/e2e/category/category-crud.e2e.test.ts.
  • Unit example: backend/src/tests/unit/update-category-impl.test.ts.
Terminal window
curl -X POST "https://budgeti-backend.johandercampos.com/api/v1/categories" \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"name": "Food",
"walletId": "wlt_123"
}'
{
"code": "CATEGORY_CREATED",
"message": "Category created successfully",
"data": {
"id": "cat_123",
"name": "Food",
"userId": "usr_123",
"walletId": "wlt_123"
}
}
{
"code": "CATEGORY_NAME_REQUIRED",
"message": "Category name is required",
"error": "Category name is required"
}
// CategoryController.create
const name = (req.body.name ?? '').toString().trim();
const userId = req.userId;
const category = await createCategoryImpl.execute(
{ name, walletId: req.body.walletId },
userId,
);
return res.status(201).json({
...buildSuccessResponse(SuccessCodes.CATEGORY_CREATED),
data: category,
});