From 021f2c83e8c99298fef60f918fa6620a99e24d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8E=E1=85=A1=E1=86=AB=E1=84=8C?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 26 Jul 2022 00:38:47 +0900 Subject: [PATCH 01/21] =?UTF-8?q?:hammer:=20fix(slack)=20:=20=EC=8A=AC?= =?UTF-8?q?=EB=9E=99=20fake=20=EC=84=9C=EB=B9=84=EC=8A=A4=EC=97=90=20?= =?UTF-8?q?=EB=A1=9C=EA=B1=B0=20=EC=B6=94=EA=B0=80=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/slack/slackFake.service.ts | 54 +++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/src/slack/slackFake.service.ts b/src/slack/slackFake.service.ts index 0f93325..3bae8b5 100644 --- a/src/slack/slackFake.service.ts +++ b/src/slack/slackFake.service.ts @@ -17,29 +17,69 @@ import { export class SlackFakeService { constructor() {} - async findSlackUserIdByEmail(email: string) {} + async findSlackUserIdByEmail(email: string) { + Logger.log( + 'findSlackUserIdByEmail' + JSON.stringify(email), + 'SlackFakeService' + ); + } async sendDMwithValidationNumber( slackValidationNumberDMDto: SlackValidationNumberDMDto - ) {} + ) { + Logger.log( + 'sendDMwithValidationNumber' + JSON.stringify(slackValidationNumberDMDto), + 'SlackFakeService' + ); + } async orderStateChangedByAdminEvent( slackOrderStateChangeDto: SlackOrderStateChangeDto - ) {} + ) { + Logger.log( + 'orderStateChangedByAdminEvent' + + JSON.stringify(slackOrderStateChangeDto), + 'SlackFakeService' + ); + } - async newOrderAlarm(slackNewOrderDto: SlackNewOrderDto) {} + async newOrderAlarm(slackNewOrderDto: SlackNewOrderDto) { + Logger.log( + 'newOrderAlarm' + JSON.stringify(slackNewOrderDto), + 'SlackFakeService' + ); + } async ticketStateChangedByAdminEvent( slackTicketStateChangeDto: SlackTicketStateChangeDto - ) {} + ) { + Logger.log( + 'ticketStateChangedByAdminEvent' + + JSON.stringify(slackTicketStateChangeDto), + 'SlackFakeService' + ); + } async ticketQREnterEvent( slackTicketQREnterEventDto: SlackTicketQREnterEventDto - ) {} + ) { + Logger.log( + 'ticketQREnterEvent' + JSON.stringify(slackTicketQREnterEventDto), + 'SlackFakeService' + ); + } async backendInternelServerError( path: string, body: string, errorStack: string | undefined - ) {} + ) { + Logger.log( + 'backendInternelServerError' + + JSON.stringify(path) + + JSON.stringify(body) + + JSON.stringify(errorStack), + 'SlackFakeService' + ); + } } From 0d9dc8b30a43c7feb02798c139be8c403b91a1ee Mon Sep 17 00:00:00 2001 From: gengminy Date: Tue, 26 Jul 2022 01:26:24 +0900 Subject: [PATCH 02/21] =?UTF-8?q?:hammer:=20fix(socket):=20SocketService?= =?UTF-8?q?=20emitToAll=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20#51?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/socket/socket-admin.gateway.ts | 4 +--- src/socket/socket.service.ts | 6 +++++ src/tickets/dtos/update-ticket-status.dto.ts | 2 +- src/tickets/tickets.service.ts | 24 +++++++------------- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/socket/socket-admin.gateway.ts b/src/socket/socket-admin.gateway.ts index 343d938..6a40cc2 100644 --- a/src/socket/socket-admin.gateway.ts +++ b/src/socket/socket-admin.gateway.ts @@ -1,4 +1,4 @@ -import { Logger, UnauthorizedException, UseGuards } from '@nestjs/common'; +import { Logger, UnauthorizedException } from '@nestjs/common'; import { ConnectedSocket, OnGatewayConnection, @@ -10,8 +10,6 @@ import { import { Namespace, Server, Socket } from 'socket.io'; import { AuthService } from 'src/auth/auth.service'; import { Role } from 'src/common/consts/enum'; -import { Roles } from 'src/common/decorators/roles.decorator'; -import { SocketGuard } from './socket.guard'; // @UseGuards(SocketGuard) // @Roles(Role.Admin) diff --git a/src/socket/socket.service.ts b/src/socket/socket.service.ts index 88f4d89..9cc63bd 100644 --- a/src/socket/socket.service.ts +++ b/src/socket/socket.service.ts @@ -35,4 +35,10 @@ export class SocketService { throw new GatewayTimeoutException('소켓 서버에 연결할 수 없습니다'); } } + + //양쪽 + async emitToAll(ticketEntryResponseDto: TicketEntryResponseDto) { + await this.emitToUser(ticketEntryResponseDto); + await this.emitToAdmin(ticketEntryResponseDto); + } } diff --git a/src/tickets/dtos/update-ticket-status.dto.ts b/src/tickets/dtos/update-ticket-status.dto.ts index 0cbff18..4295976 100644 --- a/src/tickets/dtos/update-ticket-status.dto.ts +++ b/src/tickets/dtos/update-ticket-status.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Expose } from 'class-transformer'; -import { IsEnum, IsNumber, IsString } from 'class-validator'; +import { IsEnum, IsNumber } from 'class-validator'; import { TicketStatus } from 'src/common/consts/enum'; export class UpdateTicketStatusDto { diff --git a/src/tickets/tickets.service.ts b/src/tickets/tickets.service.ts index 6afaea5..35a9896 100644 --- a/src/tickets/tickets.service.ts +++ b/src/tickets/tickets.service.ts @@ -114,11 +114,9 @@ export class TicketsService { ticket, admin.name, false, - '[입장실패] - 공연 날짜가 일치하지 않습니다' + '[입장실패] 공연 날짜가 일치하지 않습니다' ); - this.logger.error('티켓 날짜 오류 - 공연 날짜가 일치하지 않습니다'); - this.socketService.emitToUser(failureResponse); - this.socketService.emitToAdmin(failureResponse); + this.socketService.emitToAll(failureResponse); throw new BadRequestException('공연 날짜가 일치하지 않습니다'); } @@ -128,11 +126,9 @@ export class TicketsService { ticket, admin.name, false, - '[입장실패] - 이미 입장 완료된 티켓입니다' + '[입장실패] 이미 입장 완료된 티켓입니다' ); - this.logger.error('티켓 상태 오류 - 이미 입장 완료된 티켓입니다'); - this.socketService.emitToUser(failureResponse); - this.socketService.emitToAdmin(failureResponse); + this.socketService.emitToAll(failureResponse); throw new BadRequestException('이미 입장 완료된 티켓입니다'); } @@ -150,18 +146,14 @@ export class TicketsService { true, `[입장성공] ${ticket.user?.name}님이 입장하셨습니다` ); - - this.socketService.emitToUser(successResponse); - this.socketService.emitToAdmin(successResponse); + this.logger.log(`${ticket.user?.name}님이 입장하셨습니다`); + this.socketService.emitToAll(successResponse); return successResponse; } catch (e) { await queryRunner.rollbackTransaction(); - + this.logger.error(`티켓 상태 오류 - ${e.message}`); // 내부 예외 그대로 던짐 - if (e) { - throw e; - } - throw new InternalServerErrorException('Ticket db 에러'); + throw e; } finally { await queryRunner.release(); } From 115de8cf01082c154f19c10407fd10fed0f4fa86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EC=A7=84?= Date: Tue, 26 Jul 2022 01:12:27 +0900 Subject: [PATCH 03/21] =?UTF-8?q?:rocket:=20feat(order):=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20#42?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 151 +++++++++++++----- src/database/repositories/order.repository.ts | 37 +++++ src/orders/dtos/request-order.dto.ts | 17 ++ src/orders/orders.controller.ts | 37 +++++ src/orders/orders.module.ts | 13 +- src/orders/orders.service.ts | 59 +++++++ 6 files changed, 275 insertions(+), 39 deletions(-) create mode 100644 src/database/repositories/order.repository.ts create mode 100644 src/orders/dtos/request-order.dto.ts create mode 100644 src/orders/orders.controller.ts create mode 100644 src/orders/orders.service.ts diff --git a/package-lock.json b/package-lock.json index 8129434..79ed842 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "ticket-backend-22th", "version": "0.0.1", "license": "UNLICENSED", "dependencies": { @@ -917,6 +918,13 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "optional": true, + "peer": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -3405,6 +3413,47 @@ "node": ">=10.1" } }, + "node_modules/bull/node_modules/denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/bull/node_modules/ioredis": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", + "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "dependencies": { + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.isarguments": "^3.1.0", + "p-map": "^2.1.0", + "redis-commands": "1.7.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/bull/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "engines": { + "node": ">=6" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -4192,9 +4241,11 @@ } }, "node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "optional": true, + "peer": true, "engines": { "node": ">=0.10" } @@ -5851,38 +5902,30 @@ } }, "node_modules/ioredis": { - "version": "4.28.5", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", - "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.2.2.tgz", + "integrity": "sha512-wryKc1ur8PcCmNwfcGkw5evouzpbDXxxkMkzPK8wl4xQfQf7lHe11Jotell5ikMVAtikXJEu/OJVaoV51BggRQ==", + "optional": true, + "peer": true, "dependencies": { + "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", - "debug": "^4.3.1", - "denque": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.0.1", "lodash.defaults": "^4.2.0", - "lodash.flatten": "^4.4.0", "lodash.isarguments": "^3.1.0", - "p-map": "^2.1.0", - "redis-commands": "1.7.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" }, "engines": { - "node": ">=6" + "node": ">=12.22.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/ioredis" } }, - "node_modules/ioredis/node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "engines": { - "node": ">=6" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -11659,6 +11702,13 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "optional": true, + "peer": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -13525,6 +13575,36 @@ "p-timeout": "^3.2.0", "semver": "^7.3.2", "uuid": "^8.3.0" + }, + "dependencies": { + "denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + }, + "ioredis": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", + "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "requires": { + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.isarguments": "^3.1.0", + "p-map": "^2.1.0", + "redis-commands": "1.7.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + } } }, "busboy": { @@ -14126,9 +14206,11 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "optional": true, + "peer": true }, "depd": { "version": "2.0.0", @@ -15353,28 +15435,21 @@ "dev": true }, "ioredis": { - "version": "4.28.5", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", - "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.2.2.tgz", + "integrity": "sha512-wryKc1ur8PcCmNwfcGkw5evouzpbDXxxkMkzPK8wl4xQfQf7lHe11Jotell5ikMVAtikXJEu/OJVaoV51BggRQ==", + "optional": true, + "peer": true, "requires": { + "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", - "debug": "^4.3.1", - "denque": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.0.1", "lodash.defaults": "^4.2.0", - "lodash.flatten": "^4.4.0", "lodash.isarguments": "^3.1.0", - "p-map": "^2.1.0", - "redis-commands": "1.7.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" - }, - "dependencies": { - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" - } } }, "ipaddr.js": { diff --git a/src/database/repositories/order.repository.ts b/src/database/repositories/order.repository.ts new file mode 100644 index 0000000..1186ae6 --- /dev/null +++ b/src/database/repositories/order.repository.ts @@ -0,0 +1,37 @@ +import { Injectable } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { RequestOrderDto } from "src/orders/dtos/request-order.dto"; +import { Repository } from "typeorm"; +import { Order } from "../entities/order.entity"; +import { User } from "../entities/user.entity"; + +@Injectable() +export class OrderRepository { + constructor( + @InjectRepository(Order) + private orderRepository: Repository + ) {} + + /** + * 주문을 생성한다 + * @param requestOrderDto {selection, ticketCount} + * @param user Request User + * @param totalPrice 총 입금할 금액 + * @returns 생성된 주문 + */ + async createOrder(requestOrderDto: RequestOrderDto, user: User, totalPrice: number): Promise { + const {selection, ticketCount} = requestOrderDto; + const order = this.orderRepository.create({ + selection, + ticketCount, + price: totalPrice, + user: user, + isFree: false + }); + await this.orderRepository.save(order); + return order; + } + + + +} \ No newline at end of file diff --git a/src/orders/dtos/request-order.dto.ts b/src/orders/dtos/request-order.dto.ts new file mode 100644 index 0000000..15caa82 --- /dev/null +++ b/src/orders/dtos/request-order.dto.ts @@ -0,0 +1,17 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { Expose } from "class-transformer"; +import { IsEnum, IsNotEmpty, isNotEmpty, IsNumber } from "class-validator"; +import { Order } from "src/database/entities/order.entity"; +import { OrderDate } from "../../common/consts/enum"; + +export class RequestOrderDto { + @ApiProperty({ description: '공연일자', enum: OrderDate }) + @IsEnum(OrderDate) + @Expose() + selection: OrderDate; + + @ApiProperty({ description: '티켓수량', type: Number }) + @IsNumber() + @Expose() + ticketCount: number; +} \ No newline at end of file diff --git a/src/orders/orders.controller.ts b/src/orders/orders.controller.ts new file mode 100644 index 0000000..2111adc --- /dev/null +++ b/src/orders/orders.controller.ts @@ -0,0 +1,37 @@ +import { Body, Controller, Post, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common'; +import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; +import { AccessTokenGuard } from 'src/auth/guards/AccessToken.guard'; +import { ReqUser } from 'src/common/decorators/user.decorator'; +import { Order } from 'src/database/entities/order.entity'; +import { User } from 'src/database/entities/user.entity'; +import { OrdersService } from './orders.service'; +import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; + +@ApiTags('orders') +@ApiBearerAuth('accessToken') +@Controller('orders') +@UseGuards(AccessTokenGuard) +export class OrdersController { + constructor( + private orderService: OrdersService) {} + + @ApiOperation({ + summary: '주문을 생성하고, 해당 주문의 티켓을 생성한다.' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Order + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken 권한이 없을 경우' + }) + @Post('') + createOrder(@Body() requestOrderDto: RequestOrderDto, + @ReqUser() user: User): Promise { + return this.orderService.createOrder(requestOrderDto, user); + } + +} + diff --git a/src/orders/orders.module.ts b/src/orders/orders.module.ts index 90c2cca..03bc483 100644 --- a/src/orders/orders.module.ts +++ b/src/orders/orders.module.ts @@ -1,4 +1,15 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Order } from 'src/database/entities/order.entity'; +import { OrderRepository } from 'src/database/repositories/order.repository'; +import { OrdersController } from './orders.controller'; +import { OrdersService } from './orders.service'; -@Module({}) +@Module({ + imports: [ + TypeOrmModule.forFeature([Order]) + ], + controllers: [OrdersController], + providers: [OrdersService, OrderRepository] +}) export class OrdersModule {} diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts new file mode 100644 index 0000000..5da7b66 --- /dev/null +++ b/src/orders/orders.service.ts @@ -0,0 +1,59 @@ +import { BadRequestException, Injectable } from '@nestjs/common'; +import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; +import { Order } from 'src/database/entities/order.entity'; +import { User } from 'src/database/entities/user.entity'; +import { OrderRepository } from 'src/database/repositories/order.repository'; + +@Injectable() +export class OrdersService { + constructor(private orderRepository: OrderRepository) {} + + // 가격 책정 함수 : 단지 가독성을 위해 함수로 뺌 + getTotalPrice(requestOrderDto: RequestOrderDto): number { + const {selection, ticketCount} = requestOrderDto; + const pricePerTicket = 3000; // 티켓 한 장 가격 + const discountForBoth = 1000; // 양일권에 대한 할인 가격 + + let totalPrice = pricePerTicket * ticketCount; + + if (selection === 'BOTH') { + // ticketCount = 양일권 개수 + totalPrice = (totalPrice * 2) - (discountForBoth * ticketCount); + } + return totalPrice; + } + + /** + * selection과 ticketCount를 요청받아서 가격 책정 후 주문을 생성하고, + * 해당 주문에 포함되는 모든 티켓을 각각 생성한다. + * @param requestOrderDto {selection, ticketCount} + * @param user Request User + */ + async createOrder(requestOrderDto: RequestOrderDto, user: User): Promise { + const {selection, ticketCount} = requestOrderDto; + const totalPrice = this.getTotalPrice(requestOrderDto); // 가격 책정 + const order = await this.orderRepository.createOrder(requestOrderDto, user, totalPrice); + + for (let i = 0; i < ticketCount; i++) { + if (selection === 'BOTH') { + + } else { + + } + } + + /* + switch(selection) { + case 'BOTH': + break; + case 'YB': + break; + case 'OB': + break; + default: + throw new BadRequestException(`${selection} 값을 확인해주세요`) + } + */ + return order; + } +} From 7d6735f186dd9c4bacfd47355ad9755bdbb9543e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EC=A7=84?= Date: Tue, 26 Jul 2022 02:48:32 +0900 Subject: [PATCH 04/21] =?UTF-8?q?:rocket:=20feat(order):=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EC=83=9D=EC=84=B1+=ED=8B=B0=EC=BC=93=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20#42?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repositories/ticket.repository.ts | 2 - src/orders/orders.controller.ts | 2 +- src/orders/orders.module.ts | 4 +- src/orders/orders.service.ts | 88 ++++++++++++++----- src/tickets/dtos/create-ticket.dto.ts | 4 +- 5 files changed, 71 insertions(+), 29 deletions(-) diff --git a/src/database/repositories/ticket.repository.ts b/src/database/repositories/ticket.repository.ts index 7f806fc..78c3f9e 100644 --- a/src/database/repositories/ticket.repository.ts +++ b/src/database/repositories/ticket.repository.ts @@ -150,8 +150,6 @@ export class TicketRepository { async createTicket(createTicketDto: CreateTicketDto): Promise { const { user, order, date } = createTicketDto; - //order = orderRepository.findOne(order) - const ticket = this.ticketRepository.create({ date: date, user: user, diff --git a/src/orders/orders.controller.ts b/src/orders/orders.controller.ts index 2111adc..bcda476 100644 --- a/src/orders/orders.controller.ts +++ b/src/orders/orders.controller.ts @@ -33,5 +33,5 @@ export class OrdersController { return this.orderService.createOrder(requestOrderDto, user); } -} +} diff --git a/src/orders/orders.module.ts b/src/orders/orders.module.ts index 03bc483..af1109b 100644 --- a/src/orders/orders.module.ts +++ b/src/orders/orders.module.ts @@ -2,12 +2,14 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Order } from 'src/database/entities/order.entity'; import { OrderRepository } from 'src/database/repositories/order.repository'; +import { TicketsModule } from 'src/tickets/tickets.module'; import { OrdersController } from './orders.controller'; import { OrdersService } from './orders.service'; @Module({ imports: [ - TypeOrmModule.forFeature([Order]) + TypeOrmModule.forFeature([Order]), + TicketsModule ], controllers: [OrdersController], providers: [OrdersService, OrderRepository] diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts index 5da7b66..c8f3aff 100644 --- a/src/orders/orders.service.ts +++ b/src/orders/orders.service.ts @@ -1,12 +1,24 @@ -import { BadRequestException, Injectable } from '@nestjs/common'; +import { BadRequestException, Injectable, InternalServerErrorException } from '@nestjs/common'; import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; import { Order } from 'src/database/entities/order.entity'; import { User } from 'src/database/entities/user.entity'; import { OrderRepository } from 'src/database/repositories/order.repository'; +import { OrderDate, PerformanceDate } from 'src/common/consts/enum'; +import { TicketsService } from 'src/tickets/tickets.service'; +import { DataSource } from 'typeorm'; +import { getConnectedRepository } from 'src/common/funcs/getConnectedRepository'; +import { TicketRepository } from 'src/database/repositories/ticket.repository'; +import { Ticket } from 'src/database/entities/ticket.entity'; +import e from 'express'; @Injectable() export class OrdersService { - constructor(private orderRepository: OrderRepository) {} + constructor( + private orderRepository: OrderRepository, + private ticketService: TicketsService, + private dataSource: DataSource + ) {} + // 가격 책정 함수 : 단지 가독성을 위해 함수로 뺌 getTotalPrice(requestOrderDto: RequestOrderDto): number { @@ -16,7 +28,7 @@ export class OrdersService { let totalPrice = pricePerTicket * ticketCount; - if (selection === 'BOTH') { + if (selection === OrderDate.BOTH) { // ticketCount = 양일권 개수 totalPrice = (totalPrice * 2) - (discountForBoth * ticketCount); } @@ -28,32 +40,64 @@ export class OrdersService { * 해당 주문에 포함되는 모든 티켓을 각각 생성한다. * @param requestOrderDto {selection, ticketCount} * @param user Request User + * @returns Order */ async createOrder(requestOrderDto: RequestOrderDto, user: User): Promise { const {selection, ticketCount} = requestOrderDto; const totalPrice = this.getTotalPrice(requestOrderDto); // 가격 책정 - const order = await this.orderRepository.createOrder(requestOrderDto, user, totalPrice); - for (let i = 0; i < ticketCount; i++) { - if (selection === 'BOTH') { - - } else { + // 양일권일 경우 요청수량 * 2 해서 저장 + if (selection === OrderDate.BOTH) { + requestOrderDto.ticketCount *= 2; + } + + const queryRunner = this.dataSource.createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); + + const connectedOrder = getConnectedRepository( + OrderRepository, + queryRunner, + Order + ); + const connectedTicket = getConnectedRepository( + TicketRepository, + queryRunner, + Ticket + ); + try { + const order = await connectedOrder.createOrder(requestOrderDto, user, totalPrice); + + //티켓 수량 만큼 반복해서 생성 + for (let i = 0; i < ticketCount; i++) { + if (selection === OrderDate.BOTH || selection === OrderDate.YB) { + const createTicketDto = { + date: PerformanceDate.YB, + order, + user + } + await connectedTicket.createTicket(createTicketDto); + } + if (selection === OrderDate.BOTH || selection === OrderDate.OB) { + const createTicketDto = { + date: PerformanceDate.OB, + order, + user + } + await connectedTicket.createTicket(createTicketDto); + } } - } + await queryRunner.commitTransaction(); + return order; - /* - switch(selection) { - case 'BOTH': - break; - case 'YB': - break; - case 'OB': - break; - default: - throw new BadRequestException(`${selection} 값을 확인해주세요`) - } - */ - return order; + } catch (e) { + // 주문 생성 실패시 Error + await queryRunner.rollbackTransaction(); + throw e; + + } finally { + await queryRunner.release(); + } } } diff --git a/src/tickets/dtos/create-ticket.dto.ts b/src/tickets/dtos/create-ticket.dto.ts index 9ecfcbb..0df8fbb 100644 --- a/src/tickets/dtos/create-ticket.dto.ts +++ b/src/tickets/dtos/create-ticket.dto.ts @@ -5,9 +5,7 @@ import { Ticket } from 'src/database/entities/ticket.entity'; export class CreateTicketDto extends PickType(PartialType(Ticket), [ 'date', 'order', - 'user', - 'createdAt', - 'updatedAt' + 'user' ] as const) { // @ApiProperty({ // description: '주문한 유저에 대한 정보입니다.', From 16e260049b867bc0fdca1aaa6a55c55057c4ee3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EC=A7=84?= Date: Tue, 26 Jul 2022 03:30:21 +0900 Subject: [PATCH 05/21] =?UTF-8?q?:hammer:=20fix(order):=20=ED=8B=B0?= =?UTF-8?q?=EC=BC=93=EC=88=98=EB=9F=89validation=EC=B6=94=EA=B0=80#42?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/orders/dtos/request-order.dto.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/orders/dtos/request-order.dto.ts b/src/orders/dtos/request-order.dto.ts index 15caa82..b86a2c0 100644 --- a/src/orders/dtos/request-order.dto.ts +++ b/src/orders/dtos/request-order.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from "@nestjs/swagger"; import { Expose } from "class-transformer"; -import { IsEnum, IsNotEmpty, isNotEmpty, IsNumber } from "class-validator"; +import { IsEnum, IsIn, IsNotEmpty, isNotEmpty, IsNumber } from "class-validator"; import { Order } from "src/database/entities/order.entity"; import { OrderDate } from "../../common/consts/enum"; @@ -12,6 +12,7 @@ export class RequestOrderDto { @ApiProperty({ description: '티켓수량', type: Number }) @IsNumber() + @IsIn([1,2,3]) @Expose() ticketCount: number; } \ No newline at end of file From 3d9572331ae5b2c67b733642b7885259640e5d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EC=A7=84?= Date: Tue, 26 Jul 2022 03:58:46 +0900 Subject: [PATCH 06/21] =?UTF-8?q?:hammer:=20fix(order):=20=ED=8B=B0?= =?UTF-8?q?=EC=BC=93=EC=83=9D=EC=84=B1=20=ED=95=9C=EB=B2=88=EC=97=90=20?= =?UTF-8?q?=EB=B9=84=EB=8F=99=EA=B8=B0=EC=9A=94=EC=B2=AD=20=EB=A6=AC?= =?UTF-8?q?=ED=8E=99=ED=86=A0=EB=A7=81#42?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/orders/orders.service.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts index c8f3aff..ed8af7a 100644 --- a/src/orders/orders.service.ts +++ b/src/orders/orders.service.ts @@ -67,9 +67,12 @@ export class OrdersService { ); try { + // 주문 생성 const order = await connectedOrder.createOrder(requestOrderDto, user, totalPrice); - //티켓 수량 만큼 반복해서 생성 + // ticketList에 생성할 티켓을 모두 담은 후 한번에 비동기요청 + const ticketList = new Array; + for (let i = 0; i < ticketCount; i++) { if (selection === OrderDate.BOTH || selection === OrderDate.YB) { const createTicketDto = { @@ -77,7 +80,7 @@ export class OrdersService { order, user } - await connectedTicket.createTicket(createTicketDto); + ticketList.push(createTicketDto); } if (selection === OrderDate.BOTH || selection === OrderDate.OB) { const createTicketDto = { @@ -85,9 +88,11 @@ export class OrdersService { order, user } - await connectedTicket.createTicket(createTicketDto); + ticketList.push(createTicketDto); } } + await Promise.all(ticketList.map((dto) => connectedTicket.createTicket(dto))); + await queryRunner.commitTransaction(); return order; From e442a6a35c0c02df89f357bd03e13af8cf96634e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=A4=80?= Date: Tue, 26 Jul 2022 16:18:11 +0900 Subject: [PATCH 07/21] =?UTF-8?q?=EB=B3=91=ED=95=A9=20=EC=B6=A9=EB=8F=8C?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 160 +++++++++++++++++- package.json | 1 + src/database/entities/ticket.entity.ts | 2 +- src/database/entities/user.entity.ts | 2 +- .../repositories/ticket.repository.ts | 3 +- src/queue/queue.consumer.ts | 24 +++ src/queue/queue.module.ts | 13 +- src/queue/queue.service.ts | 22 ++- src/slack/slack.module.ts | 4 +- src/slack/slack.service.ts | 3 + src/tickets/tickets.module.ts | 3 + src/tickets/tickets.service.ts | 6 +- 12 files changed, 225 insertions(+), 18 deletions(-) create mode 100644 src/queue/queue.consumer.ts diff --git a/package-lock.json b/package-lock.json index 79ed842..46be023 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0", + "save": "^2.5.0", "swagger-ui-express": "^4.4.0", "typeorm": "^0.3.7", "uuid": "^8.3.2", @@ -4365,6 +4366,11 @@ "node": ">=12" } }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -4931,6 +4937,20 @@ "node": ">= 0.6" } }, + "node_modules/event-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", + "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", + "dependencies": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -5390,6 +5410,11 @@ "node": ">= 0.6" } }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -7509,6 +7534,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -7743,6 +7773,11 @@ "tmpl": "1.0.5" } }, + "node_modules/map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==" + }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -7853,6 +7888,11 @@ "node": ">=6" } }, + "node_modules/mingo": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/mingo/-/mingo-1.3.3.tgz", + "integrity": "sha512-Y4wGTD/M7AMqF8QxKaBGps+axq/Z48hdtRAeiKtInkEXMLzUWUwT0OPDzrB26xrav9GF1AOYJfwVWPcLwnkgTA==" + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -8460,6 +8500,14 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dependencies": { + "through": "~2.3" + } + }, "node_modules/pg": { "version": "8.7.3", "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz", @@ -9102,6 +9150,17 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/save": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/save/-/save-2.5.0.tgz", + "integrity": "sha512-xiVLpKVbx8EmW0HDkNRjYL271OnIRCo8VGWAEq6/K+E0dgNrwKV2xvKXdfPj6HGYA6l760800LyewSY3ooljCg==", + "dependencies": { + "async": "^3.2.2", + "event-stream": "^4.0.1", + "lodash.assign": "^4.2.0", + "mingo": "1" + } + }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -9454,6 +9513,17 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, "node_modules/split2": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", @@ -9510,6 +9580,15 @@ "node": ">= 0.8" } }, + "node_modules/stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, "node_modules/stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", @@ -9905,8 +9984,7 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/tmp": { "version": "0.0.33", @@ -14295,6 +14373,11 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz", "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==" }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -14706,6 +14789,20 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, + "event-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", + "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", + "requires": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -15077,6 +15174,11 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + }, "fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -16651,6 +16753,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" + }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -16843,6 +16950,11 @@ "tmpl": "1.0.5" } }, + "map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==" + }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -16923,6 +17035,11 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "mingo": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/mingo/-/mingo-1.3.3.tgz", + "integrity": "sha512-Y4wGTD/M7AMqF8QxKaBGps+axq/Z48hdtRAeiKtInkEXMLzUWUwT0OPDzrB26xrav9GF1AOYJfwVWPcLwnkgTA==" + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -17381,6 +17498,14 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "requires": { + "through": "~2.3" + } + }, "pg": { "version": "8.7.3", "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz", @@ -17828,6 +17953,17 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "save": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/save/-/save-2.5.0.tgz", + "integrity": "sha512-xiVLpKVbx8EmW0HDkNRjYL271OnIRCo8VGWAEq6/K+E0dgNrwKV2xvKXdfPj6HGYA6l760800LyewSY3ooljCg==", + "requires": { + "async": "^3.2.2", + "event-stream": "^4.0.1", + "lodash.assign": "^4.2.0", + "mingo": "1" + } + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -18112,6 +18248,14 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, "split2": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", @@ -18155,6 +18299,15 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "requires": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, "stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", @@ -18448,8 +18601,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "tmp": { "version": "0.0.33", diff --git a/package.json b/package.json index e35defd..4350e3d 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0", + "save": "^2.5.0", "swagger-ui-express": "^4.4.0", "typeorm": "^0.3.7", "uuid": "^8.3.2", diff --git a/src/database/entities/ticket.entity.ts b/src/database/entities/ticket.entity.ts index 5109d99..ca6e330 100644 --- a/src/database/entities/ticket.entity.ts +++ b/src/database/entities/ticket.entity.ts @@ -84,7 +84,7 @@ export class Ticket { }) @Type(() => UserProfileDto) @Expose() - @ManyToOne(type => User, user => user.ticket, { eager: false }) + @ManyToOne(type => User, user => user.ticket, { eager: false}) public user: User; @ApiProperty({ diff --git a/src/database/entities/user.entity.ts b/src/database/entities/user.entity.ts index 774f157..ed75379 100644 --- a/src/database/entities/user.entity.ts +++ b/src/database/entities/user.entity.ts @@ -68,7 +68,7 @@ export class User { type: () => [Ticket] }) @Expose() - @OneToMany(type => Ticket, ticket => ticket.user, { eager: true }) + @OneToMany(type => Ticket, ticket => ticket.user, { eager: false }) public ticket: Ticket[]; @ApiProperty({ diff --git a/src/database/repositories/ticket.repository.ts b/src/database/repositories/ticket.repository.ts index 78c3f9e..fdbcd0d 100644 --- a/src/database/repositories/ticket.repository.ts +++ b/src/database/repositories/ticket.repository.ts @@ -31,7 +31,8 @@ export class TicketRepository { const ticket = await this.ticketRepository.findOne({ where: { id: ticketId - } + }, + relations: ['user'] }); if (!ticket) { diff --git a/src/queue/queue.consumer.ts b/src/queue/queue.consumer.ts new file mode 100644 index 0000000..8be1529 --- /dev/null +++ b/src/queue/queue.consumer.ts @@ -0,0 +1,24 @@ +import { OnQueueActive, Process, Processor } from "@nestjs/bull"; +import Bull, { Job } from "bull"; +import { SlackTicketStateChangeDto } from "src/slack/dtos"; +import { SlackService } from "src/slack/slack.service"; + +@Processor('updateTicketStatusQ') +export class QueueConsumer { + constructor(private slackService: SlackService) {} + + @Process('updateTicketStatus') + async handleUpdateTicketStatus(job: Job) { + const ticketStatusChangeDto = job.data; + console.log(job.data); + console.log("slackService:" + this.slackService.ticketStateChangedByAdminEvent) + await this.slackService.ticketStateChangedByAdminEvent(ticketStatusChangeDto); + } + + // @OnQueueActive() + // onActive(job: Job) { + // const ticketStatusChangeDto: SlackTicketStateChangeDto = job.data; + // console.log("통과"); + // const result = this.slackService.ticketStateChangedByAdminEvent(ticketStatusChangeDto); + // } +} \ No newline at end of file diff --git a/src/queue/queue.module.ts b/src/queue/queue.module.ts index ef5d4e2..049166e 100644 --- a/src/queue/queue.module.ts +++ b/src/queue/queue.module.ts @@ -1,18 +1,19 @@ import { BullModule } from '@nestjs/bull'; import { Module } from '@nestjs/common'; +import { SlackModule } from 'src/slack/slack.module'; +import { SlackService } from 'src/slack/slack.service'; +import { QueueConsumer } from './queue.consumer'; import { QueueService } from './queue.service'; @Module({ imports: [ BullModule.registerQueue( { - name: 'test' + name: 'updateTicketStatusQ' }, - { - name: 'test2' - } - ) + ), ], - providers: [QueueService] + providers: [QueueService, QueueConsumer,], + exports: [QueueService], }) export class QueueModule {} diff --git a/src/queue/queue.service.ts b/src/queue/queue.service.ts index dc8efe7..9358c8a 100644 --- a/src/queue/queue.service.ts +++ b/src/queue/queue.service.ts @@ -1,4 +1,24 @@ +import { InjectQueue } from '@nestjs/bull'; import { Injectable } from '@nestjs/common'; +import { Queue } from 'bull'; +import { create } from 'domain'; +import { Ticket } from 'src/database/entities/ticket.entity'; +import { User } from 'src/database/entities/user.entity'; +import { SlackTicketStateChangeDto } from 'src/slack/dtos'; @Injectable() -export class QueueService {} +export class QueueService { + constructor(@InjectQueue('updateTicketStatusQ') private updateTicketStatusQ: Queue) {} + + async updateTicketStatusJob(ticket: Ticket, admin: User) { + console.log("admin: " + admin.name); + console.log(ticket); + const job = await this.updateTicketStatusQ.add('updateTicketStatus', { + adminName: admin.name, + ticketId: ticket.id, + ticketStatus: ticket.status, + userName: ticket.user.name, + }) + } + +} diff --git a/src/slack/slack.module.ts b/src/slack/slack.module.ts index d5cd69f..26799cb 100644 --- a/src/slack/slack.module.ts +++ b/src/slack/slack.module.ts @@ -28,7 +28,7 @@ import { SlackFakeService } from './slackFake.service'; { provide: SlackService, useClass: - process.env.NODE_ENV === 'prod' ? SlackService : SlackFakeService + process.env.NODE_ENV === 'dev' ? SlackService : SlackService }, { provide: ADMIN_CHANNELID, @@ -56,7 +56,7 @@ import { SlackFakeService } from './slackFake.service'; { provide: SlackService, useClass: - process.env.NODE_ENV === 'prod' ? SlackService : SlackFakeService + process.env.NODE_ENV === 'dev' ? SlackService : SlackService } ] }) diff --git a/src/slack/slack.service.ts b/src/slack/slack.service.ts index 8c191c3..20a69b3 100644 --- a/src/slack/slack.service.ts +++ b/src/slack/slack.service.ts @@ -219,7 +219,10 @@ export class SlackService { ) { const { ticketId, userName, ticketStatus, adminName } = slackTicketStateChangeDto; + console.log("통과"); + console.log(ticketId, userName, ticketStatus, adminName); try { + console.log("통과"); const value = await lastValueFrom( this.httpService .post('/chat.postMessage', { diff --git a/src/tickets/tickets.module.ts b/src/tickets/tickets.module.ts index 1a496d8..9f3e657 100644 --- a/src/tickets/tickets.module.ts +++ b/src/tickets/tickets.module.ts @@ -3,6 +3,9 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { Ticket } from 'src/database/entities/ticket.entity'; import { TicketRepository } from 'src/database/repositories/ticket.repository'; import { SocketModule } from 'src/socket/socket.module'; +import { UserRepository } from 'src/database/repositories/user.repository'; +import { QueueModule } from 'src/queue/queue.module'; +import { QueueService } from 'src/queue/queue.service'; import { UsersModule } from 'src/users/users.module'; import { TicketsController } from './tickets.controller'; import { TicketsService } from './tickets.service'; diff --git a/src/tickets/tickets.service.ts b/src/tickets/tickets.service.ts index 35a9896..1a8942c 100644 --- a/src/tickets/tickets.service.ts +++ b/src/tickets/tickets.service.ts @@ -16,6 +16,8 @@ import { Ticket } from 'src/database/entities/ticket.entity'; import { User } from 'src/database/entities/user.entity'; import { TicketRepository } from 'src/database/repositories/ticket.repository'; import { SocketService } from 'src/socket/socket.service'; +import { UserRepository } from 'src/database/repositories/user.repository'; +import { QueueService } from 'src/queue/queue.service'; import { DataSource } from 'typeorm'; import { CreateTicketDto } from './dtos/create-ticket.dto'; import { TicketEntryResponseDto } from './dtos/ticket-entry-response.dto'; @@ -188,12 +190,12 @@ export class TicketsService { ticket.admin = admin; await connectedRepository.saveTicket(ticket); - + await this.queueService.updateTicketStatusJob(ticket, admin); await queryRunner.commitTransaction(); return ticket; } catch (e) { await queryRunner.rollbackTransaction(); - + throw e; //티켓 찾을때 Not Found Error 캐치 if (e) { throw e; From c03ebee841e5ff258622f49ce37689caf63023e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=A4=80?= Date: Tue, 26 Jul 2022 01:11:13 +0900 Subject: [PATCH 08/21] =?UTF-8?q?:hammer:=20refactor(queue):=20slackAlarmQ?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=20#38?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/queue/queue.consumer.ts | 13 ++----------- src/queue/queue.module.ts | 2 +- src/queue/queue.service.ts | 6 ++---- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/queue/queue.consumer.ts b/src/queue/queue.consumer.ts index 8be1529..0f0d321 100644 --- a/src/queue/queue.consumer.ts +++ b/src/queue/queue.consumer.ts @@ -3,22 +3,13 @@ import Bull, { Job } from "bull"; import { SlackTicketStateChangeDto } from "src/slack/dtos"; import { SlackService } from "src/slack/slack.service"; -@Processor('updateTicketStatusQ') +@Processor('slackAlarmQ') export class QueueConsumer { constructor(private slackService: SlackService) {} @Process('updateTicketStatus') async handleUpdateTicketStatus(job: Job) { const ticketStatusChangeDto = job.data; - console.log(job.data); - console.log("slackService:" + this.slackService.ticketStateChangedByAdminEvent) - await this.slackService.ticketStateChangedByAdminEvent(ticketStatusChangeDto); + await this.slackService.ticketQREnterEvent(ticketStatusChangeDto); } - - // @OnQueueActive() - // onActive(job: Job) { - // const ticketStatusChangeDto: SlackTicketStateChangeDto = job.data; - // console.log("통과"); - // const result = this.slackService.ticketStateChangedByAdminEvent(ticketStatusChangeDto); - // } } \ No newline at end of file diff --git a/src/queue/queue.module.ts b/src/queue/queue.module.ts index 049166e..1d508e4 100644 --- a/src/queue/queue.module.ts +++ b/src/queue/queue.module.ts @@ -9,7 +9,7 @@ import { QueueService } from './queue.service'; imports: [ BullModule.registerQueue( { - name: 'updateTicketStatusQ' + name: 'slackAlarmQ' }, ), ], diff --git a/src/queue/queue.service.ts b/src/queue/queue.service.ts index 9358c8a..96a6381 100644 --- a/src/queue/queue.service.ts +++ b/src/queue/queue.service.ts @@ -8,17 +8,15 @@ import { SlackTicketStateChangeDto } from 'src/slack/dtos'; @Injectable() export class QueueService { - constructor(@InjectQueue('updateTicketStatusQ') private updateTicketStatusQ: Queue) {} + constructor(@InjectQueue('slackAlarmQ') private slackAlarmQ: Queue) {} async updateTicketStatusJob(ticket: Ticket, admin: User) { console.log("admin: " + admin.name); console.log(ticket); - const job = await this.updateTicketStatusQ.add('updateTicketStatus', { + const job = await this.slackAlarmQ.add('updateTicketStatus', { adminName: admin.name, ticketId: ticket.id, - ticketStatus: ticket.status, userName: ticket.user.name, }) } - } From 9a4e40440f199fd6b0f9e8a8dcab2b2a267b1105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=A4=80?= Date: Tue, 26 Jul 2022 01:20:51 +0900 Subject: [PATCH 09/21] =?UTF-8?q?:rocket:=20feat(queue):=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=B2=98=EB=A6=AC=20=ED=95=B8=EB=93=A4=EB=9F=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#38?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/queue/queue.consumer.ts | 10 +++++++++- src/tickets/tickets.service.ts | 1 - 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/queue/queue.consumer.ts b/src/queue/queue.consumer.ts index 0f0d321..9b91c29 100644 --- a/src/queue/queue.consumer.ts +++ b/src/queue/queue.consumer.ts @@ -1,5 +1,7 @@ -import { OnQueueActive, Process, Processor } from "@nestjs/bull"; +import { OnQueueActive, OnQueueFailed, Process, Processor } from "@nestjs/bull"; import Bull, { Job } from "bull"; +import e from "express"; +import { Err } from "joi"; import { SlackTicketStateChangeDto } from "src/slack/dtos"; import { SlackService } from "src/slack/slack.service"; @@ -7,6 +9,12 @@ import { SlackService } from "src/slack/slack.service"; export class QueueConsumer { constructor(private slackService: SlackService) {} + @OnQueueFailed() + errHandler(job: Job, err: Err) { + console.log("error: " + err); + throw err; + } + @Process('updateTicketStatus') async handleUpdateTicketStatus(job: Job) { const ticketStatusChangeDto = job.data; diff --git a/src/tickets/tickets.service.ts b/src/tickets/tickets.service.ts index 1a8942c..9803fb7 100644 --- a/src/tickets/tickets.service.ts +++ b/src/tickets/tickets.service.ts @@ -195,7 +195,6 @@ export class TicketsService { return ticket; } catch (e) { await queryRunner.rollbackTransaction(); - throw e; //티켓 찾을때 Not Found Error 캐치 if (e) { throw e; From 4499f354b8870c88eab8b80bf26dfd6377e47df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=A4=80?= Date: Tue, 26 Jul 2022 16:14:34 +0900 Subject: [PATCH 10/21] =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20API=20=EB=A8=B8?= =?UTF-8?q?=EC=A7=80=EC=9A=A9=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/queue/queue.module.ts | 3 +++ src/queue/queue.service.ts | 9 ++++++++- src/tickets/tickets.service.ts | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/queue/queue.module.ts b/src/queue/queue.module.ts index 1d508e4..a879ba1 100644 --- a/src/queue/queue.module.ts +++ b/src/queue/queue.module.ts @@ -11,6 +11,9 @@ import { QueueService } from './queue.service'; { name: 'slackAlarmQ' }, + { + name: 'naverSmsQ' + }, ), ], providers: [QueueService, QueueConsumer,], diff --git a/src/queue/queue.service.ts b/src/queue/queue.service.ts index 96a6381..26e017a 100644 --- a/src/queue/queue.service.ts +++ b/src/queue/queue.service.ts @@ -8,7 +8,7 @@ import { SlackTicketStateChangeDto } from 'src/slack/dtos'; @Injectable() export class QueueService { - constructor(@InjectQueue('slackAlarmQ') private slackAlarmQ: Queue) {} + constructor(@InjectQueue('slackAlarmQ') private slackAlarmQ: Queue, @InjectQueue('naverSmsQ') private naverSmsQ: Queue) {} async updateTicketStatusJob(ticket: Ticket, admin: User) { console.log("admin: " + admin.name); @@ -19,4 +19,11 @@ export class QueueService { userName: ticket.user.name, }) } + + async sendNaverSmsMessageJob(phoneNumber: String, ) { + const job = await this.naverSmsQ.add('sendNaverSmsMessage', { + to: phoneNumber, + content: + }) + } } diff --git a/src/tickets/tickets.service.ts b/src/tickets/tickets.service.ts index 9803fb7..8d39cbc 100644 --- a/src/tickets/tickets.service.ts +++ b/src/tickets/tickets.service.ts @@ -210,7 +210,8 @@ export class TicketsService { * @param createTicketDto 티켓 생성 dto */ async createTicket(createTicketDto: CreateTicketDto): Promise { - return await this.ticketRepository.createTicket(createTicketDto); + const result = await this.ticketRepository.createTicket(createTicketDto); + return result; } async deleteTicketByUuid(ticketUuid: string): Promise { From 63885e2ba8c25900f6c20bda8e0dc4751335a282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EC=A7=84?= Date: Tue, 26 Jul 2022 16:33:11 +0900 Subject: [PATCH 11/21] =?UTF-8?q?:rocket:=20feat(order):=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EC=A3=BC=EB=AC=B8=EB=AA=A9=EB=A1=9D=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C,=20=EC=A3=BC=EB=AC=B8=EB=B3=84=20=ED=8B=B0=EC=BC=93?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20#55?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/database/repositories/order.repository.ts | 12 +++++ .../repositories/ticket.repository.ts | 12 +++++ src/orders/orders.controller.ts | 47 ++++++++++++++++++- src/orders/orders.service.ts | 4 ++ src/tickets/tickets.service.ts | 4 ++ 5 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/database/repositories/order.repository.ts b/src/database/repositories/order.repository.ts index 1186ae6..1372cd1 100644 --- a/src/database/repositories/order.repository.ts +++ b/src/database/repositories/order.repository.ts @@ -32,6 +32,18 @@ export class OrderRepository { return order; } + /** + * + * @param userId 해당 유저의 주문 목록을 가져온다 + * @returns Order배열 + */ + async findAllByUserId(userId: number): Promise { + return await this.orderRepository + .createQueryBuilder('order') + .where({ user: userId }) + .getMany(); + + } } \ No newline at end of file diff --git a/src/database/repositories/ticket.repository.ts b/src/database/repositories/ticket.repository.ts index 78c3f9e..aa7a1ad 100644 --- a/src/database/repositories/ticket.repository.ts +++ b/src/database/repositories/ticket.repository.ts @@ -132,6 +132,18 @@ export class TicketRepository { .getMany(); } + /** + * + * @param orderId 조회할 주문id + * @returns 해당 주문에 속한 Ticket 배열 + */ + async findAllByOrderId(orderId: number): Promise { + return await this.ticketRepository + .createQueryBuilder('ticket') + .where({ order: orderId - 10000 }) + .getMany(); + } + /** * 해당 티켓을 저장한다 * @param ticket 저장할 티켓 diff --git a/src/orders/orders.controller.ts b/src/orders/orders.controller.ts index bcda476..258f961 100644 --- a/src/orders/orders.controller.ts +++ b/src/orders/orders.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Post, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common'; +import { Body, Controller, Get, Param, Post, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common'; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; import { AccessTokenGuard } from 'src/auth/guards/AccessToken.guard'; import { ReqUser } from 'src/common/decorators/user.decorator'; @@ -6,6 +6,8 @@ import { Order } from 'src/database/entities/order.entity'; import { User } from 'src/database/entities/user.entity'; import { OrdersService } from './orders.service'; import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; +import { Ticket } from 'src/database/entities/ticket.entity'; +import { TicketsService } from 'src/tickets/tickets.service'; @ApiTags('orders') @ApiBearerAuth('accessToken') @@ -13,7 +15,9 @@ import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; @UseGuards(AccessTokenGuard) export class OrdersController { constructor( - private orderService: OrdersService) {} + private orderService: OrdersService, + private ticketService: TicketsService) {} + @ApiOperation({ summary: '주문을 생성하고, 해당 주문의 티켓을 생성한다.' @@ -33,5 +37,44 @@ export class OrdersController { return this.orderService.createOrder(requestOrderDto, user); } + + @ApiOperation({ + summary: '접근한 유저의 주문 목록을 불러온다' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Order, + isArray: true + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken이 없을 경우' + }) + @Get('') + getUserOrderList(@ReqUser() user: User): Promise { + return this.orderService.findAllByUserId(user.id); + } + + + @ApiOperation({ + summary: '해당 주문에 속한 티켓 목록을 불러온다' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Ticket, + isArray: true + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken이 없을 경우' + }) + @Get('/:orderId') + getTicketListByOrderId( + @Param('orderId') orderId: number, + @ReqUser() user: User): Promise { + return this.ticketService.findAllByOrderId(orderId); + } } diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts index ed8af7a..96a72d4 100644 --- a/src/orders/orders.service.ts +++ b/src/orders/orders.service.ts @@ -105,4 +105,8 @@ export class OrdersService { await queryRunner.release(); } } + + async findAllByUserId(userId: number): Promise { + return await this.orderRepository.findAllByUserId(userId); + } } diff --git a/src/tickets/tickets.service.ts b/src/tickets/tickets.service.ts index 35a9896..30c4485 100644 --- a/src/tickets/tickets.service.ts +++ b/src/tickets/tickets.service.ts @@ -71,6 +71,10 @@ export class TicketsService { return await this.ticketRepository.findAllByUserId(userId); } + async findAllByOrderId(orderId: number): Promise { + return await this.ticketRepository.findAllByOrderId(orderId); + } + async findAllWith( ticketFindDto: TicketFindDto, pageOptionsDto: PageOptionsDto From af6766e0c2da7edc8b8a67ddca8e1c0c83d8c8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EC=A7=84?= Date: Tue, 26 Jul 2022 16:57:26 +0900 Subject: [PATCH 12/21] =?UTF-8?q?:hammer:=20fix(order):=20eslint=EA=B9=94?= =?UTF-8?q?=EA=B5=AC=20=EC=BB=A4=EB=B0=8B=ED=95=B4=EB=B4=84=20#55?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 131 ++++++++++-------- package.json | 2 +- src/database/repositories/order.repository.ts | 55 ++++---- .../repositories/ticket.repository.ts | 2 +- 4 files changed, 103 insertions(+), 87 deletions(-) diff --git a/package-lock.json b/package-lock.json index 79ed842..639100b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "codecov": "^3.8.3", - "eslint": "^8.0.1", + "eslint": "^8.20.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^4.0.0", "husky": "^8.0.1", @@ -815,7 +815,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -827,7 +827,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1345,7 +1345,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -1387,7 +1387,7 @@ "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.14", @@ -2067,25 +2067,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "devOptional": true }, "node_modules/@types/babel__core": { "version": "7.1.19", @@ -2778,7 +2778,7 @@ "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, + "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -2986,7 +2986,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true }, "node_modules/argparse": { "version": "2.0.1", @@ -4066,7 +4066,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "node_modules/cron-parser": { "version": "4.5.0", @@ -4290,7 +4290,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.3.1" } @@ -4631,9 +4631,9 @@ } }, "node_modules/eslint": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.19.0.tgz", - "integrity": "sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", + "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", "dev": true, "dependencies": { "@eslint/eslintrc": "^1.3.0", @@ -7732,7 +7732,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -10086,7 +10086,7 @@ "version": "10.8.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", - "dev": true, + "devOptional": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -10129,7 +10129,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.4.0" } @@ -10464,7 +10464,7 @@ "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10565,7 +10565,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "node_modules/v8-to-istanbul": { "version": "8.1.1", @@ -11041,7 +11041,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -11608,7 +11608,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -11617,7 +11617,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -12040,7 +12040,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true + "devOptional": true }, "@jridgewell/set-array": { "version": "1.1.2", @@ -12075,7 +12075,7 @@ "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "devOptional": true }, "@jridgewell/trace-mapping": { "version": "0.3.14", @@ -12226,12 +12226,14 @@ "@nestjs/mapped-types": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.0.1.tgz", - "integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==" + "integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==", + "requires": {} }, "@nestjs/passport": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-8.2.2.tgz", - "integrity": "sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw==" + "integrity": "sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw==", + "requires": {} }, "@nestjs/platform-express": { "version": "8.4.7", @@ -12406,7 +12408,8 @@ "@redis/bloom": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.0.2.tgz", - "integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==" + "integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==", + "requires": {} }, "@redis/client": { "version": "1.2.0", @@ -12421,22 +12424,26 @@ "@redis/graph": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.0.1.tgz", - "integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==" + "integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==", + "requires": {} }, "@redis/json": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.3.tgz", - "integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==" + "integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==", + "requires": {} }, "@redis/search": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.0.6.tgz", - "integrity": "sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==" + "integrity": "sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==", + "requires": {} }, "@redis/time-series": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz", - "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==" + "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==", + "requires": {} }, "@sideway/address": { "version": "4.1.4", @@ -12489,25 +12496,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "devOptional": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "devOptional": true }, "@types/babel__core": { "version": "7.1.19", @@ -13107,7 +13114,7 @@ "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true + "devOptional": true }, "acorn-globals": { "version": "6.0.0", @@ -13131,13 +13138,15 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true + "dev": true, + "requires": {} }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -13250,7 +13259,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true }, "argparse": { "version": "2.0.1", @@ -14077,7 +14086,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "cron-parser": { "version": "4.5.0", @@ -14242,7 +14251,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "devOptional": true }, "diff-sequences": { "version": "27.5.1", @@ -14375,7 +14384,8 @@ "ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} } } }, @@ -14493,9 +14503,9 @@ } }, "eslint": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.19.0.tgz", - "integrity": "sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", + "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", "dev": true, "requires": { "@eslint/eslintrc": "^1.3.0", @@ -14594,7 +14604,8 @@ "version": "8.5.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-prettier": { "version": "4.2.1", @@ -15994,7 +16005,8 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "27.5.1", @@ -16832,7 +16844,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "makeerror": { "version": "1.0.12", @@ -17408,7 +17420,8 @@ "pg-pool": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz", - "integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==" + "integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==", + "requires": {} }, "pg-protocol": { "version": "1.5.0", @@ -17869,7 +17882,8 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "json-schema-traverse": { "version": "0.4.1", @@ -18569,7 +18583,7 @@ "version": "10.8.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", - "dev": true, + "devOptional": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -18590,7 +18604,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true + "devOptional": true } } }, @@ -18784,7 +18798,7 @@ "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true + "devOptional": true }, "universalify": { "version": "2.0.0", @@ -18850,7 +18864,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "v8-to-istanbul": { "version": "8.1.1", @@ -19134,7 +19148,8 @@ "version": "7.5.8", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", - "dev": true + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", @@ -19206,7 +19221,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "devOptional": true } } } diff --git a/package.json b/package.json index e35defd..407b78a 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "codecov": "^3.8.3", - "eslint": "^8.0.1", + "eslint": "^8.20.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^4.0.0", "husky": "^8.0.1", diff --git a/src/database/repositories/order.repository.ts b/src/database/repositories/order.repository.ts index 1372cd1..e4440ba 100644 --- a/src/database/repositories/order.repository.ts +++ b/src/database/repositories/order.repository.ts @@ -1,9 +1,9 @@ -import { Injectable } from "@nestjs/common"; -import { InjectRepository } from "@nestjs/typeorm"; -import { RequestOrderDto } from "src/orders/dtos/request-order.dto"; -import { Repository } from "typeorm"; -import { Order } from "../entities/order.entity"; -import { User } from "../entities/user.entity"; +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; +import { Repository } from 'typeorm'; +import { Order } from '../entities/order.entity'; +import { User } from '../entities/user.entity'; @Injectable() export class OrderRepository { @@ -19,31 +19,32 @@ export class OrderRepository { * @param totalPrice 총 입금할 금액 * @returns 생성된 주문 */ - async createOrder(requestOrderDto: RequestOrderDto, user: User, totalPrice: number): Promise { - const {selection, ticketCount} = requestOrderDto; - const order = this.orderRepository.create({ - selection, - ticketCount, - price: totalPrice, - user: user, - isFree: false - }); - await this.orderRepository.save(order); - return order; + async createOrder( + requestOrderDto: RequestOrderDto, + user: User, + totalPrice: number + ): Promise { + const { selection, ticketCount } = requestOrderDto; + const order = this.orderRepository.create({ + selection, + ticketCount, + price: totalPrice, + user: user, + isFree: false + }); + await this.orderRepository.save(order); + return order; } /** - * + * * @param userId 해당 유저의 주문 목록을 가져온다 * @returns Order배열 */ - async findAllByUserId(userId: number): Promise { - return await this.orderRepository - .createQueryBuilder('order') - .where({ user: userId }) - .getMany(); - + async findAllByUserId(userId: number): Promise { + return await this.orderRepository + .createQueryBuilder('order') + .where({ user: userId }) + .getMany(); } - - -} \ No newline at end of file +} diff --git a/src/database/repositories/ticket.repository.ts b/src/database/repositories/ticket.repository.ts index aa7a1ad..819678d 100644 --- a/src/database/repositories/ticket.repository.ts +++ b/src/database/repositories/ticket.repository.ts @@ -133,7 +133,7 @@ export class TicketRepository { } /** - * + * * @param orderId 조회할 주문id * @returns 해당 주문에 속한 Ticket 배열 */ From 815452db842dba9af2e873dffc46dbd0bc9e6152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EC=A7=84?= Date: Tue, 26 Jul 2022 17:27:46 +0900 Subject: [PATCH 13/21] =?UTF-8?q?:hammer:=20fix(order):=20orderId=20Pipe?= =?UTF-8?q?=EB=A1=9Ctransform=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20#55?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/pipes/orderId-validation.pipe.ts | 10 ++ .../repositories/ticket.repository.ts | 2 +- src/orders/orders.controller.ts | 141 ++++++++++-------- 3 files changed, 89 insertions(+), 64 deletions(-) create mode 100644 src/common/pipes/orderId-validation.pipe.ts diff --git a/src/common/pipes/orderId-validation.pipe.ts b/src/common/pipes/orderId-validation.pipe.ts new file mode 100644 index 0000000..2def576 --- /dev/null +++ b/src/common/pipes/orderId-validation.pipe.ts @@ -0,0 +1,10 @@ +import { PipeTransform } from '@nestjs/common'; + +export class OrderIdValidationPipe implements PipeTransform { + + transform(value: any) { + value = value - 10000; + return value; + } + +} \ No newline at end of file diff --git a/src/database/repositories/ticket.repository.ts b/src/database/repositories/ticket.repository.ts index 819678d..6ed2215 100644 --- a/src/database/repositories/ticket.repository.ts +++ b/src/database/repositories/ticket.repository.ts @@ -140,7 +140,7 @@ export class TicketRepository { async findAllByOrderId(orderId: number): Promise { return await this.ticketRepository .createQueryBuilder('ticket') - .where({ order: orderId - 10000 }) + .where({ order: orderId }) .getMany(); } diff --git a/src/orders/orders.controller.ts b/src/orders/orders.controller.ts index 258f961..f18d72f 100644 --- a/src/orders/orders.controller.ts +++ b/src/orders/orders.controller.ts @@ -1,5 +1,20 @@ -import { Body, Controller, Get, Param, Post, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common'; -import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; +import { + Body, + Controller, + Get, + Param, + Post, + UseGuards, + UsePipes, + ValidationPipe +} from '@nestjs/common'; +import { + ApiBearerAuth, + ApiOperation, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse +} from '@nestjs/swagger'; import { AccessTokenGuard } from 'src/auth/guards/AccessToken.guard'; import { ReqUser } from 'src/common/decorators/user.decorator'; import { Order } from 'src/database/entities/order.entity'; @@ -8,73 +23,73 @@ import { OrdersService } from './orders.service'; import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; import { Ticket } from 'src/database/entities/ticket.entity'; import { TicketsService } from 'src/tickets/tickets.service'; +import { OrderIdValidationPipe } from 'src/common/pipes/orderId-validation.pipe'; @ApiTags('orders') @ApiBearerAuth('accessToken') @Controller('orders') @UseGuards(AccessTokenGuard) export class OrdersController { - constructor( - private orderService: OrdersService, - private ticketService: TicketsService) {} + constructor( + private orderService: OrdersService, + private ticketService: TicketsService + ) {} + @ApiOperation({ + summary: '주문을 생성하고, 해당 주문의 티켓을 생성한다.' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Order + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken 권한이 없을 경우' + }) + @Post('') + createOrder( + @Body() requestOrderDto: RequestOrderDto, + @ReqUser() user: User + ): Promise { + return this.orderService.createOrder(requestOrderDto, user); + } - @ApiOperation({ - summary: '주문을 생성하고, 해당 주문의 티켓을 생성한다.' - }) - @ApiResponse({ - status: 200, - description: '요청 성공시', - type: Order - }) - @ApiUnauthorizedResponse({ - status: 401, - description: 'AccessToken 권한이 없을 경우' - }) - @Post('') - createOrder(@Body() requestOrderDto: RequestOrderDto, - @ReqUser() user: User): Promise { - return this.orderService.createOrder(requestOrderDto, user); - } - - - @ApiOperation({ - summary: '접근한 유저의 주문 목록을 불러온다' - }) - @ApiResponse({ - status: 200, - description: '요청 성공시', - type: Order, - isArray: true - }) - @ApiUnauthorizedResponse({ - status: 401, - description: 'AccessToken이 없을 경우' - }) - @Get('') - getUserOrderList(@ReqUser() user: User): Promise { - return this.orderService.findAllByUserId(user.id); - } - - - @ApiOperation({ - summary: '해당 주문에 속한 티켓 목록을 불러온다' - }) - @ApiResponse({ - status: 200, - description: '요청 성공시', - type: Ticket, - isArray: true - }) - @ApiUnauthorizedResponse({ - status: 401, - description: 'AccessToken이 없을 경우' - }) - @Get('/:orderId') - getTicketListByOrderId( - @Param('orderId') orderId: number, - @ReqUser() user: User): Promise { - return this.ticketService.findAllByOrderId(orderId); - } -} + @ApiOperation({ + summary: '접근한 유저의 주문 목록을 불러온다' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Order, + isArray: true + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken이 없을 경우' + }) + @Get('') + getUserOrderList(@ReqUser() user: User): Promise { + return this.orderService.findAllByUserId(user.id); + } + @ApiOperation({ + summary: '해당 주문에 속한 티켓 목록을 불러온다' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Ticket, + isArray: true + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken이 없을 경우' + }) + @Get('/:orderId') + getTicketListByOrderId( + @Param('orderId', OrderIdValidationPipe) orderId: number + ): Promise { + return this.ticketService.findAllByOrderId(orderId); + } +} From 5c929f67e2905fdfcb4445c2e8784ee0e0edcb67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=A4=80?= Date: Tue, 26 Jul 2022 20:20:11 +0900 Subject: [PATCH 14/21] =?UTF-8?q?:rocket:=20feat(queue):=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=20=EC=83=9D=EC=84=B1=20=EC=9A=94=EC=B2=AD=20=EC=8B=9C?= =?UTF-8?q?,=20=EC=83=9D=EC=84=B1=EB=90=98=EB=8A=94=20=ED=8B=B0=EC=BC=93?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EB=93=A4=20sms=EB=A1=9C=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EA=B8=B0=20#38?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 117 ++++++++++++++++++-------------- src/orders/orders.module.ts | 4 +- src/orders/orders.service.ts | 10 +-- src/queue/queue.consumer.sms.ts | 24 +++++++ src/queue/queue.consumer.ts | 40 ++++++----- src/queue/queue.module.ts | 19 ++++-- src/queue/queue.service.ts | 66 +++++++++++++----- src/slack/slack.module.ts | 6 +- src/slack/slack.service.ts | 4 +- src/sms/sms.service.ts | 1 - src/tickets/tickets.module.ts | 3 +- src/tickets/tickets.service.ts | 3 +- 12 files changed, 192 insertions(+), 105 deletions(-) create mode 100644 src/queue/queue.consumer.sms.ts diff --git a/package-lock.json b/package-lock.json index 46be023..a07d5d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -816,7 +816,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -828,7 +828,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1346,7 +1346,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -1388,7 +1388,7 @@ "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.14", @@ -2068,25 +2068,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "devOptional": true }, "node_modules/@types/babel__core": { "version": "7.1.19", @@ -2779,7 +2779,7 @@ "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, + "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -2987,7 +2987,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true }, "node_modules/argparse": { "version": "2.0.1", @@ -4067,7 +4067,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "node_modules/cron-parser": { "version": "4.5.0", @@ -4291,7 +4291,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.3.1" } @@ -7762,7 +7762,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -10164,7 +10164,7 @@ "version": "10.8.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", - "dev": true, + "devOptional": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -10207,7 +10207,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.4.0" } @@ -10542,7 +10542,7 @@ "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10643,7 +10643,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "node_modules/v8-to-istanbul": { "version": "8.1.1", @@ -11119,7 +11119,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -11686,7 +11686,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -11695,7 +11695,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -12118,7 +12118,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true + "devOptional": true }, "@jridgewell/set-array": { "version": "1.1.2", @@ -12153,7 +12153,7 @@ "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "devOptional": true }, "@jridgewell/trace-mapping": { "version": "0.3.14", @@ -12304,12 +12304,14 @@ "@nestjs/mapped-types": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.0.1.tgz", - "integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==" + "integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==", + "requires": {} }, "@nestjs/passport": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-8.2.2.tgz", - "integrity": "sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw==" + "integrity": "sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw==", + "requires": {} }, "@nestjs/platform-express": { "version": "8.4.7", @@ -12484,7 +12486,8 @@ "@redis/bloom": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.0.2.tgz", - "integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==" + "integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==", + "requires": {} }, "@redis/client": { "version": "1.2.0", @@ -12499,22 +12502,26 @@ "@redis/graph": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.0.1.tgz", - "integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==" + "integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==", + "requires": {} }, "@redis/json": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.3.tgz", - "integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==" + "integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==", + "requires": {} }, "@redis/search": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.0.6.tgz", - "integrity": "sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==" + "integrity": "sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==", + "requires": {} }, "@redis/time-series": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz", - "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==" + "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==", + "requires": {} }, "@sideway/address": { "version": "4.1.4", @@ -12567,25 +12574,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "devOptional": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "devOptional": true }, "@types/babel__core": { "version": "7.1.19", @@ -13185,7 +13192,7 @@ "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true + "devOptional": true }, "acorn-globals": { "version": "6.0.0", @@ -13209,13 +13216,15 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true + "dev": true, + "requires": {} }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -13328,7 +13337,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true }, "argparse": { "version": "2.0.1", @@ -14155,7 +14164,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "cron-parser": { "version": "4.5.0", @@ -14320,7 +14329,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "devOptional": true }, "diff-sequences": { "version": "27.5.1", @@ -14458,7 +14467,8 @@ "ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} } } }, @@ -14677,7 +14687,8 @@ "version": "8.5.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-prettier": { "version": "4.2.1", @@ -16096,7 +16107,8 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "27.5.1", @@ -16939,7 +16951,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "makeerror": { "version": "1.0.12", @@ -17533,7 +17545,8 @@ "pg-pool": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz", - "integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==" + "integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==", + "requires": {} }, "pg-protocol": { "version": "1.5.0", @@ -18005,7 +18018,8 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "json-schema-traverse": { "version": "0.4.1", @@ -18721,7 +18735,7 @@ "version": "10.8.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", - "dev": true, + "devOptional": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -18742,7 +18756,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true + "devOptional": true } } }, @@ -18936,7 +18950,7 @@ "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true + "devOptional": true }, "universalify": { "version": "2.0.0", @@ -19002,7 +19016,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "v8-to-istanbul": { "version": "8.1.1", @@ -19286,7 +19300,8 @@ "version": "7.5.8", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", - "dev": true + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", @@ -19358,7 +19373,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "devOptional": true } } } diff --git a/src/orders/orders.module.ts b/src/orders/orders.module.ts index af1109b..28221b1 100644 --- a/src/orders/orders.module.ts +++ b/src/orders/orders.module.ts @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Order } from 'src/database/entities/order.entity'; import { OrderRepository } from 'src/database/repositories/order.repository'; +import { QueueModule } from 'src/queue/queue.module'; import { TicketsModule } from 'src/tickets/tickets.module'; import { OrdersController } from './orders.controller'; import { OrdersService } from './orders.service'; @@ -9,7 +10,8 @@ import { OrdersService } from './orders.service'; @Module({ imports: [ TypeOrmModule.forFeature([Order]), - TicketsModule + TicketsModule, + QueueModule, ], controllers: [OrdersController], providers: [OrdersService, OrderRepository] diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts index ed8af7a..222e1cb 100644 --- a/src/orders/orders.service.ts +++ b/src/orders/orders.service.ts @@ -10,13 +10,15 @@ import { getConnectedRepository } from 'src/common/funcs/getConnectedRepository' import { TicketRepository } from 'src/database/repositories/ticket.repository'; import { Ticket } from 'src/database/entities/ticket.entity'; import e from 'express'; +import { QueueService } from 'src/queue/queue.service'; @Injectable() export class OrdersService { constructor( private orderRepository: OrderRepository, private ticketService: TicketsService, - private dataSource: DataSource + private dataSource: DataSource, + private queueService: QueueService, ) {} @@ -72,7 +74,6 @@ export class OrdersService { // ticketList에 생성할 티켓을 모두 담은 후 한번에 비동기요청 const ticketList = new Array; - for (let i = 0; i < ticketCount; i++) { if (selection === OrderDate.BOTH || selection === OrderDate.YB) { const createTicketDto = { @@ -91,8 +92,9 @@ export class OrdersService { ticketList.push(createTicketDto); } } - await Promise.all(ticketList.map((dto) => connectedTicket.createTicket(dto))); - + const ticketListForQ = await Promise.all(ticketList.map((dto) => {return connectedTicket.createTicket(dto);})); + this.queueService.createNewOrderJob(order); + this.queueService.sendNaverSmsForOrderJob(order, ticketListForQ); await queryRunner.commitTransaction(); return order; diff --git a/src/queue/queue.consumer.sms.ts b/src/queue/queue.consumer.sms.ts new file mode 100644 index 0000000..ba4d5cb --- /dev/null +++ b/src/queue/queue.consumer.sms.ts @@ -0,0 +1,24 @@ +import { OnQueueFailed, Process, Processor } from '@nestjs/bull'; +import { Job } from 'bull'; +import { plainToInstance } from 'class-transformer'; +import { Err } from 'joi'; +import { MessageDto } from 'src/sms/dtos/message.dto'; +import { SmsService } from 'src/sms/sms.service'; + +@Processor('naverSmsQ') +export class QueueConsumerSms { + constructor(private smsService: SmsService) {} + + @OnQueueFailed() + errHandler(job: Job, err: Err) { + console.log(`error: ` + err); + throw err; + } + + @Process('sendNaverSmsForOrder') + async handleSmsForOrder(job: Job) { + const data = job.data; + const messageDtoList = plainToInstance(MessageDto, data as MessageDto[]); + await this.smsService.sendMessages(messageDtoList); + } +} diff --git a/src/queue/queue.consumer.ts b/src/queue/queue.consumer.ts index 9b91c29..dc0ba4c 100644 --- a/src/queue/queue.consumer.ts +++ b/src/queue/queue.consumer.ts @@ -1,23 +1,27 @@ -import { OnQueueActive, OnQueueFailed, Process, Processor } from "@nestjs/bull"; -import Bull, { Job } from "bull"; -import e from "express"; -import { Err } from "joi"; -import { SlackTicketStateChangeDto } from "src/slack/dtos"; -import { SlackService } from "src/slack/slack.service"; +import { OnQueueFailed, Process, Processor } from '@nestjs/bull'; +import { Job } from 'bull'; +import { Err } from 'joi'; +import { SlackService } from 'src/slack/slack.service'; @Processor('slackAlarmQ') export class QueueConsumer { - constructor(private slackService: SlackService) {} + constructor(private slackService: SlackService) {} - @OnQueueFailed() - errHandler(job: Job, err: Err) { - console.log("error: " + err); - throw err; - } + @OnQueueFailed() + errHandler(job: Job, err: Err) { + console.log('error: ' + err); + throw err; + } - @Process('updateTicketStatus') - async handleUpdateTicketStatus(job: Job) { - const ticketStatusChangeDto = job.data; - await this.slackService.ticketQREnterEvent(ticketStatusChangeDto); - } -} \ No newline at end of file + @Process('updateTicketStatus') + async handleUpdateTicketStatus(job: Job) { + const ticketStatusChangeDto = job.data; + await this.slackService.ticketQREnterEvent(ticketStatusChangeDto); + } + + @Process('createNewOrder') + async handleCreateNewOrder(job: Job) { + const newOrderDto = job.data; + await this.slackService.newOrderAlarm(newOrderDto); + } +} diff --git a/src/queue/queue.module.ts b/src/queue/queue.module.ts index a879ba1..5856116 100644 --- a/src/queue/queue.module.ts +++ b/src/queue/queue.module.ts @@ -1,8 +1,11 @@ import { BullModule } from '@nestjs/bull'; import { Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import { SlackModule } from 'src/slack/slack.module'; -import { SlackService } from 'src/slack/slack.service'; +import { SmsModule } from 'src/sms/sms.module'; + import { QueueConsumer } from './queue.consumer'; +import { QueueConsumerSms } from './queue.consumer.sms'; import { QueueService } from './queue.service'; @Module({ @@ -13,10 +16,18 @@ import { QueueService } from './queue.service'; }, { name: 'naverSmsQ' - }, + } ), + SmsModule.forRootAsync({ + imports: [ConfigModule], + useFactory: async (configService: ConfigService) => ({ + isProd: configService.get('NODE_ENV') === 'dev' ? true : false + }), + inject: [ConfigService] + }), + SlackModule ], - providers: [QueueService, QueueConsumer,], - exports: [QueueService], + providers: [QueueService, QueueConsumer, QueueConsumerSms], + exports: [QueueService] }) export class QueueModule {} diff --git a/src/queue/queue.service.ts b/src/queue/queue.service.ts index 26e017a..b4d3126 100644 --- a/src/queue/queue.service.ts +++ b/src/queue/queue.service.ts @@ -1,29 +1,59 @@ import { InjectQueue } from '@nestjs/bull'; import { Injectable } from '@nestjs/common'; import { Queue } from 'bull'; -import { create } from 'domain'; +import { OrderDate, PerformanceDate } from 'src/common/consts/enum'; +import { Order } from 'src/database/entities/order.entity'; import { Ticket } from 'src/database/entities/ticket.entity'; import { User } from 'src/database/entities/user.entity'; -import { SlackTicketStateChangeDto } from 'src/slack/dtos'; @Injectable() export class QueueService { - constructor(@InjectQueue('slackAlarmQ') private slackAlarmQ: Queue, @InjectQueue('naverSmsQ') private naverSmsQ: Queue) {} + constructor( + @InjectQueue('slackAlarmQ') private slackAlarmQ: Queue, + @InjectQueue('naverSmsQ') private naverSmsQ: Queue + ) {} - async updateTicketStatusJob(ticket: Ticket, admin: User) { - console.log("admin: " + admin.name); - console.log(ticket); - const job = await this.slackAlarmQ.add('updateTicketStatus', { - adminName: admin.name, - ticketId: ticket.id, - userName: ticket.user.name, - }) - } + async updateTicketStatusJob(ticket: Ticket, admin: User) { + console.log('admin: ' + admin.name); + console.log(ticket); + const job = await this.slackAlarmQ.add('updateTicketStatus', { + adminName: admin.name, + ticketId: ticket.id, + userName: ticket.user.name + }); + return job; + } - async sendNaverSmsMessageJob(phoneNumber: String, ) { - const job = await this.naverSmsQ.add('sendNaverSmsMessage', { - to: phoneNumber, - content: - }) - } + async createNewOrderJob(order: Order) { + console.log('order: ' + order.id); + const job = await this.slackAlarmQ.add('createNewOrder', { + orderId: order.id, + userName: order.user.name, + orderTicketCount: order.ticketCount, + orderPrice: order.price + }); + return job; + } + + async sendNaverSmsForOrderJob(order: Order, ticketList: Ticket[]) { + const url = 'https://gosrock.band/tickets/'; + let obIdx = 1; + let ybIdx = 1; + const totalTicketCnt = order.selection == OrderDate.BOTH ? order.ticketCount/2 : order.ticketCount + const messageDtoList = ticketList.map(ticket => { + switch (ticket.date) { + case PerformanceDate.OB: + return { + to: order.user.phoneNumber, + content: `[${ticket.date}] 고티켓 (${obIdx++}/${totalTicketCnt}) \n\n ${url}${ticket.uuid}` + }; + case PerformanceDate.YB: + return { + to: order.user.phoneNumber, + content: `[${ticket.date}] 고티켓 (${ybIdx++}/${totalTicketCnt}) \n\n ${url}${ticket.uuid}` + }; + } + }); + this.naverSmsQ.add('sendNaverSmsForOrder', messageDtoList); + } } diff --git a/src/slack/slack.module.ts b/src/slack/slack.module.ts index 26799cb..4b014c2 100644 --- a/src/slack/slack.module.ts +++ b/src/slack/slack.module.ts @@ -27,8 +27,7 @@ import { SlackFakeService } from './slackFake.service'; providers: [ { provide: SlackService, - useClass: - process.env.NODE_ENV === 'dev' ? SlackService : SlackService + useClass: process.env.NODE_ENV === 'dev' ? SlackService : SlackService }, { provide: ADMIN_CHANNELID, @@ -55,8 +54,7 @@ import { SlackFakeService } from './slackFake.service'; exports: [ { provide: SlackService, - useClass: - process.env.NODE_ENV === 'dev' ? SlackService : SlackService + useClass: process.env.NODE_ENV === 'dev' ? SlackService : SlackService } ] }) diff --git a/src/slack/slack.service.ts b/src/slack/slack.service.ts index 20a69b3..6632b1b 100644 --- a/src/slack/slack.service.ts +++ b/src/slack/slack.service.ts @@ -161,6 +161,8 @@ export class SlackService { async newOrderAlarm(slackNewOrderDto: SlackNewOrderDto) { const { orderId, userName, orderTicketCount, orderPrice } = slackNewOrderDto; + console.log('통과:' + orderId); + console.log('') try { const value = await lastValueFrom( this.httpService @@ -219,10 +221,8 @@ export class SlackService { ) { const { ticketId, userName, ticketStatus, adminName } = slackTicketStateChangeDto; - console.log("통과"); console.log(ticketId, userName, ticketStatus, adminName); try { - console.log("통과"); const value = await lastValueFrom( this.httpService .post('/chat.postMessage', { diff --git a/src/sms/sms.service.ts b/src/sms/sms.service.ts index 3cda910..a926c2a 100644 --- a/src/sms/sms.service.ts +++ b/src/sms/sms.service.ts @@ -26,7 +26,6 @@ export class SmsService { const signature = this.makeSignature(serviceId, 'POST', date); Logger.log('실제 문자메시지 전송' + JSON.stringify(messages), 'SmsService'); - try { const data = await lastValueFrom( this.httpService diff --git a/src/tickets/tickets.module.ts b/src/tickets/tickets.module.ts index 9f3e657..28d47f8 100644 --- a/src/tickets/tickets.module.ts +++ b/src/tickets/tickets.module.ts @@ -14,7 +14,8 @@ import { TicketsService } from './tickets.service'; imports: [ TypeOrmModule.forFeature([Ticket]), SocketModule, - UsersModule //삭제예정 + UsersModule, //삭제예정, + QueueModule ], providers: [ TicketsService, diff --git a/src/tickets/tickets.service.ts b/src/tickets/tickets.service.ts index 8d39cbc..100aa6c 100644 --- a/src/tickets/tickets.service.ts +++ b/src/tickets/tickets.service.ts @@ -30,7 +30,8 @@ export class TicketsService { constructor( private ticketRepository: TicketRepository, private socketService: SocketService, - private dataSource: DataSource + private dataSource: DataSource, + private queueService: QueueService ) {} async findById(ticketId: number): Promise { From 7a674495158ee4d495441d6d37f49f5eba132691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=A4=80?= Date: Tue, 26 Jul 2022 20:24:15 +0900 Subject: [PATCH 15/21] =?UTF-8?q?:hammer:=20chore(queue):=20format=20?= =?UTF-8?q?=EB=A7=9E=EC=B6=94=EA=B8=B0=20#38?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/queue/queue.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queue/queue.service.ts b/src/queue/queue.service.ts index b4d3126..3f60083 100644 --- a/src/queue/queue.service.ts +++ b/src/queue/queue.service.ts @@ -39,7 +39,7 @@ export class QueueService { const url = 'https://gosrock.band/tickets/'; let obIdx = 1; let ybIdx = 1; - const totalTicketCnt = order.selection == OrderDate.BOTH ? order.ticketCount/2 : order.ticketCount + const totalTicketCnt = order.selection == OrderDate.BOTH ? order.ticketCount/2 : order.ticketCount const messageDtoList = ticketList.map(ticket => { switch (ticket.date) { case PerformanceDate.OB: From e831755b6c219d9aa5387b7a71e3d47ede00aa9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8E=E1=85=A1=E1=86=AB=E1=84=8C?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 26 Jul 2022 20:25:26 +0900 Subject: [PATCH 16/21] =?UTF-8?q?:hammer:=20fix(order)=20:=20any[]=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80,=20=EB=A6=B0=ED=8A=B8?= =?UTF-8?q?=EB=95=8C=EB=AC=B8=EC=97=90=20=EC=95=88=EB=8F=8C=EC=95=84?= =?UTF-8?q?=EA=B0=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/orders/orders.service.ts | 180 ++++++++++++++++++----------------- 1 file changed, 95 insertions(+), 85 deletions(-) diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts index 96a72d4..eedc170 100644 --- a/src/orders/orders.service.ts +++ b/src/orders/orders.service.ts @@ -1,4 +1,8 @@ -import { BadRequestException, Injectable, InternalServerErrorException } from '@nestjs/common'; +import { + BadRequestException, + Injectable, + InternalServerErrorException +} from '@nestjs/common'; import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; import { Order } from 'src/database/entities/order.entity'; import { User } from 'src/database/entities/user.entity'; @@ -13,100 +17,106 @@ import e from 'express'; @Injectable() export class OrdersService { - constructor( - private orderRepository: OrderRepository, - private ticketService: TicketsService, - private dataSource: DataSource - ) {} + constructor( + private orderRepository: OrderRepository, + private ticketService: TicketsService, + private dataSource: DataSource + ) {} + // 가격 책정 함수 : 단지 가독성을 위해 함수로 뺌 + getTotalPrice(requestOrderDto: RequestOrderDto): number { + const { selection, ticketCount } = requestOrderDto; + const pricePerTicket = 3000; // 티켓 한 장 가격 + const discountForBoth = 1000; // 양일권에 대한 할인 가격 - // 가격 책정 함수 : 단지 가독성을 위해 함수로 뺌 - getTotalPrice(requestOrderDto: RequestOrderDto): number { - const {selection, ticketCount} = requestOrderDto; - const pricePerTicket = 3000; // 티켓 한 장 가격 - const discountForBoth = 1000; // 양일권에 대한 할인 가격 + let totalPrice = pricePerTicket * ticketCount; - let totalPrice = pricePerTicket * ticketCount; + if (selection === OrderDate.BOTH) { + // ticketCount = 양일권 개수 + totalPrice = totalPrice * 2 - discountForBoth * ticketCount; + } + return totalPrice; + } - if (selection === OrderDate.BOTH) { - // ticketCount = 양일권 개수 - totalPrice = (totalPrice * 2) - (discountForBoth * ticketCount); - } - return totalPrice; - } + /** + * selection과 ticketCount를 요청받아서 가격 책정 후 주문을 생성하고, + * 해당 주문에 포함되는 모든 티켓을 각각 생성한다. + * @param requestOrderDto {selection, ticketCount} + * @param user Request User + * @returns Order + */ + async createOrder( + requestOrderDto: RequestOrderDto, + user: User + ): Promise { + const { selection, ticketCount } = requestOrderDto; + const totalPrice = this.getTotalPrice(requestOrderDto); // 가격 책정 - /** - * selection과 ticketCount를 요청받아서 가격 책정 후 주문을 생성하고, - * 해당 주문에 포함되는 모든 티켓을 각각 생성한다. - * @param requestOrderDto {selection, ticketCount} - * @param user Request User - * @returns Order - */ - async createOrder(requestOrderDto: RequestOrderDto, user: User): Promise { - const {selection, ticketCount} = requestOrderDto; - const totalPrice = this.getTotalPrice(requestOrderDto); // 가격 책정 + // 양일권일 경우 요청수량 * 2 해서 저장 + if (selection === OrderDate.BOTH) { + requestOrderDto.ticketCount *= 2; + } - // 양일권일 경우 요청수량 * 2 해서 저장 - if (selection === OrderDate.BOTH) { - requestOrderDto.ticketCount *= 2; - } + const queryRunner = this.dataSource.createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); - const queryRunner = this.dataSource.createQueryRunner(); - await queryRunner.connect(); - await queryRunner.startTransaction(); + const connectedOrder = getConnectedRepository( + OrderRepository, + queryRunner, + Order + ); + const connectedTicket = getConnectedRepository( + TicketRepository, + queryRunner, + Ticket + ); - const connectedOrder = getConnectedRepository( - OrderRepository, - queryRunner, - Order - ); - const connectedTicket = getConnectedRepository( - TicketRepository, - queryRunner, - Ticket - ); + try { + // 주문 생성 + const order = await connectedOrder.createOrder( + requestOrderDto, + user, + totalPrice + ); - try { - // 주문 생성 - const order = await connectedOrder.createOrder(requestOrderDto, user, totalPrice); + // ticketList에 생성할 티켓을 모두 담은 후 한번에 비동기요청 + const ticketList: any[] = []; - // ticketList에 생성할 티켓을 모두 담은 후 한번에 비동기요청 - const ticketList = new Array; + for (let i = 0; i < ticketCount; i++) { + if (selection === OrderDate.BOTH || selection === OrderDate.YB) { + const createTicketDto = { + date: PerformanceDate.YB, + order, + user + }; + ticketList.push(createTicketDto); + } + if (selection === OrderDate.BOTH || selection === OrderDate.OB) { + const createTicketDto = { + date: PerformanceDate.OB, + order, + user + }; + ticketList.push(createTicketDto); + } + } + await Promise.all( + ticketList.map(dto => connectedTicket.createTicket(dto)) + ); - for (let i = 0; i < ticketCount; i++) { - if (selection === OrderDate.BOTH || selection === OrderDate.YB) { - const createTicketDto = { - date: PerformanceDate.YB, - order, - user - } - ticketList.push(createTicketDto); - } - if (selection === OrderDate.BOTH || selection === OrderDate.OB) { - const createTicketDto = { - date: PerformanceDate.OB, - order, - user - } - ticketList.push(createTicketDto); - } - } - await Promise.all(ticketList.map((dto) => connectedTicket.createTicket(dto))); + await queryRunner.commitTransaction(); + return order; + } catch (e) { + // 주문 생성 실패시 Error + await queryRunner.rollbackTransaction(); + throw e; + } finally { + await queryRunner.release(); + } + } - await queryRunner.commitTransaction(); - return order; - - } catch (e) { - // 주문 생성 실패시 Error - await queryRunner.rollbackTransaction(); - throw e; - - } finally { - await queryRunner.release(); - } - } - - async findAllByUserId(userId: number): Promise { - return await this.orderRepository.findAllByUserId(userId); - } + async findAllByUserId(userId: number): Promise { + return await this.orderRepository.findAllByUserId(userId); + } } From 3bddf94f69190903f0bdcee63fb163052a593f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=A4=80?= Date: Tue, 26 Jul 2022 21:08:35 +0900 Subject: [PATCH 17/21] =?UTF-8?q?:hammer:=20fix(queue):=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=9A=94=EC=B2=AD=20=EC=82=AC=ED=95=AD=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20#38?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/database/entities/user.entity.ts | 2 +- src/orders/orders.service.ts | 4 ++-- src/queue/queue.module.ts | 2 +- src/queue/queue.service.ts | 2 +- src/slack/slack.module.ts | 5 +++-- src/slack/slack.service.ts | 1 - 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/database/entities/user.entity.ts b/src/database/entities/user.entity.ts index ed75379..774f157 100644 --- a/src/database/entities/user.entity.ts +++ b/src/database/entities/user.entity.ts @@ -68,7 +68,7 @@ export class User { type: () => [Ticket] }) @Expose() - @OneToMany(type => Ticket, ticket => ticket.user, { eager: false }) + @OneToMany(type => Ticket, ticket => ticket.user, { eager: true }) public ticket: Ticket[]; @ApiProperty({ diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts index 222e1cb..6782973 100644 --- a/src/orders/orders.service.ts +++ b/src/orders/orders.service.ts @@ -93,8 +93,8 @@ export class OrdersService { } } const ticketListForQ = await Promise.all(ticketList.map((dto) => {return connectedTicket.createTicket(dto);})); - this.queueService.createNewOrderJob(order); - this.queueService.sendNaverSmsForOrderJob(order, ticketListForQ); + await this.queueService.createNewOrderJob(order); + await this.queueService.sendNaverSmsForOrderJob(order, ticketListForQ); await queryRunner.commitTransaction(); return order; diff --git a/src/queue/queue.module.ts b/src/queue/queue.module.ts index 5856116..170086b 100644 --- a/src/queue/queue.module.ts +++ b/src/queue/queue.module.ts @@ -21,7 +21,7 @@ import { QueueService } from './queue.service'; SmsModule.forRootAsync({ imports: [ConfigModule], useFactory: async (configService: ConfigService) => ({ - isProd: configService.get('NODE_ENV') === 'dev' ? true : false + isProd: configService.get('NODE_ENV') === 'prod' ? true : false }), inject: [ConfigService] }), diff --git a/src/queue/queue.service.ts b/src/queue/queue.service.ts index 3f60083..356a23d 100644 --- a/src/queue/queue.service.ts +++ b/src/queue/queue.service.ts @@ -54,6 +54,6 @@ export class QueueService { }; } }); - this.naverSmsQ.add('sendNaverSmsForOrder', messageDtoList); + await this.naverSmsQ.add('sendNaverSmsForOrder', messageDtoList); } } diff --git a/src/slack/slack.module.ts b/src/slack/slack.module.ts index 4b014c2..6b879d3 100644 --- a/src/slack/slack.module.ts +++ b/src/slack/slack.module.ts @@ -27,7 +27,7 @@ import { SlackFakeService } from './slackFake.service'; providers: [ { provide: SlackService, - useClass: process.env.NODE_ENV === 'dev' ? SlackService : SlackService + useClass: process.env.NODE_ENV === 'prod' ? SlackService : SlackFakeService }, { provide: ADMIN_CHANNELID, @@ -54,7 +54,8 @@ import { SlackFakeService } from './slackFake.service'; exports: [ { provide: SlackService, - useClass: process.env.NODE_ENV === 'dev' ? SlackService : SlackService + useClass: + process.env.NODE_ENV === 'prod' ? SlackService : SlackFakeService } ] }) diff --git a/src/slack/slack.service.ts b/src/slack/slack.service.ts index 6632b1b..8a2c431 100644 --- a/src/slack/slack.service.ts +++ b/src/slack/slack.service.ts @@ -221,7 +221,6 @@ export class SlackService { ) { const { ticketId, userName, ticketStatus, adminName } = slackTicketStateChangeDto; - console.log(ticketId, userName, ticketStatus, adminName); try { const value = await lastValueFrom( this.httpService From 82898d1f3b19cb0c6413b347c8748cf0261760da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8E=E1=85=A1=E1=86=AB=E1=84=8C?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 26 Jul 2022 22:02:25 +0900 Subject: [PATCH 18/21] :hammer: fix(db) : enum type migrations --- package-lock.json | 40 ++++++---- package.json | 9 ++- src/common/consts/enum.ts | 5 +- .../pipes/ticket-status-validation.pipe.ts | 2 +- src/database/database.module.ts | 2 +- src/database/entities/comment.entity.ts | 2 +- src/database/entities/order.entity.ts | 4 +- src/database/entities/ticket.entity.ts | 6 +- src/database/entities/user.entity.ts | 2 +- .../1658837628780-TicketStatusAddEnum.ts | 78 +++++++++++++++++++ src/database/migrations/typeOrm.config.ts | 23 ++++++ src/slack/slack.service.spec.ts | 7 +- src/tickets/tickets.service.ts | 2 +- 13 files changed, 153 insertions(+), 29 deletions(-) create mode 100644 src/database/migrations/1658837628780-TicketStatusAddEnum.ts create mode 100644 src/database/migrations/typeOrm.config.ts diff --git a/package-lock.json b/package-lock.json index 639100b..1091e00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,6 @@ "requires": true, "packages": { "": { - "name": "ticket-backend-22th", "version": "0.0.1", "license": "UNLICENSED", "dependencies": { @@ -42,7 +41,8 @@ "redis": "^4.2.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", - "rxjs": "^7.2.0", + "rxjs": "^7.5.6", + "rxjs-compat": "^6.6.7", "swagger-ui-express": "^4.4.0", "typeorm": "^0.3.7", "uuid": "^8.3.2", @@ -74,7 +74,7 @@ "supertest": "^6.1.3", "ts-jest": "^27.0.3", "ts-loader": "^9.2.3", - "ts-node": "^10.0.0", + "ts-node": "^10.9.1", "tsconfig-paths": "^3.10.1", "typescript": "^4.3.5" } @@ -9063,13 +9063,18 @@ } }, "node_modules/rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", + "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", "dependencies": { "tslib": "^2.1.0" } }, + "node_modules/rxjs-compat": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz", + "integrity": "sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw==" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -10083,9 +10088,9 @@ } }, "node_modules/ts-node": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", - "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "devOptional": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -17819,13 +17824,18 @@ } }, "rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", + "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", "requires": { "tslib": "^2.1.0" } }, + "rxjs-compat": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz", + "integrity": "sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw==" + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -18580,9 +18590,9 @@ } }, "ts-node": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", - "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "devOptional": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", diff --git a/package.json b/package.json index 407b78a..062ff3a 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,12 @@ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", "prepare": "husky install", - "lint-staged": "lint-staged" + "lint-staged": "lint-staged", + "typeorm": "ts-node ./node_modules/typeorm/cli", + "typeorm:run-migrations": "npm run typeorm migration:run -- -d ./src/database/migrations/typeOrm.config.ts", + "typeorm:generate-migration": "npm run typeorm -- -d ./src/database/migrations/typeOrm.config.ts migration:generate ./src/database/migrations/$npm_config_name", + "typeorm:create-migration": "npm run typeorm -- migration:create ./src/database/migrations/$npm_config_name", + "typeorm:revert-migration": "npm run typeorm -- -d ./src/database/migrations/typeOrm.config.ts migration:revert" }, "dependencies": { "@nestjs/axios": "^0.1.0", @@ -93,7 +98,7 @@ "supertest": "^6.1.3", "ts-jest": "^27.0.3", "ts-loader": "^9.2.3", - "ts-node": "^10.0.0", + "ts-node": "^10.9.1", "tsconfig-paths": "^3.10.1", "typescript": "^4.3.5" }, diff --git a/src/common/consts/enum.ts b/src/common/consts/enum.ts index f345b6a..bafcd8a 100644 --- a/src/common/consts/enum.ts +++ b/src/common/consts/enum.ts @@ -27,7 +27,10 @@ enum OrderStatus { enum TicketStatus { DONE = '입장완료', - WAIT = '입장대기' + // 원래 WAIT = "입장대기" 였음 ENTERWAIT이라고 생각하면될듯 + ENTERWAIT = '입금확인', + ORDERWAIT = '확인대기', + EXPIRE = '기한만료' } enum JWTType { diff --git a/src/common/pipes/ticket-status-validation.pipe.ts b/src/common/pipes/ticket-status-validation.pipe.ts index 8881c2f..7822fd9 100644 --- a/src/common/pipes/ticket-status-validation.pipe.ts +++ b/src/common/pipes/ticket-status-validation.pipe.ts @@ -3,7 +3,7 @@ import e from 'express'; import { TicketStatus } from '../consts/enum'; export class TicketStatusValidationPipe implements PipeTransform { - readonly StatusOptions = [TicketStatus.DONE, TicketStatus.WAIT]; + readonly StatusOptions = [TicketStatus.DONE, TicketStatus.ENTERWAIT]; transform(value: any) { if (typeof value === 'object') { diff --git a/src/database/database.module.ts b/src/database/database.module.ts index 6426cb4..f3dabc6 100644 --- a/src/database/database.module.ts +++ b/src/database/database.module.ts @@ -38,7 +38,7 @@ export class DatabaseModule { password: configService.get('POSTGRES_PASSWORD'), // database: configService.get('POSTGRES_DB'), entities: [__dirname + '/../**/*.entity.{js,ts}'], - synchronize: configService.get('NODE_ENV') === 'dev' ? true : false, + synchronize: configService.get('NODE_ENV') === false, logging: configService.get('NODE_ENV') === 'dev' ? true : false }) }) diff --git a/src/database/entities/comment.entity.ts b/src/database/entities/comment.entity.ts index cdeb12a..c1999ed 100644 --- a/src/database/entities/comment.entity.ts +++ b/src/database/entities/comment.entity.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Exclude, Expose, Transform } from 'class-transformer'; -import { Role } from 'src/common/consts/enum'; +import { Role } from '../../common/consts/enum'; import { Column, diff --git a/src/database/entities/order.entity.ts b/src/database/entities/order.entity.ts index 5a72af0..d02d823 100644 --- a/src/database/entities/order.entity.ts +++ b/src/database/entities/order.entity.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger'; import { Expose, Transform, Type } from 'class-transformer'; import { MaxLength } from 'class-validator'; -import { OrderStatus, OrderDate } from 'src/common/consts/enum'; -import { UserProfileDto } from 'src/common/dtos/user-profile.dto'; +import { OrderStatus, OrderDate } from '../../common/consts/enum'; +import { UserProfileDto } from '../../common/dtos/user-profile.dto'; import { Column, CreateDateColumn, diff --git a/src/database/entities/ticket.entity.ts b/src/database/entities/ticket.entity.ts index 5109d99..54f27fa 100644 --- a/src/database/entities/ticket.entity.ts +++ b/src/database/entities/ticket.entity.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Exclude, Expose, Type } from 'class-transformer'; -import { PerformanceDate, TicketStatus } from 'src/common/consts/enum'; +import { PerformanceDate, TicketStatus } from '../../common/consts/enum'; import { AfterLoad, BeforeInsert, @@ -16,7 +16,7 @@ import { import { Order } from './order.entity'; import { User } from './user.entity'; import { nanoid } from 'nanoid'; -import { UserProfileDto } from 'src/common/dtos/user-profile.dto'; +import { UserProfileDto } from '../../common/dtos/user-profile.dto'; @Entity() export class Ticket { @@ -55,7 +55,7 @@ export class Ticket { @Column({ type: 'enum', enum: TicketStatus, - default: TicketStatus.WAIT + default: TicketStatus.ORDERWAIT }) public status: TicketStatus; diff --git a/src/database/entities/user.entity.ts b/src/database/entities/user.entity.ts index 774f157..5884b72 100644 --- a/src/database/entities/user.entity.ts +++ b/src/database/entities/user.entity.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Exclude, Expose } from 'class-transformer'; -import { Role } from 'src/common/consts/enum'; +import { Role } from '../../common/consts/enum'; import { Column, CreateDateColumn, diff --git a/src/database/migrations/1658837628780-TicketStatusAddEnum.ts b/src/database/migrations/1658837628780-TicketStatusAddEnum.ts new file mode 100644 index 0000000..e98139b --- /dev/null +++ b/src/database/migrations/1658837628780-TicketStatusAddEnum.ts @@ -0,0 +1,78 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class TicketStatusAddEnum1658837628780 implements MigrationInterface { + name = 'TicketStatusAddEnum1658837628780'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TYPE "public"."ticket_status_enum" RENAME TO "ticket_status_enum_old"` + ); + + await queryRunner.query( + `CREATE TYPE "public"."ticket_status_enum_migration" AS ENUM('입장완료', '입금확인', '확인대기', '기한만료' ,'입장대기')` + ); + await queryRunner.query( + `CREATE TYPE "public"."ticket_status_enum" AS ENUM('입장완료', '입금확인', '확인대기', '기한만료' )` + ); + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" DROP DEFAULT` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" TYPE "public"."ticket_status_enum_migration" USING "status"::"text"::"public"."ticket_status_enum_migration"` + ); + await queryRunner.query( + `UPDATE "ticket" + SET status = '확인대기' + WHERE status = '입장대기' ;` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" TYPE "public"."ticket_status_enum" USING "status"::"text"::"public"."ticket_status_enum"` + ); + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" SET DEFAULT '확인대기'` + ); + + await queryRunner.query(`DROP TYPE "public"."ticket_status_enum_old"`); + await queryRunner.query( + `DROP TYPE "public"."ticket_status_enum_migration"` + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."ticket_status_enum_old" AS ENUM('입장완료', '입장대기')` + ); + await queryRunner.query( + `CREATE TYPE "public"."ticket_status_enum_migration" AS ENUM('입장완료', '입금확인', '확인대기', '기한만료' ,'입장대기')` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" DROP DEFAULT` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" TYPE "public"."ticket_status_enum_migration" USING "status"::"text"::"public"."ticket_status_enum_migration"` + ); + await queryRunner.query( + `UPDATE "ticket" + SET status = '입장대기' + WHERE status IN('확인대기', '기한만료' ,'입장대기') ;` + ); + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" TYPE "public"."ticket_status_enum_old" USING "status"::"text"::"public"."ticket_status_enum_old"` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" SET DEFAULT '입장대기'` + ); + await queryRunner.query(`DROP TYPE "public"."ticket_status_enum"`); + await queryRunner.query( + `DROP TYPE "public"."ticket_status_enum_migration"` + ); + await queryRunner.query( + `ALTER TYPE "public"."ticket_status_enum_old" RENAME TO "ticket_status_enum"` + ); + } +} diff --git a/src/database/migrations/typeOrm.config.ts b/src/database/migrations/typeOrm.config.ts new file mode 100644 index 0000000..b22613a --- /dev/null +++ b/src/database/migrations/typeOrm.config.ts @@ -0,0 +1,23 @@ +import 'reflect-metadata'; +import { DataSource } from 'typeorm'; +import { ConfigService } from '@nestjs/config'; +import { config } from 'dotenv'; +import { Ticket } from '../entities/ticket.entity'; +import { Order } from '../entities/order.entity'; +import { User } from '../entities/user.entity'; +import { Comment } from '../entities/comment.entity'; +import { TicketStatusAddEnum1658837628780 } from './1658837628780-TicketStatusAddEnum'; + +config(); + +const configService = new ConfigService(); +console.log(configService.get('POSTGRES_HOST')); +export default new DataSource({ + type: 'postgres', + host: configService.get('POSTGRES_HOST'), + port: configService.get('POSTGRES_PORT'), + username: configService.get('POSTGRES_USER'), + password: configService.get('POSTGRES_PASSWORD'), + entities: [Ticket, Order, User, Comment], + migrations: [TicketStatusAddEnum1658837628780] +}); diff --git a/src/slack/slack.service.spec.ts b/src/slack/slack.service.spec.ts index 598b661..b53055a 100644 --- a/src/slack/slack.service.spec.ts +++ b/src/slack/slack.service.spec.ts @@ -76,7 +76,12 @@ describe('SlackService', () => { it('관리자가 티켓의 상태를 변경하면 알림이 가야합니다.', async () => { const value = await service.ticketStateChangedByAdminEvent( - new SlackTicketStateChangeDto(1, '테스트', TicketStatus.WAIT, '테스트2') + new SlackTicketStateChangeDto( + 1, + '테스트', + TicketStatus.ENTERWAIT, + '테스트2' + ) ); console.log(value); expect(value).toBeDefined(); diff --git a/src/tickets/tickets.service.ts b/src/tickets/tickets.service.ts index 30c4485..1599149 100644 --- a/src/tickets/tickets.service.ts +++ b/src/tickets/tickets.service.ts @@ -125,7 +125,7 @@ export class TicketsService { } // 티켓 상태 오류('입장대기'가 아님) - if (ticket.status !== TicketStatus.WAIT) { + if (ticket.status !== TicketStatus.ENTERWAIT) { const failureResponse = new TicketEntryResponseDto( ticket, admin.name, From 969aaaff0f824c1e9088f60e95021c86e446815e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8E=E1=85=A1=E1=86=AB=E1=84=8C?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 26 Jul 2022 22:07:40 +0900 Subject: [PATCH 19/21] =?UTF-8?q?:hammer:=20fix(db)=20:=20dev=20option=20s?= =?UTF-8?q?ync=20true=20=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/database/database.module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database/database.module.ts b/src/database/database.module.ts index f3dabc6..6426cb4 100644 --- a/src/database/database.module.ts +++ b/src/database/database.module.ts @@ -38,7 +38,7 @@ export class DatabaseModule { password: configService.get('POSTGRES_PASSWORD'), // database: configService.get('POSTGRES_DB'), entities: [__dirname + '/../**/*.entity.{js,ts}'], - synchronize: configService.get('NODE_ENV') === false, + synchronize: configService.get('NODE_ENV') === 'dev' ? true : false, logging: configService.get('NODE_ENV') === 'dev' ? true : false }) }) From 0ce5571d35cfcc305c3afa2940aa034f5c4120a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8E=E1=85=A1=E1=86=AB=E1=84=8C?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 26 Jul 2022 22:20:07 +0900 Subject: [PATCH 20/21] =?UTF-8?q?uuid=20(=EC=8B=A4=EC=A0=9C=20=EB=94=94?= =?UTF-8?q?=EB=B9=84=EC=9A=A9)=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1658841312873-TicketUuidToVARCHAR.ts | 19 +++++++++++++++++++ src/database/migrations/typeOrm.config.ts | 6 +++++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/database/migrations/1658841312873-TicketUuidToVARCHAR.ts diff --git a/src/database/migrations/1658841312873-TicketUuidToVARCHAR.ts b/src/database/migrations/1658841312873-TicketUuidToVARCHAR.ts new file mode 100644 index 0000000..eef017c --- /dev/null +++ b/src/database/migrations/1658841312873-TicketUuidToVARCHAR.ts @@ -0,0 +1,19 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class TicketUuidToVARCHAR1658841312873 implements MigrationInterface { + name = 'migrations1658841312873'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "ticket" DROP COLUMN "uuid"`); + await queryRunner.query( + `ALTER TABLE "ticket" ADD "uuid" character varying(14) NOT NULL` + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "ticket" DROP COLUMN "uuid"`); + await queryRunner.query( + `ALTER TABLE "ticket" ADD "uuid" uuid NOT NULL DEFAULT uuid_generate_v4()` + ); + } +} diff --git a/src/database/migrations/typeOrm.config.ts b/src/database/migrations/typeOrm.config.ts index b22613a..4db3947 100644 --- a/src/database/migrations/typeOrm.config.ts +++ b/src/database/migrations/typeOrm.config.ts @@ -7,6 +7,7 @@ import { Order } from '../entities/order.entity'; import { User } from '../entities/user.entity'; import { Comment } from '../entities/comment.entity'; import { TicketStatusAddEnum1658837628780 } from './1658837628780-TicketStatusAddEnum'; +import { TicketUuidToVARCHAR1658841312873 } from './1658841312873-TicketUuidToVARCHAR'; config(); @@ -19,5 +20,8 @@ export default new DataSource({ username: configService.get('POSTGRES_USER'), password: configService.get('POSTGRES_PASSWORD'), entities: [Ticket, Order, User, Comment], - migrations: [TicketStatusAddEnum1658837628780] + migrations: [ + TicketStatusAddEnum1658837628780, + TicketUuidToVARCHAR1658841312873 + ] }); From e49b319ebf95f9276c0ec4aef33d378017f212cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8E=E1=85=A1=E1=86=AB=E1=84=8C?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 26 Jul 2022 22:20:28 +0900 Subject: [PATCH 21/21] =?UTF-8?q?typeorm=20migration=20=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EC=8B=A4=EB=94=94=EB=B9=84=EC=9A=A9=20=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/database/migrations/typeOrm.config.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/database/migrations/typeOrm.config.ts b/src/database/migrations/typeOrm.config.ts index 4db3947..b22613a 100644 --- a/src/database/migrations/typeOrm.config.ts +++ b/src/database/migrations/typeOrm.config.ts @@ -7,7 +7,6 @@ import { Order } from '../entities/order.entity'; import { User } from '../entities/user.entity'; import { Comment } from '../entities/comment.entity'; import { TicketStatusAddEnum1658837628780 } from './1658837628780-TicketStatusAddEnum'; -import { TicketUuidToVARCHAR1658841312873 } from './1658841312873-TicketUuidToVARCHAR'; config(); @@ -20,8 +19,5 @@ export default new DataSource({ username: configService.get('POSTGRES_USER'), password: configService.get('POSTGRES_PASSWORD'), entities: [Ticket, Order, User, Comment], - migrations: [ - TicketStatusAddEnum1658837628780, - TicketUuidToVARCHAR1658841312873 - ] + migrations: [TicketStatusAddEnum1658837628780] });