--- description: HMVC module pattern for ERP backend src/modules globs: src/modules/**/*.js alwaysApply: false --- # HMVC Module Pattern Each module is self-contained with this file set: | File | Role | |------|------| | `*.routes.js` | HTTP verbs + middleware chain only | | `*.controller.js` | Parse request, call service, shape `ApiResponse` via `asyncHandler` | | `*.service.js` | Business logic, Prisma calls, `auditLog` | | `*.validation.js` | Joi schemas (body default; `'query'` for list filters) | | `*.repository.js` | **Complex modules only** (PO, GRN, Assets) — multi-table `prisma.$transaction` | ## Route middleware order ```js router.post('/', authenticate, authorize('VENDOR', 'create'), validate(createSchema), controller.create); ``` ## Service rules - Simple masters/CRUD: call Prisma directly from service - Auto codes: `nextDocumentNumber('VENDOR')` inside a transaction - Pass `req.user.id` and `req.id` (request ID) into service for audit trails - Filter all reads with `deleted_at: null` ## Masters - RBAC module code: `MASTERS` - UOM is the template — replicate four-file pattern for other masters - Aggregate sub-routers in `src/modules/masters/index.js` ## Do not - Put Prisma calls or business logic in controllers - Skip `authorize()` on protected endpoints - Hard-delete transactional records - Return raw refresh tokens or passwords in API responses