redis/backend
>- 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.
npx skills add https://github.com/redis/RedisInsight --skill backend
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
feature.module.tsfeature.controller.tsfeature.service.tscreate-feature.dto.ts, update-feature.dto.tsfeature.entity.tsfeature.types.tsfeature.service.spec.tsfeature.constants.tsfeature-not-found.exception.tsStore 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;
@nestjs/*, etc.)src/* alias — the backend's self-reference into redisinsight/api/src/*)Always inject dependencies via constructor with proper decorators:
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>,
private readonly emailService: EmailService,
) {}
}
@Get, @Post, etc.)@Body, @Param, @Query for inputs@UseGuards()@HttpCode() decorator for non-standard codesUse class-validator decorators for validation:
@IsString(), @IsNumber(), @IsEmail()@IsNotEmpty(), @IsOptional()@MinLength(), @MaxLength()@Min(), @Max()Use @ApiProperty() and @ApiPropertyOptional() for Swagger docs.
Use appropriate exception types:
NotFoundException - 404BadRequestException - 400UnauthorizedException - 401ForbiddenException - 403ConflictException - 409InternalServerErrorException - 500Prefer custom exceptions over generic ones when you need:
Create custom exceptions following existing patterns:
// src/modules/feature/exceptions/feature-invalid.exception.ts
import {
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);
}
}
private readonly logger = new Logger(ServiceName.name)
this.logger.error('Error message', error.stack, { context })
src/modules/redisExtract repeated strings to constants in constants file.
@ApiTags() - Group endpoints@ApiOperation() - Describe operation@ApiResponse() - Document responses@ApiParam() - Document params@ApiQuery() - Document query params@ApiBearerAuth() - Auth requirementTake redis/backend from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.