From 1ec882780d0ea2d09f35988f772959ada1c635b8 Mon Sep 17 00:00:00 2001 From: John Brunton Date: Thu, 15 Aug 2024 23:20:27 +0100 Subject: [PATCH] feat: generate swagger docs --- services/api/package-lock.json | 187 ++++++++++++++++-- services/api/package.json | 4 + .../app/messages/dto/create-message.dto.ts | 4 - services/api/src/app/messages/dto/messages.ts | 37 ++++ .../app/messages/messages.controller.spec.ts | 2 +- .../src/app/messages/messages.controller.ts | 14 +- .../src/app/messages/messages.service.spec.ts | 2 +- .../api/src/app/messages/messages.service.ts | 2 +- .../src/domain/entities/messages/message.ts | 5 +- .../api/src/domain/usecases/rooms/rename.ts | 4 +- .../api/src/domain/usecases/users/rename.ts | 4 +- services/api/src/main.ts | 13 +- 12 files changed, 248 insertions(+), 30 deletions(-) delete mode 100644 services/api/src/app/messages/dto/create-message.dto.ts create mode 100644 services/api/src/app/messages/dto/messages.ts diff --git a/services/api/package-lock.json b/services/api/package-lock.json index b1185648..1ca0a1d4 100644 --- a/services/api/package-lock.json +++ b/services/api/package-lock.json @@ -9,6 +9,8 @@ "version": "0.0.1", "license": "UNLICENSED", "dependencies": { + "@anatine/zod-nestjs": "2.0.9", + "@anatine/zod-openapi": "2.2.6", "@aws-sdk/client-dynamodb": "3.238.0", "@aws-sdk/credential-provider-node": "3.238.0", "@aws-sdk/lib-dynamodb": "3.238.0", @@ -20,6 +22,7 @@ "@nestjs/mapped-types": "*", "@nestjs/passport": "9.0.0", "@nestjs/platform-express": "^9.0.0", + "@nestjs/swagger": "7.4.0", "async-cache-dedupe": "1.8.0", "auth0": "3.0.1", "cache-manager": "5.1.4", @@ -27,6 +30,7 @@ "express-jwt": "7.7.7", "jwks-rsa": "3.0.0", "node-fetch": "2.6.7", + "openapi3-ts": "4.3.3", "passport": "0.6.0", "passport-jwt": "4.0.0", "rambda": "7.4.0", @@ -87,6 +91,33 @@ "node": ">=6.0.0" } }, + "node_modules/@anatine/zod-nestjs": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@anatine/zod-nestjs/-/zod-nestjs-2.0.9.tgz", + "integrity": "sha512-XEK+7wMXAxc4tOkzOpH/vav1MVZrVYeOwKpXmn7aFiTUoB08G1FzAP7rDQ90ZrIFOGSoC0hpJA9izPQxBRAIDg==", + "dependencies": { + "ts-deepmerge": "^6.1.0" + }, + "peerDependencies": { + "@anatine/zod-openapi": "^2.0.1", + "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", + "@nestjs/swagger": "^6.0.0 || ^7.0.0", + "openapi3-ts": "^4.1.2", + "zod": "^3.20.0" + } + }, + "node_modules/@anatine/zod-openapi": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@anatine/zod-openapi/-/zod-openapi-2.2.6.tgz", + "integrity": "sha512-Z5sr2Nq2xifEpPbPdUcvyl776LY652oR3VHMV++WFSmRrRL8RDP2XTkbuGn+vgfVNOD7UrndYwCWnxaiw7IZog==", + "dependencies": { + "ts-deepmerge": "^6.0.3" + }, + "peerDependencies": { + "openapi3-ts": "^4.1.2", + "zod": "^3.20.0" + } + }, "node_modules/@angular-devkit/core": { "version": "14.2.2", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz", @@ -3469,6 +3500,11 @@ "node": ">=8" } }, + "node_modules/@microsoft/tsdoc": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==" + }, "node_modules/@nestjs/cli": { "version": "9.1.5", "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.1.5.tgz", @@ -3665,14 +3701,14 @@ } }, "node_modules/@nestjs/mapped-types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.2.0.tgz", - "integrity": "sha512-NTFwPZkQWsArQH8QSyFWGZvJ08gR+R4TofglqZoihn/vU+ktHEJjMqsIsADwb7XD97DhiD+TVv5ac+jG33BHrg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz", + "integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==", "peerDependencies": { - "@nestjs/common": "^7.0.8 || ^8.0.0 || ^9.0.0", - "class-transformer": "^0.2.0 || ^0.3.0 || ^0.4.0 || ^0.5.0", - "class-validator": "^0.11.1 || ^0.12.0 || ^0.13.0", - "reflect-metadata": "^0.1.12" + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "class-transformer": "^0.4.0 || ^0.5.0", + "class-validator": "^0.13.0 || ^0.14.0", + "reflect-metadata": "^0.1.12 || ^0.2.0" }, "peerDependenciesMeta": { "class-transformer": { @@ -3808,6 +3844,38 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/@nestjs/swagger": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", + "integrity": "sha512-dCiwKkRxcR7dZs5jtrGspBAe/nqJd1AYzOBTzw9iCdbq3BGrLpwokelk6lFZPe4twpTsPQqzNKBwKzVbI6AR/g==", + "dependencies": { + "@microsoft/tsdoc": "^0.15.0", + "@nestjs/mapped-types": "2.0.5", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0", + "swagger-ui-dist": "5.17.14" + }, + "peerDependencies": { + "@fastify/static": "^6.0.0 || ^7.0.0", + "@nestjs/common": "^9.0.0 || ^10.0.0", + "@nestjs/core": "^9.0.0 || ^10.0.0", + "class-transformer": "*", + "class-validator": "*", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "@fastify/static": { + "optional": true + }, + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/testing": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.2.1.tgz", @@ -5318,8 +5386,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-flatten": { "version": "1.1.1", @@ -10995,7 +11062,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -11879,6 +11945,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi3-ts": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-4.3.3.tgz", + "integrity": "sha512-LKkzBGJcZ6wdvkKGMoSvpK+0cbN5Xc3XuYkJskO+vjEQWJgs1kgtyUk0pjf8KwPuysv323Er62F5P17XQl96Qg==", + "dependencies": { + "yaml": "^2.4.5" + } + }, + "node_modules/openapi3-ts/node_modules/yaml": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -13501,6 +13586,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-ui-dist": { + "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz", + "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==" + }, "node_modules/swap-case": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", @@ -13737,6 +13827,14 @@ "tree-kill": "cli.js" } }, + "node_modules/ts-deepmerge": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-6.2.1.tgz", + "integrity": "sha512-8CYSLazCyj0DJDpPIxOFzJG46r93uh6EynYjuey+bxcLltBeqZL7DMfaE5ZPzZNFlav7wx+2TDa/mBl8gkTYzw==", + "engines": { + "node": ">=14.13.1" + } + }, "node_modules/ts-essentials": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", @@ -14755,6 +14853,22 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@anatine/zod-nestjs": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@anatine/zod-nestjs/-/zod-nestjs-2.0.9.tgz", + "integrity": "sha512-XEK+7wMXAxc4tOkzOpH/vav1MVZrVYeOwKpXmn7aFiTUoB08G1FzAP7rDQ90ZrIFOGSoC0hpJA9izPQxBRAIDg==", + "requires": { + "ts-deepmerge": "^6.1.0" + } + }, + "@anatine/zod-openapi": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@anatine/zod-openapi/-/zod-openapi-2.2.6.tgz", + "integrity": "sha512-Z5sr2Nq2xifEpPbPdUcvyl776LY652oR3VHMV++WFSmRrRL8RDP2XTkbuGn+vgfVNOD7UrndYwCWnxaiw7IZog==", + "requires": { + "ts-deepmerge": "^6.0.3" + } + }, "@angular-devkit/core": { "version": "14.2.2", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz", @@ -17417,6 +17531,11 @@ "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==" }, + "@microsoft/tsdoc": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==" + }, "@nestjs/cli": { "version": "9.1.5", "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.1.5.tgz", @@ -17537,9 +17656,9 @@ } }, "@nestjs/mapped-types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.2.0.tgz", - "integrity": "sha512-NTFwPZkQWsArQH8QSyFWGZvJ08gR+R4TofglqZoihn/vU+ktHEJjMqsIsADwb7XD97DhiD+TVv5ac+jG33BHrg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz", + "integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==", "requires": {} }, "@nestjs/passport": { @@ -17638,6 +17757,19 @@ } } }, + "@nestjs/swagger": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", + "integrity": "sha512-dCiwKkRxcR7dZs5jtrGspBAe/nqJd1AYzOBTzw9iCdbq3BGrLpwokelk6lFZPe4twpTsPQqzNKBwKzVbI6AR/g==", + "requires": { + "@microsoft/tsdoc": "^0.15.0", + "@nestjs/mapped-types": "2.0.5", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0", + "swagger-ui-dist": "5.17.14" + } + }, "@nestjs/testing": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.2.1.tgz", @@ -18839,8 +18971,7 @@ "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "array-flatten": { "version": "1.1.1", @@ -23105,7 +23236,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "requires": { "argparse": "^2.0.1" } @@ -23806,6 +23936,21 @@ "is-wsl": "^2.2.0" } }, + "openapi3-ts": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-4.3.3.tgz", + "integrity": "sha512-LKkzBGJcZ6wdvkKGMoSvpK+0cbN5Xc3XuYkJskO+vjEQWJgs1kgtyUk0pjf8KwPuysv323Er62F5P17XQl96Qg==", + "requires": { + "yaml": "^2.4.5" + }, + "dependencies": { + "yaml": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==" + } + } + }, "opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -25014,6 +25159,11 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "swagger-ui-dist": { + "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz", + "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==" + }, "swap-case": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", @@ -25188,6 +25338,11 @@ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, + "ts-deepmerge": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-6.2.1.tgz", + "integrity": "sha512-8CYSLazCyj0DJDpPIxOFzJG46r93uh6EynYjuey+bxcLltBeqZL7DMfaE5ZPzZNFlav7wx+2TDa/mBl8gkTYzw==" + }, "ts-essentials": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", diff --git a/services/api/package.json b/services/api/package.json index a7fde8aa..20949b5b 100644 --- a/services/api/package.json +++ b/services/api/package.json @@ -30,6 +30,8 @@ "docs:serve": "http-server docs" }, "dependencies": { + "@anatine/zod-nestjs": "2.0.9", + "@anatine/zod-openapi": "2.2.6", "@aws-sdk/client-dynamodb": "3.238.0", "@aws-sdk/credential-provider-node": "3.238.0", "@aws-sdk/lib-dynamodb": "3.238.0", @@ -41,6 +43,7 @@ "@nestjs/mapped-types": "*", "@nestjs/passport": "9.0.0", "@nestjs/platform-express": "^9.0.0", + "@nestjs/swagger": "7.4.0", "async-cache-dedupe": "1.8.0", "auth0": "3.0.1", "cache-manager": "5.1.4", @@ -48,6 +51,7 @@ "express-jwt": "7.7.7", "jwks-rsa": "3.0.0", "node-fetch": "2.6.7", + "openapi3-ts": "4.3.3", "passport": "0.6.0", "passport-jwt": "4.0.0", "rambda": "7.4.0", diff --git a/services/api/src/app/messages/dto/create-message.dto.ts b/services/api/src/app/messages/dto/create-message.dto.ts deleted file mode 100644 index b0d30669..00000000 --- a/services/api/src/app/messages/dto/create-message.dto.ts +++ /dev/null @@ -1,4 +0,0 @@ -export class CreateMessageDto { - content: string; - roomId: string; -} diff --git a/services/api/src/app/messages/dto/messages.ts b/services/api/src/app/messages/dto/messages.ts new file mode 100644 index 00000000..90d53e2b --- /dev/null +++ b/services/api/src/app/messages/dto/messages.ts @@ -0,0 +1,37 @@ +import { createZodDto } from '@anatine/zod-nestjs'; +import { extendApi } from '@anatine/zod-openapi'; +import { SentMessage, UpdatedEntity } from '@entities/messages'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { z } from 'zod'; + +const CreateMessageSchema = extendApi( + z.strictObject({ + content: z.string(), + roomId: z.string(), + }), +); + +export class CreateMessageDto extends createZodDto(CreateMessageSchema) {} + +export class SentMessageDto implements SentMessage { + @ApiProperty() + id: string; + + @ApiProperty() + time: number; + + @ApiProperty() + roomId: string; + + @ApiProperty() + authorId: string; + + @ApiProperty() + content: string; + + @ApiPropertyOptional() + recipientId: string | undefined; + + @ApiProperty() + updatedEntities: UpdatedEntity[]; +} diff --git a/services/api/src/app/messages/messages.controller.spec.ts b/services/api/src/app/messages/messages.controller.spec.ts index 19eb02d9..72a31cda 100644 --- a/services/api/src/app/messages/messages.controller.spec.ts +++ b/services/api/src/app/messages/messages.controller.spec.ts @@ -18,7 +18,7 @@ import { Room } from '@entities/room.entity'; import { RoomsRepository } from '@entities/rooms.repository'; import { TestRoomsRepository } from '@fixtures/data/test.rooms.repository'; import { RoomFactory } from '@fixtures/messages/room.factory'; -import { CreateMessageDto } from './dto/create-message.dto'; +import { CreateMessageDto } from './dto/messages'; import { TestMembershipsRepository } from '@fixtures/data/test.memberships.repository'; import { MembershipsRepository } from '@entities/memberships.repository'; import { MembershipStatus } from '@entities/membership.entity'; diff --git a/services/api/src/app/messages/messages.controller.ts b/services/api/src/app/messages/messages.controller.ts index bf153e55..e97b866f 100644 --- a/services/api/src/app/messages/messages.controller.ts +++ b/services/api/src/app/messages/messages.controller.ts @@ -1,13 +1,15 @@ import { Controller, Get, Post, Body, Param, Sse } from '@nestjs/common'; import { MessagesService } from './messages.service'; -import { CreateMessageDto } from './dto/create-message.dto'; +import { CreateMessageDto, SentMessageDto } from './dto/messages'; import { Auth } from '@app/auth/auth.decorator'; import { Identify } from '@app/auth/auth0/identify.decorator'; import { User } from '@entities/users'; import { Dispatcher } from '@entities/messages'; import { GetMessagesUseCase } from '@usecases/messages/get-messages'; +import { ApiBearerAuth, ApiOperation, ApiResponse } from '@nestjs/swagger'; @Auth() +@ApiBearerAuth() @Controller('messages') export class MessagesController { constructor( @@ -17,6 +19,9 @@ export class MessagesController { ) {} @Post('/') + @ApiOperation({ + summary: 'Send a message to a room from the authenticated user', + }) saveMessage( @Body() createMessageDto: CreateMessageDto, @Identify() user: User, @@ -25,11 +30,18 @@ export class MessagesController { } @Get('/:roomId') + @ApiOperation({ summary: 'Get all messages for the room' }) + @ApiResponse({ + status: 200, + description: 'The messages for the room', + type: [SentMessageDto], + }) get(@Param('roomId') roomId: string, @Identify() user: User) { return this.getMessages.exec(roomId, user); } @Sse('/:roomId/subscribe') + @ApiOperation({ summary: 'subscribe to messages for the room' }) subscribeMessages(@Param('roomId') roomId: string, @Identify() user: User) { return this.dispatcher.subscribe(roomId, user); } diff --git a/services/api/src/app/messages/messages.service.spec.ts b/services/api/src/app/messages/messages.service.spec.ts index 99855cba..5916d39f 100644 --- a/services/api/src/app/messages/messages.service.spec.ts +++ b/services/api/src/app/messages/messages.service.spec.ts @@ -1,5 +1,5 @@ import { MessagesService } from './messages.service'; -import { CreateMessageDto } from './dto/create-message.dto'; +import { CreateMessageDto } from './dto/messages'; import { UserFactory } from '@fixtures/messages/user.factory'; import { RoomFactory } from '@fixtures/messages/room.factory'; import { User } from '@entities/users'; diff --git a/services/api/src/app/messages/messages.service.ts b/services/api/src/app/messages/messages.service.ts index 38a60537..cc05699b 100644 --- a/services/api/src/app/messages/messages.service.ts +++ b/services/api/src/app/messages/messages.service.ts @@ -1,5 +1,5 @@ import { HttpException, Injectable } from '@nestjs/common'; -import { CreateMessageDto } from './dto/create-message.dto'; +import { CreateMessageDto } from './dto/messages'; import { User, systemUser } from '@entities/users'; import { SendMessageUseCase } from '@usecases/messages/send'; import { CommandService } from '@app/messages/command.service'; diff --git a/services/api/src/domain/entities/messages/message.ts b/services/api/src/domain/entities/messages/message.ts index b99e6f70..60b1fb82 100644 --- a/services/api/src/domain/entities/messages/message.ts +++ b/services/api/src/domain/entities/messages/message.ts @@ -1,7 +1,10 @@ import { Observable } from 'rxjs'; import { User } from '../users/user.entity'; -type UpdatedEntity = 'room' | 'users'; +export enum UpdatedEntity { + Room = 'room', + Users = 'users', +} /** * A message that has been sent by a user and is stored in the system. diff --git a/services/api/src/domain/usecases/rooms/rename.ts b/services/api/src/domain/usecases/rooms/rename.ts index c3392c63..a7b9319a 100644 --- a/services/api/src/domain/usecases/rooms/rename.ts +++ b/services/api/src/domain/usecases/rooms/rename.ts @@ -1,5 +1,5 @@ import { AuthService, Role } from '@usecases/auth.service'; -import { Dispatcher, DraftMessage } from '@entities/messages'; +import { Dispatcher, DraftMessage, UpdatedEntity } from '@entities/messages'; import { RoomsRepository } from '@entities/rooms.repository'; import { User } from '@entities/users'; import { Injectable } from '@nestjs/common'; @@ -39,7 +39,7 @@ export class RenameRoomUseCase { content: `Room renamed to ${updatedRoom.name}`, roomId: room.id, authorId: 'system', - updatedEntities: ['room'], + updatedEntities: [UpdatedEntity.Room], }; await this.dispatcher.send(message); diff --git a/services/api/src/domain/usecases/users/rename.ts b/services/api/src/domain/usecases/users/rename.ts index 64edd632..c2ef3ef8 100644 --- a/services/api/src/domain/usecases/users/rename.ts +++ b/services/api/src/domain/usecases/users/rename.ts @@ -1,4 +1,4 @@ -import { Dispatcher, DraftMessage } from '@entities/messages'; +import { Dispatcher, DraftMessage, UpdatedEntity } from '@entities/messages'; import { User } from '@entities/users'; import { UsersRepository } from '@entities/users'; import { Injectable } from '@nestjs/common'; @@ -28,7 +28,7 @@ export class RenameUserUseCase { content: `User ${authenticatedUser.name} renamed to ${newName}`, roomId, authorId: 'system', - updatedEntities: ['users'], + updatedEntities: [UpdatedEntity.Users], }; this.dispatcher.send(message); diff --git a/services/api/src/main.ts b/services/api/src/main.ts index d521a50d..377a1a64 100644 --- a/services/api/src/main.ts +++ b/services/api/src/main.ts @@ -1,5 +1,6 @@ import { ConsoleLogger } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; +import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { MainModule } from './main.module'; const port = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000; @@ -10,7 +11,17 @@ async function bootstrap() { const logger = await app.resolve(ConsoleLogger); logger.setContext('main'); - logger.log(`Running server on PID=${process.pid}, port=${port}`); + logger.log(`Running server on http://localhost:${port}`); + + const config = new DocumentBuilder() + .setTitle('Chat Demo API') + .setDescription('API docs for Chat Demo') + .setVersion('1.0') + .addBearerAuth() + .addSecurityRequirements('bearer') + .build(); + const document = SwaggerModule.createDocument(app, config); + SwaggerModule.setup('docs', app, document); await app.listen(port); }