Skip to content

Commit

Permalink
docs(swagger): improve swagger docs (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinezanardi committed Mar 19, 2023
1 parent 63bc894 commit f9ea037
Show file tree
Hide file tree
Showing 43 changed files with 3,932 additions and 3,388 deletions.
2 changes: 1 addition & 1 deletion config/eslint/rules/standard.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const standardRules = Object.freeze({
"accessor-pairs": ERROR,
"arrow-body-style": [ERROR, "as-needed"],
"block-scoped-var": ERROR,
"camelcase": ERROR,
"camelcase": [ERROR, { allow: ["npm_package_version"] }],
"capitalized-comments": [ERROR, "never", { ignorePattern: "TODO" }],
"class-methods-use-this": ERROR,
"complexity": ERROR,
Expand Down
2 changes: 1 addition & 1 deletion config/gource/gource.config
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ title=Werewolves Assistant API
date-format=%d/%m/%Y
user-image-dir=./config/gource/assets/images/users
user-filter=(Antoine ZANARDI)
logo=./assets/images/werewolves-logo-small.png
logo=./public/assets/images/logo/full/werewolves-logo-small.png
30 changes: 24 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"docker:test:start": " docker-compose -f docker/werewolves-assistant-test/docker-compose.yml up -d",
"docker:test:stop": " docker-compose -f docker/werewolves-assistant-test/docker-compose.yml down",
"start": "nest start",
"start:dev": "nest start --watch",
"start:dev": "rimraf dist && nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint .",
Expand Down Expand Up @@ -44,7 +44,6 @@
},
"homepage": "https://github.com/antoinezanardi/werewolves-assistant-api-next#readme",
"dependencies": {
"@fastify/static": "^6.9.0",
"@nestjs/common": "^9.3.10",
"@nestjs/config": "^2.3.1",
"@nestjs/core": "^9.3.10",
Expand Down
3 changes: 3 additions & 0 deletions public/assets/css/custom-swagger.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.topbar {
display: none;
}
File renamed without changes
File renamed without changes
File renamed without changes
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/modules/config/database/database.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { MongooseModule } from "@nestjs/mongoose";
import { mongooseModuleFactory } from "./database.helper";
import { mongooseModuleFactory } from "./helpers/database.helper";

@Module({
imports: [
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/modules/config/env/env.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { getEnvPaths, validate } from "./env.helper";
import { getEnvPaths, validate } from "./helpers/env.helper";

@Module({
imports: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { plainToInstance } from "class-transformer";
import { validateSync } from "class-validator";
import { EnvironmentVariables } from "./env";
import { EnvironmentVariables } from "../types/env.type";

function validate(config: Record<string, unknown>): EnvironmentVariables {
const validatedConfig = plainToInstance(EnvironmentVariables, config, { enableImplicitConversion: true });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { IsEnum, IsNotEmpty, IsNumber, IsString } from "class-validator";
import { ENVIRONMENTS } from "./env.enum";
import { ENVIRONMENTS } from "../enums/env.enum";

class EnvironmentVariables {
@IsEnum(ENVIRONMENTS)
Expand Down
2 changes: 1 addition & 1 deletion src/modules/game/constants/game.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const gameFieldsSpecs = Object.freeze({

const gameApiProperties: Record<keyof Game, ApiPropertyOptions> = Object.freeze({
_id: {
description: "Game's ID",
description: "Game's Mongo ObjectId",
example: "507f1f77bcf86cd799439011",
},
turn: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { ApiParamOptions } from "@nestjs/swagger";
import { ApiParam } from "@nestjs/swagger";

function ApiGameIdParam(options: Partial<ApiParamOptions> = {}): MethodDecorator {
const defaultOptions: ApiParamOptions = {
name: "id",
description: "Game's Id. Must be a valid Mongo ObjectId",
example: "507f1f77bcf86cd799439011",
};
return ApiParam({ ...defaultOptions, ...options });
}

export { ApiGameIdParam };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { ApiResponseOptions } from "@nestjs/swagger";
import { ApiNotFoundResponse } from "@nestjs/swagger";

function ApiGameNotFoundResponse(options: ApiResponseOptions = {}): ClassDecorator & MethodDecorator {
const defaultOptions: ApiResponseOptions = { description: "The game with the provided id doesn't exist in database" };
return ApiNotFoundResponse({ ...defaultOptions, ...options });
}

export { ApiGameNotFoundResponse };
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
import { Body, Controller, Delete, Get, HttpStatus, Param, Post } from "@nestjs/common";
import { ApiOperation, ApiParam, ApiResponse, ApiTags } from "@nestjs/swagger";
import { API_RESOURCES } from "../../shared/api/enums/api.enum";
import { ValidateMongoId } from "../../shared/api/pipes/validate-mongo-id.pipe";
import { getControllerRouteError } from "../../shared/error/helpers/error.helper";
import { CreateGameDto } from "./dto/create-game/create-game.dto";
import { GAME_STATUSES } from "./enums/game.enum";
import { GameService } from "./game.service";
import { Game } from "./schemas/game.schema";
import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { API_RESOURCES } from "../../../shared/api/enums/api.enum";
import { ValidateMongoId } from "../../../shared/api/pipes/validate-mongo-id.pipe";
import { getControllerRouteError } from "../../../shared/error/helpers/error.helper";
import { CreateGameDto } from "../dto/create-game/create-game.dto";
import { GAME_STATUSES } from "../enums/game.enum";
import { GameService } from "../providers/game.service";
import { Game } from "../schemas/game.schema";
import { ApiGameIdParam } from "./decorators/api-game-id-param.decorator";
import { ApiGameNotFoundResponse } from "./decorators/api-game-not-found-response.decorator";

@ApiTags("🎲 Games")
@Controller(API_RESOURCES.GAMES)
export class GameController {
public constructor(private readonly gameService: GameService) {}
@Get()
@ApiOperation({ summary: "Get games" })
@ApiResponse({ status: HttpStatus.OK, type: Game, isArray: true })
public async getGames(): Promise<Game[]> {
return this.gameService.getGames();
}

@Get(":id")
@ApiOperation({ summary: "Get a game by id" })
@ApiGameIdParam()
@ApiResponse({ status: HttpStatus.OK, type: Game })
@ApiGameNotFoundResponse()
public async getGame(@Param("id", ValidateMongoId) id: string): Promise<Game> {
try {
return await this.gameService.getGameById(id);
Expand All @@ -29,14 +35,16 @@ export class GameController {
}

@Post()
@ApiOperation({ summary: "Create a new game" })
public async createGame(@Body() createGameDto: CreateGameDto): Promise<Game> {
return this.gameService.createGame(createGameDto);
}

@Delete(":id")
@ApiOperation({ summary: "Cancel a playing game" })
@ApiParam({ name: "id", description: "Game's Id. Must be a valid MongoId" })
@ApiOperation({ summary: "Cancel a playing game", description: `This endpoint won't delete the game, but set its status to ${GAME_STATUSES.CANCELED}. In this status, the game can't be mutated anymore.` })
@ApiGameIdParam()
@ApiResponse({ status: HttpStatus.OK, type: Game, description: `Game's status will be set to ${GAME_STATUSES.CANCELED}` })
@ApiGameNotFoundResponse()
public async cancelGame(@Param("id", ValidateMongoId) id: string): Promise<Game> {
try {
return await this.gameService.cancelGameById(id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ValidationOptions } from "class-validator";
import { registerDecorator } from "class-validator";
import { roles } from "../../../../role/constants/role.constant";
import type { Role } from "../../../../role/role.entity";
import type { Role } from "../../../../role/types/role.type";
import type { CreateGamePlayerDto } from "../create-game-player/create-game-player.dto";
import type { CreateGameDto } from "../create-game.dto";

Expand Down
6 changes: 3 additions & 3 deletions src/modules/game/game.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Module } from "@nestjs/common";
import { MongooseModule } from "@nestjs/mongoose";
import { DatabaseModule } from "../config/database/database.module";
import { GameController } from "./game.controller";
import { GameRepository } from "./game.repository";
import { GameService } from "./game.service";
import { GameController } from "./controllers/game.controller";
import { GameRepository } from "./providers/game.repository";
import { GameService } from "./providers/game.service";
import { Game, GameSchema } from "./schemas/game.schema";

@Module({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Injectable } from "@nestjs/common";
import { InjectModel } from "@nestjs/mongoose";
import type { FilterQuery, QueryOptions } from "mongoose";
import { Model } from "mongoose";
import type { CreateGameDto } from "./dto/create-game/create-game.dto";
import type { GameDocument } from "./schemas/game.schema";
import { Game } from "./schemas/game.schema";
import type { CreateGameDto } from "../dto/create-game/create-game.dto";
import type { GameDocument } from "../schemas/game.schema";
import { Game } from "../schemas/game.schema";

@Injectable()
export class GameRepository {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Injectable } from "@nestjs/common";
import { API_RESOURCES } from "../../shared/api/enums/api.enum";
import { BAD_RESOURCE_MUTATION_REASONS } from "../../shared/error/enums/bad-resource-mutation-error.enum";
import { BadResourceMutationError } from "../../shared/error/types/bad-resource-mutation-error.type";
import { ResourceNotFoundError } from "../../shared/error/types/resource-not-found-error.type";
import type { CreateGameDto } from "./dto/create-game/create-game.dto";
import { GAME_STATUSES } from "./enums/game.enum";
import { API_RESOURCES } from "../../../shared/api/enums/api.enum";
import { BAD_RESOURCE_MUTATION_REASONS } from "../../../shared/error/enums/bad-resource-mutation-error.enum";
import { BadResourceMutationError } from "../../../shared/error/types/bad-resource-mutation-error.type";
import { ResourceNotFoundError } from "../../../shared/error/types/resource-not-found-error.type";
import type { CreateGameDto } from "../dto/create-game/create-game.dto";
import { GAME_STATUSES } from "../enums/game.enum";
import type { Game } from "../schemas/game.schema";
import { GameRepository } from "./game.repository";
import type { Game } from "./schemas/game.schema";

@Injectable()
export class GameService {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Controller, Get } from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { ApiOperation, ApiTags } from "@nestjs/swagger";
import type { HealthCheckResult, HealthIndicatorResult } from "@nestjs/terminus";
import { HealthCheck, HealthCheckService, MongooseHealthIndicator } from "@nestjs/terminus";
import { API_RESOURCES } from "../../shared/api/enums/api.enum";
import { API_RESOURCES } from "../../../shared/api/enums/api.enum";

@ApiTags("❤️ Health")
@Controller(API_RESOURCES.HEALTH)
Expand All @@ -12,7 +12,11 @@ export class HealthController {
private readonly mongoose: MongooseHealthIndicator,
) {}

@Get("/")
@Get()
@ApiOperation({
summary: "Get health's status of the API",
description: "The health will be defined against the MongoDB connection instance",
})
@HealthCheck()
public async check(): Promise<HealthCheckResult> {
return this.health.check([async(): Promise<HealthIndicatorResult> => this.mongoose.pingCheck("mongoose")]);
Expand Down

0 comments on commit f9ea037

Please sign in to comment.