From harness-claude
Documents NestJS APIs with @ApiProperty, @ApiOperation, @ApiTags, and DocumentBuilder, generating interactive Swagger UI and OpenAPI specs.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:nestjs-swagger-integrationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Document APIs with @ApiProperty, @ApiOperation, @ApiTags, and DocumentBuilder
Document APIs with @ApiProperty, @ApiOperation, @ApiTags, and DocumentBuilder
/api (or a custom path)npm install @nestjs/swagger swagger-ui-express
// main.ts
const config = new DocumentBuilder()
.setTitle('My API')
.setDescription('REST API documentation')
.setVersion('1.0')
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document, {
swaggerOptions: { persistAuthorization: true },
});
@ApiTags('users')
@Controller('users')
export class UsersController {
@ApiOperation({ summary: 'Get a user by ID' })
@ApiParam({ name: 'id', type: 'string', format: 'uuid' })
@ApiResponse({ status: 200, type: UserDto })
@ApiResponse({ status: 404, description: 'User not found' })
@Get(':id')
findOne(@Param('id') id: string) { ... }
@ApiOperation({ summary: 'Create a user' })
@ApiBody({ type: CreateUserDto })
@ApiResponse({ status: 201, type: UserDto })
@ApiBearerAuth()
@Post()
create(@Body() dto: CreateUserDto) { ... }
}
export class CreateUserDto {
@ApiProperty({ example: '[email protected]', description: 'User email address' })
@IsEmail()
email: string;
@ApiProperty({ example: 'myP@ssw0rd', minLength: 8 })
@IsString()
@MinLength(8)
password: string;
@ApiPropertyOptional({ example: 'John Doe' })
@IsOptional()
@IsString()
displayName?: string;
}
@nestjs/swagger (not @nestjs/mapped-types) for full Swagger compatibility:import { PartialType, OmitType, PickType } from '@nestjs/swagger';
export class UpdateUserDto extends PartialType(CreateUserDto) {}
export class UserProfileDto extends OmitType(CreateUserDto, ['password']) {}
@ApiResponse({ status: 200, schema: {
properties: {
data: { type: 'array', items: { $ref: getSchemaPath(UserDto) } },
total: { type: 'number' },
page: { type: 'number' },
}
}})
@nestjs/swagger uses TypeScript reflection metadata to auto-detect types in DTOs and controllers. When emitDecoratorMetadata is enabled in tsconfig.json (it must be for NestJS to work), most types are inferred automatically.
Enum documentation: Pass enum: MyEnum in @ApiProperty for Swagger to show all valid values: @ApiProperty({ enum: UserRole, enumName: 'UserRole' }).
@ApiHideProperty(): Exclude a property from the Swagger spec (e.g., internal tracking fields) without removing it from the DTO class.
CLI plugin (recommended): Add to nest-cli.json to auto-add @ApiProperty based on class-validator decorators — eliminates duplication:
{
"compilerOptions": {
"plugins": ["@nestjs/swagger"]
}
}
Exclude from production: The Swagger UI and spec endpoint should be conditionally registered. Wrap the SwaggerModule.setup() call: if (process.env.NODE_ENV !== 'production') { ... }.
Export the spec: SwaggerModule.createDocument() returns a plain OpenAPI 3.0 object. Write it to disk with fs.writeFileSync('swagger.json', JSON.stringify(document)) to integrate with API gateway import workflows.
https://docs.nestjs.com/openapi/introduction
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeCreates and configures NestJS modules, controllers, services, DTOs, guards, interceptors, and authentication for enterprise-grade TypeScript backend applications.
Scaffolds and configures NestJS modules, controllers, services, DTOs, guards, interceptors, pipes, and validation for enterprise-grade TypeScript backends with REST APIs or GraphQL. Integrates JWT/Passport auth, TypeORM/Prisma, and Swagger docs.
Generates or reviews OpenAPI/Swagger documentation for Spring Boot REST APIs by adding @Operation, @Schema, @ApiResponse annotations and configuring Swagger UI.