Skill v1.0.0
currentAutomated scan96/100version: "1.0.0" name: backend description: >- NestJS backend development patterns for the RedisInsight API: module structure, services, controllers, DTOs, dependency injection, and error handling. Use when editing any file under redisinsight/api/**, writing or modifying NestJS modules, controllers, services, DTOs, providers, or when the user mentions the backend, API, or NestJS.
Backend Development (NestJS/API)
Module Structure
NestJS Architecture
- Follow modular architecture (feature-based modules)
- Use dependency injection throughout
- Separate concerns: Controllers, Services, Repositories
- Use DTOs for validation and data transfer
- Apply proper error handling with NestJS exceptions
Module Folder Structure
Each feature module in its own directory under api/src/:
feature/├── feature.module.ts # Module definition├── feature.controller.ts # REST endpoints├── feature.service.ts # Business logic├── feature.service.spec.ts # Service tests├── feature.controller.spec.ts # Controller tests├── feature.types.ts # Interfaces and types related to the feature├── dto/ # Data transfer objects│ ├── create-feature.dto.ts│ ├── update-feature.dto.ts│ └── feature.dto.ts├── entities/ # TypeORM entities├── repositories/ # Custom repositories├── exceptions/ # Custom exceptions├── guards/ # Feature-specific guards├── decorators/ # Custom decorators└── constants/ # Feature constants
File Naming
- Modules:
feature.module.ts - Controllers:
feature.controller.ts - Services:
feature.service.ts - DTOs:
create-feature.dto.ts,update-feature.dto.ts - Entities:
feature.entity.ts - Interfaces and types:
feature.types.ts - Tests:
feature.service.spec.ts - Constants:
feature.constants.ts - Exceptions:
feature-not-found.exception.ts
Constants Organization
Store feature-specific constants in dedicated constants file:
export const FEATURE_CONSTANTS = {MAX_NAME_LENGTH: 100,DEFAULT_PAGE_SIZE: 20,} as const;export const FEATURE_ERROR_MESSAGES = {NOT_FOUND: 'Feature not found',INVALID_INPUT: 'Invalid feature data',} as const;
Imports Order
- Node.js built-in modules
- External dependencies (
@nestjs/*, etc.) - Internal modules (using
src/*alias — the backend's self-reference intoredisinsight/api/src/*) - Local relative imports
Service Layer
Service Pattern
- Inject dependencies via constructor
- Use TypeORM repositories
- Handle errors with NestJS exceptions
- Use Logger for important operations
- Keep business logic in services (not controllers)
Dependency Injection
Always inject dependencies via constructor with proper decorators:
@Injectable()export class UserService {constructor(@InjectRepository(User)private readonly userRepository: Repository<User>,private readonly emailService: EmailService,) {}}
Controller Layer
Controller Pattern
- Keep controllers thin (delegate to services)
- Use proper HTTP decorators (
@Get,@Post, etc.) - Use
@Body,@Param,@Queryfor inputs - Apply guards with
@UseGuards() - Document with Swagger decorators
HTTP Status Codes
- Use
@HttpCode()decorator for non-standard codes - Return appropriate status codes (200, 201, 204, 400, 404, etc.)
Data Transfer Objects (DTOs)
Validation
Use class-validator decorators for validation:
@IsString(),@IsNumber(),@IsEmail()@IsNotEmpty(),@IsOptional()@MinLength(),@MaxLength()@Min(),@Max()
Swagger Documentation
Use @ApiProperty() and @ApiPropertyOptional() for Swagger docs.
Error Handling
NestJS Exceptions
Use appropriate exception types:
NotFoundException- 404BadRequestException- 400UnauthorizedException- 401ForbiddenException- 403ConflictException- 409InternalServerErrorException- 500
Custom Exceptions
Prefer custom exceptions over generic ones when you need:
- Consistent error codes for frontend handling
- Specific error messages from constants
- Consistent error structure across the codebase
Create custom exceptions following existing patterns:
// src/modules/feature/exceptions/feature-invalid.exception.tsimport {HttpException,HttpExceptionOptions,HttpStatus,} from '@nestjs/common';import ERROR_MESSAGES from 'src/constants/error-messages';import { CustomErrorCodes } from 'src/constants';export class FeatureInvalidException extends HttpException {constructor(message = ERROR_MESSAGES.FEATURE_INVALID,options?: HttpExceptionOptions,) {const response = {message,statusCode: HttpStatus.BAD_REQUEST,error: 'FeatureInvalid',errorCode: CustomErrorCodes.FeatureInvalid,};super(response, response.statusCode, options);}}
Error Logging
private readonly logger = new Logger(ServiceName.name)this.logger.error('Error message', error.stack, { context })
Redis Integration
Redis Service Pattern
- Use RedisClient from
src/modules/redis - Handle errors gracefully
- Log Redis operations
- Use try-catch for error handling
Code Quality
Cognitive Complexity (≤ 15)
- Use early returns to reduce nesting
- Extract complex logic to separate functions
- Avoid deeply nested conditions
No Duplicate Strings
Extract repeated strings to constants in constants file.
API Documentation (Swagger)
Required Decorators
@ApiTags()- Group endpoints@ApiOperation()- Describe operation@ApiResponse()- Document responses@ApiParam()- Document params@ApiQuery()- Document query params@ApiBearerAuth()- Auth requirement
Checklist
- [ ] Services use dependency injection
- [ ] DTOs have validation decorators
- [ ] Controllers have Swagger documentation
- [ ] Proper HTTP status codes used
- [ ] Error handling with appropriate exceptions
- [ ] Logging for important operations
- [ ] Transactions for related DB operations
- [ ] Configuration via ConfigService
- [ ] Guards for authentication/authorization
- [ ] Cognitive complexity ≤ 15