Categories Module
What this module solves
Section titled “What this module solves”Allows users to organize transactions with personal categories and keep analytics meaningful.
Endpoints
Section titled “Endpoints”- Canonical base:
/api/v1/categoriesPOST /api/v1/categoriesGET /api/v1/categoriesPATCH /api/v1/categories/:categoryIdDELETE /api/v1/categories/:categoryId
- Compatibility alias base:
/api/v1/category(same handlers and behavior).
Validation rules
Section titled “Validation rules”nameis required, min 2 chars, max 10 chars.- Schema file:
backend/src/Shared/Schemas/categorySchema.ts.
Internal flow
Section titled “Internal flow”| Route | Controller | Use case | Repository | Route file trace |
|---|---|---|---|---|
POST /categories | CategoryController.create | CreateCategoryImpl | CategoryRepositoryImpl | backend/src/Presentation/Routes/CategoryRoutes.ts |
GET /categories | CategoryController.get | GetUserCategoriesImpl | CategoryRepositoryImpl | backend/src/Presentation/Routes/CategoryRoutes.ts |
PATCH /categories/:categoryId | CategoryController.update | UpdateCategoryImpl | CategoryRepositoryImpl | backend/src/Presentation/Routes/CategoryRoutes.ts |
DELETE /categories/:categoryId | CategoryController.delete | DeleteCategoryImpl | CategoryRepositoryImpl | backend/src/Presentation/Routes/CategoryRoutes.ts |
Alias wiring (/category) lives in backend/src/Presentation/Routes/Index.ts.
Common errors
Section titled “Common errors”CATEGORY_NAME_REQUIRED(400).CATEGORY_ALREADY_EXISTSorCATEGORY_NAME_ALREADY_EXIST(409).CATEGORY_ID_REQUIRED(400).USER_NOT_AUTHENTICATED(401).
Testing notes
Section titled “Testing notes”- E2E file:
backend/src/tests/e2e/category/category-crud.e2e.test.ts. - Unit example:
backend/src/tests/unit/update-category-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/categories" \ -H "Authorization: Bearer <jwt>" \ -H "Content-Type: application/json" \ -d '{ "name": "Food", "walletId": "wlt_123" }'2) Success JSON response example
Section titled “2) Success JSON response example”{ "code": "CATEGORY_CREATED", "message": "Category created successfully", "data": { "id": "cat_123", "name": "Food", "userId": "usr_123", "walletId": "wlt_123" }}3) Common error JSON response example
Section titled “3) Common error JSON response example”{ "code": "CATEGORY_NAME_REQUIRED", "message": "Category name is required", "error": "Category name is required"}4) Tiny internal trace snippet
Section titled “4) Tiny internal trace snippet”// CategoryController.createconst 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,});