--- description: Backend NestJS modules, Prisma, permissions, guards globs: backend/src/** alwaysApply: false --- # Backend conventions ## Module layout `backend/src/modules/{feature}/` → `{feature}.module.ts`, `.controller.ts`, `.service.ts`, `dto/`. Register new modules in `app.module.ts`. ## Errors Use coded errors — not raw user-facing strings: ```typescript throw new AppException(ErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN); ``` - Codes: `backend/src/common/errors/error-codes.ts` - DTO validation: `{ message: ErrorCode.VALIDATION_* }` on class-validator decorators - Global filter: `HttpExceptionFilter` in `main.ts` ## Permissions - Check access with `hasEffectivePermission(membership, 'TAB_*')` from `common/membership-permissions.ts`. - Clinic-only routes: `ClinicOrgGuard`. Lab-only: `LabOrgGuard`. - Feature-specific checks belong in the **service**, not only the controller. ## Prisma - Schema: `backend/prisma/schema.prisma` - Always add a migration for schema changes (`npm run prisma:migrate` in backend). - Seed permissions stay in sync with `ALL_TAB_PERMISSIONS` in `common/permissions.ts`. ## API responses Prefer `{ success: true, data: ... }` shape consistent with existing modules.