From 87834bab17e5f169053e72a4ae7aaa9d6a15c918 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Thu, 7 Nov 2024 15:19:24 +0900 Subject: [PATCH 01/16] =?UTF-8?q?=F0=9F=94=A7=20fix:=20socket=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/app.module.ts | 4 +- .../index/interface/stock.index.interface.ts | 7 --- BE/src/stock/index/stock.index.controller.ts | 29 +++++++++++++ BE/src/stock/index/stock.index.module.ts | 3 +- BE/src/websocket/socket.module.ts | 12 ++++++ BE/src/websocket/socket.service.ts | 43 +++---------------- 6 files changed, 51 insertions(+), 47 deletions(-) create mode 100644 BE/src/websocket/socket.module.ts diff --git a/BE/src/app.module.ts b/BE/src/app.module.ts index 36681ad9..28a931c8 100644 --- a/BE/src/app.module.ts +++ b/BE/src/app.module.ts @@ -11,6 +11,7 @@ import { SocketService } from './websocket/socket.service'; import { SocketGateway } from './websocket/socket.gateway'; import { StockTopfiveModule } from './stock/topfive/stock.topfive.module'; import { KoreaInvestmentModule } from './koreaInvestment/korea.investment.module'; +import { SocketModule } from './websocket/socket.module'; @Module({ imports: [ @@ -30,8 +31,9 @@ import { KoreaInvestmentModule } from './koreaInvestment/korea.investment.module AuthModule, StockIndexModule, StockTopfiveModule, + SocketModule, ], controllers: [AppController], - providers: [AppService, SocketService, SocketGateway], + providers: [AppService], }) export class AppModule {} diff --git a/BE/src/stock/index/interface/stock.index.interface.ts b/BE/src/stock/index/interface/stock.index.interface.ts index 48d5851b..93636c51 100644 --- a/BE/src/stock/index/interface/stock.index.interface.ts +++ b/BE/src/stock/index/interface/stock.index.interface.ts @@ -1,10 +1,3 @@ -export interface AccessTokenInterface { - access_token: string; - access_token_token_expired: string; - token_type: string; - expires_in: number; -} - export interface StockIndexChartInterface { output: StockIndexChartElementInterface[]; rt_cd: string; diff --git a/BE/src/stock/index/stock.index.controller.ts b/BE/src/stock/index/stock.index.controller.ts index acc139b6..c44c29db 100644 --- a/BE/src/stock/index/stock.index.controller.ts +++ b/BE/src/stock/index/stock.index.controller.ts @@ -1,8 +1,10 @@ import { Controller, Get } from '@nestjs/common'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { Cron } from '@nestjs/schedule'; import { StockIndexService } from './stock.index.service'; import { StockIndexResponseDto } from './dto/stock.index.response.dto'; import { KoreaInvestmentService } from '../../koreaInvestment/korea.investment.service'; +import { SocketGateway } from '../../websocket/socket.gateway'; @Controller('/api/stocks/index') @ApiTags('주가 지수 API') @@ -10,6 +12,7 @@ export class StockIndexController { constructor( private readonly stockIndexService: StockIndexService, private readonly koreaInvestmentService: KoreaInvestmentService, + private readonly socketGateway: SocketGateway, ) {} @Get() @@ -65,4 +68,30 @@ export class StockIndexController { return new StockIndexResponseDto(stockLists, stockValues); } + + @Cron('*/1 9-16 * * 1-5') + async cronStockIndexLists() { + const accessToken = await this.koreaInvestmentService.getAccessToken(); + + const stockLists = await Promise.all([ + this.stockIndexService.getDomesticStockIndexListByCode( + '0001', + accessToken, + ), // 코스피 + this.stockIndexService.getDomesticStockIndexListByCode( + '1001', + accessToken, + ), // 코스닥 + this.stockIndexService.getDomesticStockIndexListByCode( + '2001', + accessToken, + ), // 코스피200 + this.stockIndexService.getDomesticStockIndexListByCode( + '3003', + accessToken, + ), // KSQ150 + ]); + + this.socketGateway.sendStockIndexListToClient(stockLists); + } } diff --git a/BE/src/stock/index/stock.index.module.ts b/BE/src/stock/index/stock.index.module.ts index 2a044bf5..1227e4f7 100644 --- a/BE/src/stock/index/stock.index.module.ts +++ b/BE/src/stock/index/stock.index.module.ts @@ -2,9 +2,10 @@ import { Module } from '@nestjs/common'; import { StockIndexController } from './stock.index.controller'; import { StockIndexService } from './stock.index.service'; import { KoreaInvestmentModule } from '../../koreaInvestment/korea.investment.module'; +import { SocketModule } from '../../websocket/socket.module'; @Module({ - imports: [KoreaInvestmentModule], + imports: [KoreaInvestmentModule, SocketModule], controllers: [StockIndexController], providers: [StockIndexService], exports: [StockIndexService], diff --git a/BE/src/websocket/socket.module.ts b/BE/src/websocket/socket.module.ts new file mode 100644 index 00000000..7dad68a3 --- /dev/null +++ b/BE/src/websocket/socket.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { SocketService } from './socket.service'; +import { SocketGateway } from './socket.gateway'; +import { KoreaInvestmentModule } from '../koreaInvestment/korea.investment.module'; + +@Module({ + imports: [KoreaInvestmentModule], + controllers: [], + providers: [SocketService, SocketGateway], + exports: [SocketGateway], +}) +export class SocketModule {} diff --git a/BE/src/websocket/socket.service.ts b/BE/src/websocket/socket.service.ts index 0970d7a7..543517c0 100644 --- a/BE/src/websocket/socket.service.ts +++ b/BE/src/websocket/socket.service.ts @@ -1,10 +1,7 @@ import { Injectable, OnModuleInit } from '@nestjs/common'; import { WebSocket } from 'ws'; -import { Cron } from '@nestjs/schedule'; import { SocketGateway } from './socket.gateway'; import { StockIndexValueElementDto } from '../stock/index/dto/stock.index.value.element.dto'; -import { StockIndexService } from '../stock/index/stock.index.service'; -import { KoreaInvestmentService } from '../koreaInvestment/korea.investment.service'; @Injectable() export class SocketService implements OnModuleInit { @@ -13,11 +10,7 @@ export class SocketService implements OnModuleInit { H0UPCNT0: this.handleStockIndexValue.bind(this), }; - constructor( - private readonly stockIndexGateway: SocketGateway, - private readonly stockIndexService: StockIndexService, - private readonly koreaInvestmentService: KoreaInvestmentService, - ) {} + constructor(private readonly socketGateway: SocketGateway) {} async onModuleInit() { const socketConnectionKey = await this.getSocketConnectionKey(); @@ -43,35 +36,9 @@ export class SocketService implements OnModuleInit { }; } - @Cron('*/5 9-16 * * 1-5') - async cronStockIndexLists() { - const accessToken = await this.koreaInvestmentService.getAccessToken(); - - const stockLists = await Promise.all([ - this.stockIndexService.getDomesticStockIndexListByCode( - '0001', - accessToken, - ), // 코스피 - this.stockIndexService.getDomesticStockIndexListByCode( - '1001', - accessToken, - ), // 코스닥 - this.stockIndexService.getDomesticStockIndexListByCode( - '2001', - accessToken, - ), // 코스피200 - this.stockIndexService.getDomesticStockIndexListByCode( - '3003', - accessToken, - ), // KSQ150 - ]); - - this.stockIndexGateway.sendStockIndexListToClient(stockLists); - } - private handleStockIndexValue(responseData: string) { const responseList = responseData.split('^'); - this.stockIndexGateway.sendStockIndexValueToClient( + this.socketGateway.sendStockIndexValueToClient( new StockIndexValueElementDto( responseList[0], responseList[2], @@ -83,7 +50,7 @@ export class SocketService implements OnModuleInit { } private async getSocketConnectionKey() { - const url = 'https://openapi.koreainvestment.com:9443/oauth2/Approval'; + const url = `${process.env.KOREA_INVESTMENT_BASE_URL}/oauth2/Approval`; const response = await fetch(url, { method: 'POST', @@ -92,8 +59,8 @@ export class SocketService implements OnModuleInit { }, body: JSON.stringify({ grant_type: 'client_credentials', - appkey: process.env.APP_KEY, - secretkey: process.env.APP_SECRET, + appkey: process.env.KOREA_INVESTMENT_APP_KEY, + secretkey: process.env.KOREA_INVESTMENT_APP_SECRET, }), }); const result: SocketConnectTokenInterface = await response.json(); From cf81c6ec256f5cea231e8b519a51b060b96caf34 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Thu, 7 Nov 2024 15:25:15 +0900 Subject: [PATCH 02/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20import=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/app.module.ts | 2 -- BE/src/stock/index/stock.index.controller.ts | 2 +- BE/src/websocket/socket.module.ts | 3 +-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/BE/src/app.module.ts b/BE/src/app.module.ts index 28a931c8..fbef051f 100644 --- a/BE/src/app.module.ts +++ b/BE/src/app.module.ts @@ -7,8 +7,6 @@ import { AppService } from './app.service'; import { AuthModule } from './auth/auth.module'; import { User } from './auth/user.entity'; import { StockIndexModule } from './stock/index/stock.index.module'; -import { SocketService } from './websocket/socket.service'; -import { SocketGateway } from './websocket/socket.gateway'; import { StockTopfiveModule } from './stock/topfive/stock.topfive.module'; import { KoreaInvestmentModule } from './koreaInvestment/korea.investment.module'; import { SocketModule } from './websocket/socket.module'; diff --git a/BE/src/stock/index/stock.index.controller.ts b/BE/src/stock/index/stock.index.controller.ts index c44c29db..c3ddce59 100644 --- a/BE/src/stock/index/stock.index.controller.ts +++ b/BE/src/stock/index/stock.index.controller.ts @@ -69,7 +69,7 @@ export class StockIndexController { return new StockIndexResponseDto(stockLists, stockValues); } - @Cron('*/1 9-16 * * 1-5') + @Cron('*/5 9-16 * * 1-5') async cronStockIndexLists() { const accessToken = await this.koreaInvestmentService.getAccessToken(); diff --git a/BE/src/websocket/socket.module.ts b/BE/src/websocket/socket.module.ts index 7dad68a3..4e9e2eb2 100644 --- a/BE/src/websocket/socket.module.ts +++ b/BE/src/websocket/socket.module.ts @@ -1,10 +1,9 @@ import { Module } from '@nestjs/common'; import { SocketService } from './socket.service'; import { SocketGateway } from './socket.gateway'; -import { KoreaInvestmentModule } from '../koreaInvestment/korea.investment.module'; @Module({ - imports: [KoreaInvestmentModule], + imports: [], controllers: [], providers: [SocketService, SocketGateway], exports: [SocketGateway], From 89420d7b4ede7af079c74d8c481399cd8d1efaef Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Thu, 7 Nov 2024 16:03:14 +0900 Subject: [PATCH 03/16] =?UTF-8?q?=F0=9F=94=A7=20fix:=20=EC=A3=BC=EA=B0=80?= =?UTF-8?q?=20=EC=A7=80=EC=88=98=20API=20response=20=ED=98=95=EC=8B=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../index/dto/stock.index.response.dto.ts | 33 ++++--- .../dto/stock.index.response.element.dto.ts | 16 +++ BE/src/stock/index/stock.index.controller.ts | 97 ++++++++++++------- 3 files changed, 94 insertions(+), 52 deletions(-) create mode 100644 BE/src/stock/index/dto/stock.index.response.element.dto.ts diff --git a/BE/src/stock/index/dto/stock.index.response.dto.ts b/BE/src/stock/index/dto/stock.index.response.dto.ts index 358266a5..7f26af32 100644 --- a/BE/src/stock/index/dto/stock.index.response.dto.ts +++ b/BE/src/stock/index/dto/stock.index.response.dto.ts @@ -1,25 +1,28 @@ import { ApiProperty } from '@nestjs/swagger'; -import { StockIndexListElementDto } from './stock.index.list.element.dto'; -import { StockIndexValueElementDto } from './stock.index.value.element.dto'; +import { StockIndexResponseElementDto } from './stock.index.response.element.dto'; export class StockIndexResponseDto { - constructor( - indexList: StockIndexListElementDto[], - indexValue: StockIndexValueElementDto[], - ) { - this.indexList = indexList; - this.indexValue = indexValue; - } + @ApiProperty({ + description: '코스피 지수', + type: StockIndexResponseElementDto, + }) + KOSPI: StockIndexResponseElementDto; + + @ApiProperty({ + description: '코스닥 지수', + type: StockIndexResponseElementDto, + }) + KOSDAQ: StockIndexResponseElementDto; @ApiProperty({ - description: '주가 지수 차트 정보 (코스피, 코스닥, 코스피200, KSQ150)', - type: [StockIndexListElementDto], + description: '코스피200 지수', + type: StockIndexResponseElementDto, }) - indexList: StockIndexListElementDto[]; + KOSPI200: StockIndexResponseElementDto; @ApiProperty({ - description: '주가 지수 실시간 값 정보 (코스피, 코스닥, 코스피200, KSQ150)', - type: [StockIndexValueElementDto], + description: 'KSQ150 지수', + type: StockIndexResponseElementDto, }) - indexValue: StockIndexValueElementDto[]; + KSQ150: StockIndexResponseElementDto; } diff --git a/BE/src/stock/index/dto/stock.index.response.element.dto.ts b/BE/src/stock/index/dto/stock.index.response.element.dto.ts new file mode 100644 index 00000000..7ce0ef1a --- /dev/null +++ b/BE/src/stock/index/dto/stock.index.response.element.dto.ts @@ -0,0 +1,16 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { StockIndexValueElementDto } from './stock.index.value.element.dto'; +import { StockIndexListElementDto } from './stock.index.list.element.dto'; + +export class StockIndexResponseElementDto { + @ApiProperty({ + description: '코스피: 0001, 코스닥: 1001, 코스피200: 2001, KSQ150: 3003', + }) + code: string; + + @ApiProperty({ description: '실시간 값', type: StockIndexValueElementDto }) + value: StockIndexValueElementDto; + + @ApiProperty({ description: '실시간 차트', type: StockIndexListElementDto }) + chart: StockIndexListElementDto; +} diff --git a/BE/src/stock/index/stock.index.controller.ts b/BE/src/stock/index/stock.index.controller.ts index c3ddce59..949df5a5 100644 --- a/BE/src/stock/index/stock.index.controller.ts +++ b/BE/src/stock/index/stock.index.controller.ts @@ -28,45 +28,68 @@ export class StockIndexController { async getStockIndex() { const accessToken = await this.koreaInvestmentService.getAccessToken(); - const stockLists = await Promise.all([ - this.stockIndexService.getDomesticStockIndexListByCode( - '0001', - accessToken, - ), // 코스피 - this.stockIndexService.getDomesticStockIndexListByCode( - '1001', - accessToken, - ), // 코스닥 - this.stockIndexService.getDomesticStockIndexListByCode( - '2001', - accessToken, - ), // 코스피200 - this.stockIndexService.getDomesticStockIndexListByCode( - '3003', - accessToken, - ), // KSQ150 - ]); + const [kospiChart, kosdaqChart, kospi200Chart, ksq150Chart] = + await Promise.all([ + this.stockIndexService.getDomesticStockIndexListByCode( + '0001', + accessToken, + ), // 코스피 + this.stockIndexService.getDomesticStockIndexListByCode( + '1001', + accessToken, + ), // 코스닥 + this.stockIndexService.getDomesticStockIndexListByCode( + '2001', + accessToken, + ), // 코스피200 + this.stockIndexService.getDomesticStockIndexListByCode( + '3003', + accessToken, + ), // KSQ150 + ]); - const stockValues = await Promise.all([ - this.stockIndexService.getDomesticStockIndexValueByCode( - '0001', - accessToken, - ), // 코스피 - this.stockIndexService.getDomesticStockIndexValueByCode( - '1001', - accessToken, - ), // 코스닥 - this.stockIndexService.getDomesticStockIndexValueByCode( - '2001', - accessToken, - ), // 코스피200 - this.stockIndexService.getDomesticStockIndexValueByCode( - '3003', - accessToken, - ), // KSQ150 - ]); + const [kospiValue, kosdaqValue, kospi200Value, ksq150Value] = + await Promise.all([ + this.stockIndexService.getDomesticStockIndexValueByCode( + '0001', + accessToken, + ), // 코스피 + this.stockIndexService.getDomesticStockIndexValueByCode( + '1001', + accessToken, + ), // 코스닥 + this.stockIndexService.getDomesticStockIndexValueByCode( + '2001', + accessToken, + ), // 코스피200 + this.stockIndexService.getDomesticStockIndexValueByCode( + '3003', + accessToken, + ), // KSQ150 + ]); - return new StockIndexResponseDto(stockLists, stockValues); + const stockIndexResponse = new StockIndexResponseDto(); + stockIndexResponse.KOSPI = { + code: '0001', + value: kospiValue, + chart: kospiChart, + }; + stockIndexResponse.KOSDAQ = { + code: '1001', + value: kosdaqValue, + chart: kosdaqChart, + }; + stockIndexResponse.KOSPI200 = { + code: '2001', + value: kospi200Value, + chart: kospi200Chart, + }; + stockIndexResponse.KSQ150 = { + code: '3003', + value: ksq150Value, + chart: ksq150Chart, + }; + return stockIndexResponse; } @Cron('*/5 9-16 * * 1-5') From 3d36bce6d1f6d9883bdee0aa2cb12a6a99e2bb94 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Thu, 7 Nov 2024 17:05:11 +0900 Subject: [PATCH 04/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20fetch=20?= =?UTF-8?q?API=20axios=EB=A1=9C=20=EB=AA=A8=EB=91=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/stock/index/stock.index.service.ts | 64 +++++++++++-------- .../websocket/interface/socket.interface.ts | 3 + BE/src/websocket/socket.service.ts | 26 +++----- 3 files changed, 48 insertions(+), 45 deletions(-) create mode 100644 BE/src/websocket/interface/socket.interface.ts diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index f466a461..3b355f35 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@nestjs/common'; +import axios from 'axios'; import { StockIndexListChartElementDto } from './dto/stock.index.list.chart.element.dto'; import { StockIndexListElementDto } from './dto/stock.index.list.element.dto'; import { StockIndexValueElementDto } from './dto/stock.index.value.element.dto'; @@ -10,22 +11,26 @@ import { @Injectable() export class StockIndexService { async getDomesticStockIndexListByCode(code: string, accessToken: string) { - const url = `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/quotations/inquire-index-timeprice`; - const queryParams = `?FID_INPUT_HOUR_1=300&FID_COND_MRKT_DIV_CODE=U&FID_INPUT_ISCD=${code}`; - - const response = await fetch(url + queryParams, { - method: 'GET', - headers: { - 'content-type': 'application/json; charset=utf-8', - authorization: `Bearer ${accessToken}`, - appkey: process.env.KOREA_INVESTMENT_APP_KEY, - appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, - tr_id: 'FHPUP02110200', - custtype: 'P', + const response = await axios.get( + `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/quotations/inquire-index-timeprice`, + { + headers: { + 'content-type': 'application/json; charset=utf-8', + authorization: `Bearer ${accessToken}`, + appkey: process.env.KOREA_INVESTMENT_APP_KEY, + appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, + tr_id: 'FHPUP02110200', + custtype: 'P', + }, + params: { + fid_input_hour_1: 300, + fid_cond_mrkt_div_code: 'U', + fid_input_iscd: code, + }, }, - }); + ); - const result: StockIndexChartInterface = await response.json(); + const result = response.data; if (result.rt_cd !== '0') throw new Error('유효하지 않은 토큰'); return new StockIndexListElementDto( @@ -40,22 +45,25 @@ export class StockIndexService { } async getDomesticStockIndexValueByCode(code: string, accessToken: string) { - const url = `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/quotations/inquire-index-price`; - const queryParams = `?FID_COND_MRKT_DIV_CODE=U&FID_INPUT_ISCD=${code}`; - - const response = await fetch(url + queryParams, { - method: 'GET', - headers: { - 'content-type': 'application/json; charset=utf-8', - authorization: `Bearer ${accessToken}`, - appkey: process.env.KOREA_INVESTMENT_APP_KEY, - appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, - tr_id: 'FHPUP02100000', - custtype: 'P', + const response = await axios.get( + `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/quotations/inquire-index-price`, + { + headers: { + 'content-type': 'application/json; charset=utf-8', + authorization: `Bearer ${accessToken}`, + appkey: process.env.KOREA_INVESTMENT_APP_KEY, + appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, + tr_id: 'FHPUP02100000', + custtype: 'P', + }, + params: { + fid_cond_mrkt_div_code: 'U', + fid_input_iscd: code, + }, }, - }); + ); - const result: StockIndexValueInterface = await response.json(); + const result = response.data; return new StockIndexValueElementDto( code, result.output.bstp_nmix_prpr, diff --git a/BE/src/websocket/interface/socket.interface.ts b/BE/src/websocket/interface/socket.interface.ts new file mode 100644 index 00000000..d9a6aabb --- /dev/null +++ b/BE/src/websocket/interface/socket.interface.ts @@ -0,0 +1,3 @@ +export interface SocketConnectTokenInterface { + approval_key: string; +} diff --git a/BE/src/websocket/socket.service.ts b/BE/src/websocket/socket.service.ts index 543517c0..0c25bf03 100644 --- a/BE/src/websocket/socket.service.ts +++ b/BE/src/websocket/socket.service.ts @@ -1,7 +1,9 @@ import { Injectable, OnModuleInit } from '@nestjs/common'; import { WebSocket } from 'ws'; +import axios from 'axios'; import { SocketGateway } from './socket.gateway'; import { StockIndexValueElementDto } from '../stock/index/dto/stock.index.value.element.dto'; +import { SocketConnectTokenInterface } from './interface/socket.interface'; @Injectable() export class SocketService implements OnModuleInit { @@ -50,20 +52,16 @@ export class SocketService implements OnModuleInit { } private async getSocketConnectionKey() { - const url = `${process.env.KOREA_INVESTMENT_BASE_URL}/oauth2/Approval`; - - const response = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json; charset=UTF-8', - }, - body: JSON.stringify({ + const response = await axios.post( + `${process.env.KOREA_INVESTMENT_BASE_URL}/oauth2/Approval`, + { grant_type: 'client_credentials', appkey: process.env.KOREA_INVESTMENT_APP_KEY, secretkey: process.env.KOREA_INVESTMENT_APP_SECRET, - }), - }); - const result: SocketConnectTokenInterface = await response.json(); + }, + ); + + const result = response.data; return result.approval_key; } @@ -86,9 +84,3 @@ export class SocketService implements OnModuleInit { ); } } - -// interfaces - -interface SocketConnectTokenInterface { - approval_key: string; -} From bf91271a2d6d268b65ef4ea25ef7171eb5ce703b Mon Sep 17 00:00:00 2001 From: JIN Date: Thu, 7 Nov 2024 17:07:23 +0900 Subject: [PATCH 05/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=EB=B3=80=EC=88=98=20=EA=B0=80=EC=A7=80?= =?UTF-8?q?=EA=B3=A0=20=EC=98=A4=EB=8A=94=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/stock/topfive/stock.topfive.service.ts | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/BE/src/stock/topfive/stock.topfive.service.ts b/BE/src/stock/topfive/stock.topfive.service.ts index 806f3459..fd0a2442 100644 --- a/BE/src/stock/topfive/stock.topfive.service.ts +++ b/BE/src/stock/topfive/stock.topfive.service.ts @@ -1,6 +1,5 @@ import axios from 'axios'; import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; import { StockRankigRequestDto } from './dto/stock-ranking-request.dto'; import { StockRankingResponseDto } from './dto/stock-ranking-response.dto'; import { StockRankingDataDto } from './dto/stock-ranking-data.dto'; @@ -13,37 +12,24 @@ import { KoreaInvestmentService } from '../../koreaInvestment/korea.investment.s @Injectable() export class StockTopfiveService { - private readonly koreaInvestmentConfig: { - appKey: string; - appSecret: string; - baseUrl: string; - }; - private readonly logger = new Logger(); constructor( - private readonly config: ConfigService, private readonly koreaInvestmentService: KoreaInvestmentService, - ) { - this.koreaInvestmentConfig = { - appKey: this.config.get('KOREA_INVESTMENT_APP_KEY'), - appSecret: this.config.get('KOREA_INVESTMENT_APP_SECRET'), - baseUrl: this.config.get('KOREA_INVESTMENT_BASE_URL'), - }; - } + ) {} private async requestApi(params: StockRankigRequestDto) { try { const token = await this.koreaInvestmentService.getAccessToken(); const response = await axios.get( - `${this.koreaInvestmentConfig.baseUrl}/uapi/domestic-stock/v1/ranking/fluctuation`, + `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/ranking/fluctuation`, { headers: { 'content-type': 'application/json; charset=utf-8', authorization: `Bearer ${token}`, - appkey: this.koreaInvestmentConfig.appKey, - appsecret: this.koreaInvestmentConfig.appSecret, + appkey: process.env.KOREA_INVESTMENT_APP_KEY, + appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, tr_id: 'FHPST01700000', custtype: 'P', }, From bb3cdbe9e7ae907dfc68eb29438d14cf457618ba Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Thu, 7 Nov 2024 17:23:19 +0900 Subject: [PATCH 06/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20stock=20?= =?UTF-8?q?index=20=EA=B4=80=EB=A0=A8=20API=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=95=A8=EC=88=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/stock/index/stock.index.service.ts | 64 +++++++++++++++-------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index 3b355f35..e0690231 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -11,6 +11,43 @@ import { @Injectable() export class StockIndexService { async getDomesticStockIndexListByCode(code: string, accessToken: string) { + const result = await this.requestDomesticStockIndexListApi( + code, + accessToken, + ); + + if (result.rt_cd !== '0') throw new Error('유효하지 않은 토큰'); + + return new StockIndexListElementDto( + code, + result.output.map((element) => { + return new StockIndexListChartElementDto( + element.bsop_hour, + element.bstp_nmix_prpr, + ); + }), + ); + } + + async getDomesticStockIndexValueByCode(code: string, accessToken: string) { + const result = await this.requestDomesticStockIndexValueApi( + code, + accessToken, + ); + + return new StockIndexValueElementDto( + code, + result.output.bstp_nmix_prpr, + result.output.bstp_nmix_prdy_vrss, + result.output.bstp_nmix_prdy_vrss, + result.output.prdy_vrss_sign, + ); + } + + private async requestDomesticStockIndexListApi( + code: string, + accessToken: string, + ) { const response = await axios.get( `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/quotations/inquire-index-timeprice`, { @@ -30,21 +67,13 @@ export class StockIndexService { }, ); - const result = response.data; - if (result.rt_cd !== '0') throw new Error('유효하지 않은 토큰'); - - return new StockIndexListElementDto( - code, - result.output.map((element) => { - return new StockIndexListChartElementDto( - element.bsop_hour, - element.bstp_nmix_prpr, - ); - }), - ); + return response.data; } - async getDomesticStockIndexValueByCode(code: string, accessToken: string) { + private async requestDomesticStockIndexValueApi( + code: string, + accessToken: string, + ) { const response = await axios.get( `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/quotations/inquire-index-price`, { @@ -63,13 +92,6 @@ export class StockIndexService { }, ); - const result = response.data; - return new StockIndexValueElementDto( - code, - result.output.bstp_nmix_prpr, - result.output.bstp_nmix_prdy_vrss, - result.output.bstp_nmix_prdy_vrss, - result.output.prdy_vrss_sign, - ); + return response.data; } } From edcb77919410eb0f04b335e294c77e6efd21af10 Mon Sep 17 00:00:00 2001 From: JIN Date: Thu, 7 Nov 2024 17:36:01 +0900 Subject: [PATCH 07/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=ED=95=A8=EC=88=98=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EB=AA=85=ED=99=95=ED=95=9C=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../topfive/dto/stock-ranking-request.dto.ts | 2 +- BE/src/stock/topfive/stock.topfive.service.ts | 82 +++++++++---------- BE/src/util/getFullURL.ts | 3 + BE/src/util/getHeader.ts | 10 +++ 4 files changed, 55 insertions(+), 42 deletions(-) create mode 100644 BE/src/util/getFullURL.ts create mode 100644 BE/src/util/getHeader.ts diff --git a/BE/src/stock/topfive/dto/stock-ranking-request.dto.ts b/BE/src/stock/topfive/dto/stock-ranking-request.dto.ts index 200c244d..2e9fc946 100644 --- a/BE/src/stock/topfive/dto/stock-ranking-request.dto.ts +++ b/BE/src/stock/topfive/dto/stock-ranking-request.dto.ts @@ -1,7 +1,7 @@ /** * 등락률 API를 사용할 때 쿼리 파라미터로 사용할 요청값 DTO */ -export class StockRankigRequestDto { +export class StockRankingQueryParameterDto { /** * 조건 시장 분류 코드 * 'J' 주식 diff --git a/BE/src/stock/topfive/stock.topfive.service.ts b/BE/src/stock/topfive/stock.topfive.service.ts index fd0a2442..48a7dff9 100644 --- a/BE/src/stock/topfive/stock.topfive.service.ts +++ b/BE/src/stock/topfive/stock.topfive.service.ts @@ -1,13 +1,15 @@ import axios from 'axios'; import { Injectable, Logger } from '@nestjs/common'; -import { StockRankigRequestDto } from './dto/stock-ranking-request.dto'; +import { StockRankingQueryParameterDto } from './dto/stock-ranking-request.dto'; import { StockRankingResponseDto } from './dto/stock-ranking-response.dto'; import { StockRankingDataDto } from './dto/stock-ranking-data.dto'; +import { MarketType } from '../enum/MarketType'; import { StockApiOutputData, StockApiResponse, } from './interface/stock.topfive.interface'; -import { MarketType } from '../enum/MarketType'; +import { getHeader } from '../../util/getHeader'; +import { getFullURL } from '../../util/getFullURL'; import { KoreaInvestmentService } from '../../koreaInvestment/korea.investment.service'; @Injectable() @@ -18,39 +20,18 @@ export class StockTopfiveService { private readonly koreaInvestmentService: KoreaInvestmentService, ) {} - private async requestApi(params: StockRankigRequestDto) { + private async requestApi(queryParams: StockRankingQueryParameterDto) { try { - const token = await this.koreaInvestmentService.getAccessToken(); + const accessToken = await this.koreaInvestmentService.getAccessToken(); + const headers = getHeader(accessToken, 'FHPST01700000'); + const url = getFullURL('/uapi/domestic-stock/v1/ranking/fluctuation'); + const params = this.getStockRankingParams(queryParams); + + const response = await axios.get(url, { + headers, + params, + }); - const response = await axios.get( - `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/ranking/fluctuation`, - { - headers: { - 'content-type': 'application/json; charset=utf-8', - authorization: `Bearer ${token}`, - appkey: process.env.KOREA_INVESTMENT_APP_KEY, - appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, - tr_id: 'FHPST01700000', - custtype: 'P', - }, - params: { - fid_rsfl_rate2: '', - fid_cond_mrkt_div_code: params.fid_cond_mrkt_div_code, - fid_cond_scr_div_code: '20170', - fid_input_iscd: params.fid_input_iscd, - fid_rank_sort_cls_code: params.fid_rank_sort_cls_code, - fid_input_cnt_1: '0', - fid_prc_cls_code: '1', - fid_input_price_1: '', - fid_input_price_2: '', - fid_vol_cnt: '', - fid_trgt_cls_code: '0', - fid_trgt_exls_cls_code: '0', - fid_div_cls_code: '0', - fid_rsfl_rate1: '', - }, - }, - ); return response.data; } catch (error) { this.logger.error('API Error Details:', { @@ -66,33 +47,33 @@ export class StockTopfiveService { async getMarketRanking(marketType: MarketType) { try { - const params = new StockRankigRequestDto(); - params.fid_cond_mrkt_div_code = 'J'; + const queryParams = new StockRankingQueryParameterDto(); + queryParams.fid_cond_mrkt_div_code = 'J'; switch (marketType) { case MarketType.ALL: - params.fid_input_iscd = '0000'; + queryParams.fid_input_iscd = '0000'; break; case MarketType.KOSPI: - params.fid_input_iscd = '0001'; + queryParams.fid_input_iscd = '0001'; break; case MarketType.KOSDAQ: - params.fid_input_iscd = '1001'; + queryParams.fid_input_iscd = '1001'; break; case MarketType.KOSPI200: - params.fid_input_iscd = '2001'; + queryParams.fid_input_iscd = '2001'; break; default: break; } const highResponse = await this.requestApi({ - ...params, + ...queryParams, fid_rank_sort_cls_code: '0', }); const lowResponse = await this.requestApi({ - ...params, + ...queryParams, fid_rank_sort_cls_code: '1', }); @@ -125,4 +106,23 @@ export class StockTopfiveService { return stockData; }); } + + private getStockRankingParams(params: StockRankingQueryParameterDto) { + return { + fid_rsfl_rate2: '', + fid_cond_mrkt_div_code: params.fid_cond_mrkt_div_code, + fid_cond_scr_div_code: '20170', + fid_input_iscd: params.fid_input_iscd, + fid_rank_sort_cls_code: params.fid_rank_sort_cls_code, + fid_input_cnt_1: '0', + fid_prc_cls_code: '1', + fid_input_price_1: '', + fid_input_price_2: '', + fid_vol_cnt: '', + fid_trgt_cls_code: '0', + fid_trgt_exls_cls_code: '0', + fid_div_cls_code: '0', + fid_rsfl_rate1: '', + }; + } } diff --git a/BE/src/util/getFullURL.ts b/BE/src/util/getFullURL.ts new file mode 100644 index 00000000..da79427f --- /dev/null +++ b/BE/src/util/getFullURL.ts @@ -0,0 +1,3 @@ +export const getFullURL = (url: string) => { + return `${process.env.KOREA_INVESTMENT_BASE_URL}${url}`; +}; diff --git a/BE/src/util/getHeader.ts b/BE/src/util/getHeader.ts new file mode 100644 index 00000000..1f63ee64 --- /dev/null +++ b/BE/src/util/getHeader.ts @@ -0,0 +1,10 @@ +export const getHeader = (accessToken: string, trId: string) => { + return { + 'content-type': 'application/json; charset=utf-8', + authorization: `Bearer ${accessToken}`, + appkey: process.env.KOREA_INVESTMENT_APP_KEY, + appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, + tr_id: trId, + custtype: 'P', + }; +}; From 379ffe6d13ea4eb2769ad0e749d41c8919b5a435 Mon Sep 17 00:00:00 2001 From: JIN Date: Thu, 7 Nov 2024 17:56:28 +0900 Subject: [PATCH 08/16] =?UTF-8?q?=F0=9F=92=A1=20comment:=20service=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=95=A8=EC=88=98=EB=B3=84=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/stock/topfive/stock.topfive.service.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/BE/src/stock/topfive/stock.topfive.service.ts b/BE/src/stock/topfive/stock.topfive.service.ts index 48a7dff9..d8da1643 100644 --- a/BE/src/stock/topfive/stock.topfive.service.ts +++ b/BE/src/stock/topfive/stock.topfive.service.ts @@ -20,6 +20,13 @@ export class StockTopfiveService { private readonly koreaInvestmentService: KoreaInvestmentService, ) {} + /** + * @private 한국투자 Open API - [국내주식] 순위 분석 - 국내주식 등락률 순위 호출 함수 + * @param {StockRankingQueryParameterDto} queryParams - API 요청 시 필요한 쿼리 파라미터 DTO + * @returns - 국내주식 등락률 데이터 + * + * @author uuuo3o + */ private async requestApi(queryParams: StockRankingQueryParameterDto) { try { const accessToken = await this.koreaInvestmentService.getAccessToken(); @@ -45,6 +52,13 @@ export class StockTopfiveService { } } + /** + * 국내주식 등락률 데이터 중 필요한 시장 종류 데이터를 반환하는 함수 + * @param {MarketType} marketType - 시장 종류(ALL, KOSPI, KOSDAQ, KOSPI200) + * @returns - 상승율순, 하락율순 배열 데이터가 포함된 객체 + * + * @author uuuo3o + */ async getMarketRanking(marketType: MarketType) { try { const queryParams = new StockRankingQueryParameterDto(); @@ -94,6 +108,13 @@ export class StockTopfiveService { } } + /** + * @private API에서 받은 국내주식 등락률 데이터를 필요한 정보로 정제하는 함수 + * @param {StockApiOutputData[]} stocks - API 응답에서 받은 원시 데이터 배열 + * @returns - 필요한 정보만 추출한 데이터 배열 + * + * @author uuuo3o + */ private formatStockData(stocks: StockApiOutputData[]) { return stocks.slice(0, 5).map((stock) => { const stockData = new StockRankingDataDto(); @@ -107,6 +128,13 @@ export class StockTopfiveService { }); } + /** + * @private 주식 순위 API 요청을 위한 쿼리 파라미터 객체 생성 함수 + * @param {StockRankingQueryParameterDto} params - API 요청에 필요한 쿼리 파라미터 DTO + * @returns - API 요청에 필요한 쿼리 파라미터 객체 + * + * @author uuuo3o + */ private getStockRankingParams(params: StockRankingQueryParameterDto) { return { fid_rsfl_rate2: '', From 2e10d75fe16e91771f8b728920edfbe8fff54866 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Thu, 7 Nov 2024 19:08:33 +0900 Subject: [PATCH 09/16] =?UTF-8?q?=E2=9C=85=20test:=20=EC=A3=BC=EA=B0=80=20?= =?UTF-8?q?=EC=A7=80=EC=88=98=20=EC=B0=A8=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/stock/index/stock.index.service.ts | 3 +- .../mockdata/stock.index.list.mockdata.ts | 29 +++++++++++ .../stock/index/stock.index.list.e2e-spec.ts | 49 +++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 BE/test/stock/index/mockdata/stock.index.list.mockdata.ts create mode 100644 BE/test/stock/index/stock.index.list.e2e-spec.ts diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index e0690231..1a7b500a 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -16,7 +16,8 @@ export class StockIndexService { accessToken, ); - if (result.rt_cd !== '0') throw new Error('유효하지 않은 토큰'); + if (result.rt_cd !== '0') + throw new Error('데이터를 정상적으로 조회하지 못했습니다.'); return new StockIndexListElementDto( code, diff --git a/BE/test/stock/index/mockdata/stock.index.list.mockdata.ts b/BE/test/stock/index/mockdata/stock.index.list.mockdata.ts new file mode 100644 index 00000000..7fb74649 --- /dev/null +++ b/BE/test/stock/index/mockdata/stock.index.list.mockdata.ts @@ -0,0 +1,29 @@ +export const STOCK_INDEX_LIST_MOCK = { + VALID_DATA: { + data: { + output: [ + { + bsop_hour: '100600', + bstp_nmix_prpr: '916.77', + bstp_nmix_prdy_vrss: '11.27', + prdy_vrss_sign: '2', + bstp_nmix_prdy_ctrt: '1.24', + acml_tr_pbmn: '3839797', + acml_vol: '313374', + cntg_vol: '870', + }, + ], + rt_cd: '0', + msg_cd: 'MCA00000', + msg1: '정상처리 되었습니다.', + }, + }, + INVALID_DATA: { + data: { + output: [], + rt_cd: '1', + msg_cd: 'MCA00000', + msg1: '유효하지 않은 토큰입니다.', + }, + }, +}; diff --git a/BE/test/stock/index/stock.index.list.e2e-spec.ts b/BE/test/stock/index/stock.index.list.e2e-spec.ts new file mode 100644 index 00000000..6079f011 --- /dev/null +++ b/BE/test/stock/index/stock.index.list.e2e-spec.ts @@ -0,0 +1,49 @@ +import { Test } from '@nestjs/testing'; +import axios from 'axios'; +import { StockIndexService } from '../../../src/stock/index/stock.index.service'; +import { STOCK_INDEX_LIST_MOCK } from './mockdata/stock.index.list.mockdata'; + +jest.mock('axios'); + +describe('stock index list test', () => { + let stockIndexService: StockIndexService; + + beforeEach(async () => { + const module = await Test.createTestingModule({ + providers: [StockIndexService], + }).compile(); + + stockIndexService = module.get(StockIndexService); + }); + + it('주가 지수 API에서 정상적인 데이터를 조회한 경우, 형식에 맞춰 정상적으로 반환한다.', async () => { + (axios.get as jest.Mock).mockResolvedValue( + STOCK_INDEX_LIST_MOCK.VALID_DATA, + ); + + expect( + await stockIndexService.getDomesticStockIndexListByCode( + 'code', + 'accessToken', + ), + ).toEqual({ + code: 'code', + chart: [ + { + time: STOCK_INDEX_LIST_MOCK.VALID_DATA.data.output[0].bsop_hour, + value: STOCK_INDEX_LIST_MOCK.VALID_DATA.data.output[0].bstp_nmix_prpr, + }, + ], + }); + }); + + it('주가 지수 API에서 데이터를 조회하지 못한 경우, 에러를 발생시킨다.', async () => { + (axios.get as jest.Mock).mockResolvedValue( + STOCK_INDEX_LIST_MOCK.INVALID_DATA, + ); + + await expect( + stockIndexService.getDomesticStockIndexListByCode('code', 'accessToken'), + ).rejects.toThrow('데이터를 정상적으로 조회하지 못했습니다.'); + }); +}); From 9d8ff3320736db17694540345876d1f1fb83d1bf Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Thu, 7 Nov 2024 19:19:22 +0900 Subject: [PATCH 10/16] =?UTF-8?q?=E2=9C=85=20test:=20=EC=A3=BC=EA=B0=80=20?= =?UTF-8?q?=EC=A7=80=EC=88=98=20=EA=B0=92=20=EC=A1=B0=ED=9A=8C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/stock/index/stock.index.service.ts | 5 +- .../mockdata/stock.index.value.mockdata.ts | 55 +++++++++++++++++++ .../stock/index/stock.index.list.e2e-spec.ts | 4 +- .../stock/index/stock.index.value.e2e-spec.ts | 48 ++++++++++++++++ 4 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 BE/test/stock/index/mockdata/stock.index.value.mockdata.ts create mode 100644 BE/test/stock/index/stock.index.value.e2e-spec.ts diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index 1a7b500a..875be12d 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -36,11 +36,14 @@ export class StockIndexService { accessToken, ); + if (result.rt_cd !== '0') + throw new Error('데이터를 정상적으로 조회하지 못했습니다.'); + return new StockIndexValueElementDto( code, result.output.bstp_nmix_prpr, result.output.bstp_nmix_prdy_vrss, - result.output.bstp_nmix_prdy_vrss, + result.output.bstp_nmix_prdy_ctrt, result.output.prdy_vrss_sign, ); } diff --git a/BE/test/stock/index/mockdata/stock.index.value.mockdata.ts b/BE/test/stock/index/mockdata/stock.index.value.mockdata.ts new file mode 100644 index 00000000..0faa49d9 --- /dev/null +++ b/BE/test/stock/index/mockdata/stock.index.value.mockdata.ts @@ -0,0 +1,55 @@ +export const STOCK_INDEX_VALUE_MOCK = { + VALID_DATA: { + data: { + output: { + bstp_nmix_prpr: '857.60', + bstp_nmix_prdy_vrss: '-1.61', + prdy_vrss_sign: '5', + bstp_nmix_prdy_ctrt: '-0.19', + acml_vol: '1312496', + prdy_vol: '1222188', + acml_tr_pbmn: '11507962', + prdy_tr_pbmn: '11203385', + bstp_nmix_oprc: '863.69', + prdy_nmix_vrss_nmix_oprc: '4.48', + oprc_vrss_prpr_sign: '2', + bstp_nmix_oprc_prdy_ctrt: '0.52', + bstp_nmix_hgpr: '864.24', + prdy_nmix_vrss_nmix_hgpr: '5.03', + hgpr_vrss_prpr_sign: '2', + bstp_nmix_hgpr_prdy_ctrt: '0.59', + bstp_nmix_lwpr: '854.72', + prdy_clpr_vrss_lwpr: '-4.49', + lwpr_vrss_prpr_sign: '5', + prdy_clpr_vrss_lwpr_rate: '-0.52', + ascn_issu_cnt: '828', + uplm_issu_cnt: '5', + stnr_issu_cnt: '94', + down_issu_cnt: '716', + lslm_issu_cnt: '1', + dryy_bstp_nmix_hgpr: '890.06', + dryy_hgpr_vrss_prpr_rate: '3.65', + dryy_bstp_nmix_hgpr_date: '20240109', + dryy_bstp_nmix_lwpr: '786.28', + dryy_lwpr_vrss_prpr_rate: '-9.07', + dryy_bstp_nmix_lwpr_date: '20240201', + total_askp_rsqn: '24146999', + total_bidp_rsqn: '40450437', + seln_rsqn_rate: '37.38', + shnu_rsqn_rate: '62.62', + ntby_rsqn: '16303438', + }, + rt_cd: '0', + msg_cd: 'MCA00000', + msg1: '정상처리 되었습니다.', + }, + }, + INVALID_DATA: { + data: { + output: {}, + rt_cd: '1', + msg_cd: 'MCA00000', + msg1: '유효하지 않은 토큰입니다.', + }, + }, +}; diff --git a/BE/test/stock/index/stock.index.list.e2e-spec.ts b/BE/test/stock/index/stock.index.list.e2e-spec.ts index 6079f011..7518b75d 100644 --- a/BE/test/stock/index/stock.index.list.e2e-spec.ts +++ b/BE/test/stock/index/stock.index.list.e2e-spec.ts @@ -16,7 +16,7 @@ describe('stock index list test', () => { stockIndexService = module.get(StockIndexService); }); - it('주가 지수 API에서 정상적인 데이터를 조회한 경우, 형식에 맞춰 정상적으로 반환한다.', async () => { + it('주가 지수 차트 조회 API에서 정상적인 데이터를 조회한 경우, 형식에 맞춰 정상적으로 반환한다.', async () => { (axios.get as jest.Mock).mockResolvedValue( STOCK_INDEX_LIST_MOCK.VALID_DATA, ); @@ -37,7 +37,7 @@ describe('stock index list test', () => { }); }); - it('주가 지수 API에서 데이터를 조회하지 못한 경우, 에러를 발생시킨다.', async () => { + it('주가 지수 차트 조회 API에서 데이터를 조회하지 못한 경우, 에러를 발생시킨다.', async () => { (axios.get as jest.Mock).mockResolvedValue( STOCK_INDEX_LIST_MOCK.INVALID_DATA, ); diff --git a/BE/test/stock/index/stock.index.value.e2e-spec.ts b/BE/test/stock/index/stock.index.value.e2e-spec.ts new file mode 100644 index 00000000..12ff2590 --- /dev/null +++ b/BE/test/stock/index/stock.index.value.e2e-spec.ts @@ -0,0 +1,48 @@ +import { Test } from '@nestjs/testing'; +import axios from 'axios'; +import { StockIndexService } from '../../../src/stock/index/stock.index.service'; +import { STOCK_INDEX_VALUE_MOCK } from './mockdata/stock.index.value.mockdata'; + +jest.mock('axios'); + +describe('stock index list test', () => { + let stockIndexService: StockIndexService; + + beforeEach(async () => { + const module = await Test.createTestingModule({ + providers: [StockIndexService], + }).compile(); + + stockIndexService = module.get(StockIndexService); + }); + + it('주가 지수 값 조회 API에서 정상적인 데이터를 조회한 경우, 형식에 맞춰 정상적으로 반환한다.', async () => { + (axios.get as jest.Mock).mockResolvedValue( + STOCK_INDEX_VALUE_MOCK.VALID_DATA, + ); + + expect( + await stockIndexService.getDomesticStockIndexValueByCode( + 'code', + 'accessToken', + ), + ).toEqual({ + code: 'code', + value: STOCK_INDEX_VALUE_MOCK.VALID_DATA.data.output.bstp_nmix_prpr, + diff: STOCK_INDEX_VALUE_MOCK.VALID_DATA.data.output.bstp_nmix_prdy_vrss, + diffRate: + STOCK_INDEX_VALUE_MOCK.VALID_DATA.data.output.bstp_nmix_prdy_ctrt, + sign: STOCK_INDEX_VALUE_MOCK.VALID_DATA.data.output.prdy_vrss_sign, + }); + }); + + it('주가 지수 값 조회 API에서 데이터를 조회하지 못한 경우, 에러를 발생시킨다.', async () => { + (axios.get as jest.Mock).mockResolvedValue( + STOCK_INDEX_VALUE_MOCK.INVALID_DATA, + ); + + await expect( + stockIndexService.getDomesticStockIndexValueByCode('code', 'accessToken'), + ).rejects.toThrow('데이터를 정상적으로 조회하지 못했습니다.'); + }); +}); From 99362cdf5c55fad734d74a05168779e10aa7bd24 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Fri, 8 Nov 2024 10:13:25 +0900 Subject: [PATCH 11/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20getFullU?= =?UTF-8?q?rl,=20getHeader=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../korea.investment.service.ts | 14 ++++---- BE/src/stock/index/stock.index.service.ts | 34 +++++++------------ BE/src/websocket/socket.service.ts | 6 ++-- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/BE/src/koreaInvestment/korea.investment.service.ts b/BE/src/koreaInvestment/korea.investment.service.ts index 57458372..73ebe901 100644 --- a/BE/src/koreaInvestment/korea.investment.service.ts +++ b/BE/src/koreaInvestment/korea.investment.service.ts @@ -1,4 +1,5 @@ import axios from 'axios'; +import { getFullURL } from '../util/getFullURL'; export class KoreaInvestmentService { private accessToken: string; @@ -9,14 +10,11 @@ export class KoreaInvestmentService { if (this.accessToken && this.tokenExpireTime > new Date()) { return this.accessToken; } - const response = await axios.post( - `${process.env.KOREA_INVESTMENT_BASE_URL}/oauth2/tokenP`, - { - grant_type: 'client_credentials', - appkey: process.env.KOREA_INVESTMENT_APP_KEY, - appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, - }, - ); + const response = await axios.post(getFullURL('/oauth2/tokenP'), { + grant_type: 'client_credentials', + appkey: process.env.KOREA_INVESTMENT_APP_KEY, + appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, + }); const { data } = response; diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index 875be12d..42bb056b 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -7,6 +7,8 @@ import { StockIndexChartInterface, StockIndexValueInterface, } from './interface/stock.index.interface'; +import { getFullURL } from '../../util/getFullURL'; +import { getHeader } from '../../util/getHeader'; @Injectable() export class StockIndexService { @@ -39,12 +41,14 @@ export class StockIndexService { if (result.rt_cd !== '0') throw new Error('데이터를 정상적으로 조회하지 못했습니다.'); + const data = result.output; + return new StockIndexValueElementDto( code, - result.output.bstp_nmix_prpr, - result.output.bstp_nmix_prdy_vrss, - result.output.bstp_nmix_prdy_ctrt, - result.output.prdy_vrss_sign, + data.bstp_nmix_prpr, + data.bstp_nmix_prdy_vrss, + data.bstp_nmix_prdy_ctrt, + data.prdy_vrss_sign, ); } @@ -53,16 +57,9 @@ export class StockIndexService { accessToken: string, ) { const response = await axios.get( - `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/quotations/inquire-index-timeprice`, + getFullURL('/uapi/domestic-stock/v1/quotations/inquire-index-timeprice'), { - headers: { - 'content-type': 'application/json; charset=utf-8', - authorization: `Bearer ${accessToken}`, - appkey: process.env.KOREA_INVESTMENT_APP_KEY, - appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, - tr_id: 'FHPUP02110200', - custtype: 'P', - }, + headers: getHeader(accessToken, 'FHPUP02110200'), params: { fid_input_hour_1: 300, fid_cond_mrkt_div_code: 'U', @@ -79,16 +76,9 @@ export class StockIndexService { accessToken: string, ) { const response = await axios.get( - `${process.env.KOREA_INVESTMENT_BASE_URL}/uapi/domestic-stock/v1/quotations/inquire-index-price`, + getFullURL('/uapi/domestic-stock/v1/quotations/inquire-index-price'), { - headers: { - 'content-type': 'application/json; charset=utf-8', - authorization: `Bearer ${accessToken}`, - appkey: process.env.KOREA_INVESTMENT_APP_KEY, - appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, - tr_id: 'FHPUP02100000', - custtype: 'P', - }, + headers: getHeader(accessToken, 'FHPUP02100000'), params: { fid_cond_mrkt_div_code: 'U', fid_input_iscd: code, diff --git a/BE/src/websocket/socket.service.ts b/BE/src/websocket/socket.service.ts index 0c25bf03..68893600 100644 --- a/BE/src/websocket/socket.service.ts +++ b/BE/src/websocket/socket.service.ts @@ -4,6 +4,7 @@ import axios from 'axios'; import { SocketGateway } from './socket.gateway'; import { StockIndexValueElementDto } from '../stock/index/dto/stock.index.value.element.dto'; import { SocketConnectTokenInterface } from './interface/socket.interface'; +import { getFullURL } from '../util/getFullURL'; @Injectable() export class SocketService implements OnModuleInit { @@ -17,8 +18,7 @@ export class SocketService implements OnModuleInit { async onModuleInit() { const socketConnectionKey = await this.getSocketConnectionKey(); - const url = 'ws://ops.koreainvestment.com:21000'; - this.socket = new WebSocket(url); + this.socket = new WebSocket(process.env.KOREA_INVESTMENT_SOCKET_URL); this.socket.onopen = () => { this.registerStockIndexByCode('0001', socketConnectionKey); // 코스피 @@ -53,7 +53,7 @@ export class SocketService implements OnModuleInit { private async getSocketConnectionKey() { const response = await axios.post( - `${process.env.KOREA_INVESTMENT_BASE_URL}/oauth2/Approval`, + getFullURL('/oauth2/Approval'), { grant_type: 'client_credentials', appkey: process.env.KOREA_INVESTMENT_APP_KEY, From 6549725d9e02ef975f98efc3fd562ea26ba4bf91 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Fri, 8 Nov 2024 10:59:58 +0900 Subject: [PATCH 12/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20stock=20?= =?UTF-8?q?index=20=EA=B4=80=EB=A0=A8=20=EC=86=8C=EC=BC=93=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8,=20response=20=ED=98=95=EC=8B=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../index/dto/stock.index.list.element.dto.ts | 17 -------------- .../dto/stock.index.response.element.dto.ts | 14 +++++------- .../dto/stock.index.value.element.dto.ts | 22 +++++-------------- BE/src/stock/index/stock.index.controller.ts | 11 +++++----- BE/src/stock/index/stock.index.service.ts | 17 +++++--------- BE/src/websocket/socket.gateway.ts | 8 +++---- BE/src/websocket/socket.service.ts | 9 +++++++- 7 files changed, 35 insertions(+), 63 deletions(-) delete mode 100644 BE/src/stock/index/dto/stock.index.list.element.dto.ts diff --git a/BE/src/stock/index/dto/stock.index.list.element.dto.ts b/BE/src/stock/index/dto/stock.index.list.element.dto.ts deleted file mode 100644 index 03ec0176..00000000 --- a/BE/src/stock/index/dto/stock.index.list.element.dto.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { StockIndexListChartElementDto } from './stock.index.list.chart.element.dto'; - -export class StockIndexListElementDto { - constructor(code: string, chart: StockIndexListChartElementDto[]) { - this.code = code; - this.chart = chart; - } - - @ApiProperty({ - description: '코스피: 0001, 코스닥: 1001, 코스피200: 2001, KSQ150: 3003', - }) - code: string; - - @ApiProperty({ type: [StockIndexListChartElementDto] }) - chart: StockIndexListChartElementDto[]; -} diff --git a/BE/src/stock/index/dto/stock.index.response.element.dto.ts b/BE/src/stock/index/dto/stock.index.response.element.dto.ts index 7ce0ef1a..09e21102 100644 --- a/BE/src/stock/index/dto/stock.index.response.element.dto.ts +++ b/BE/src/stock/index/dto/stock.index.response.element.dto.ts @@ -1,16 +1,14 @@ import { ApiProperty } from '@nestjs/swagger'; import { StockIndexValueElementDto } from './stock.index.value.element.dto'; -import { StockIndexListElementDto } from './stock.index.list.element.dto'; +import { StockIndexListChartElementDto } from './stock.index.list.chart.element.dto'; export class StockIndexResponseElementDto { - @ApiProperty({ - description: '코스피: 0001, 코스닥: 1001, 코스피200: 2001, KSQ150: 3003', - }) - code: string; - @ApiProperty({ description: '실시간 값', type: StockIndexValueElementDto }) value: StockIndexValueElementDto; - @ApiProperty({ description: '실시간 차트', type: StockIndexListElementDto }) - chart: StockIndexListElementDto; + @ApiProperty({ + description: '실시간 차트', + type: [StockIndexListChartElementDto], + }) + chart: StockIndexListChartElementDto[]; } diff --git a/BE/src/stock/index/dto/stock.index.value.element.dto.ts b/BE/src/stock/index/dto/stock.index.value.element.dto.ts index 88ca4949..1eb73a50 100644 --- a/BE/src/stock/index/dto/stock.index.value.element.dto.ts +++ b/BE/src/stock/index/dto/stock.index.value.element.dto.ts @@ -1,33 +1,21 @@ import { ApiProperty } from '@nestjs/swagger'; export class StockIndexValueElementDto { - constructor( - code: string, - value: string, - diff: string, - diffRate: string, - sign: string, - ) { - this.code = code; - this.value = value; + constructor(value: string, diff: string, diffRate: string, sign: string) { + this.curr_value = value; this.diff = diff; - this.diffRate = diffRate; + this.diff_rate = diffRate; this.sign = sign; } - @ApiProperty({ - description: '코스피: 0001, 코스닥: 1001, 코스피200: 2001, KSQ150: 3003', - }) - code: string; - @ApiProperty({ description: '주가 지수' }) - value: string; + curr_value: string; @ApiProperty({ description: '전일 대비 등락' }) diff: string; @ApiProperty({ description: '전일 대비 등락률' }) - diffRate: string; + diff_rate: string; @ApiProperty({ description: '부호... 인데 추후에 알아봐야 함' }) sign: string; diff --git a/BE/src/stock/index/stock.index.controller.ts b/BE/src/stock/index/stock.index.controller.ts index 949df5a5..7625e044 100644 --- a/BE/src/stock/index/stock.index.controller.ts +++ b/BE/src/stock/index/stock.index.controller.ts @@ -70,22 +70,18 @@ export class StockIndexController { const stockIndexResponse = new StockIndexResponseDto(); stockIndexResponse.KOSPI = { - code: '0001', value: kospiValue, chart: kospiChart, }; stockIndexResponse.KOSDAQ = { - code: '1001', value: kosdaqValue, chart: kosdaqChart, }; stockIndexResponse.KOSPI200 = { - code: '2001', value: kospi200Value, chart: kospi200Chart, }; stockIndexResponse.KSQ150 = { - code: '3003', value: ksq150Value, chart: ksq150Chart, }; @@ -115,6 +111,11 @@ export class StockIndexController { ), // KSQ150 ]); - this.socketGateway.sendStockIndexListToClient(stockLists); + this.socketGateway.sendStockIndexListToClient({ + KOSPI: stockLists[0], + KOSDAQ: stockLists[1], + KOSPI200: stockLists[2], + KSQ150: stockLists[3], + }); } } diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index 42bb056b..0d4a97c0 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -1,7 +1,6 @@ import { Injectable } from '@nestjs/common'; import axios from 'axios'; import { StockIndexListChartElementDto } from './dto/stock.index.list.chart.element.dto'; -import { StockIndexListElementDto } from './dto/stock.index.list.element.dto'; import { StockIndexValueElementDto } from './dto/stock.index.value.element.dto'; import { StockIndexChartInterface, @@ -21,15 +20,12 @@ export class StockIndexService { if (result.rt_cd !== '0') throw new Error('데이터를 정상적으로 조회하지 못했습니다.'); - return new StockIndexListElementDto( - code, - result.output.map((element) => { - return new StockIndexListChartElementDto( - element.bsop_hour, - element.bstp_nmix_prpr, - ); - }), - ); + return result.output.map((element) => { + return new StockIndexListChartElementDto( + element.bsop_hour, + element.bstp_nmix_prpr, + ); + }); } async getDomesticStockIndexValueByCode(code: string, accessToken: string) { @@ -44,7 +40,6 @@ export class StockIndexService { const data = result.output; return new StockIndexValueElementDto( - code, data.bstp_nmix_prpr, data.bstp_nmix_prdy_vrss, data.bstp_nmix_prdy_ctrt, diff --git a/BE/src/websocket/socket.gateway.ts b/BE/src/websocket/socket.gateway.ts index 921d9503..e65eac69 100644 --- a/BE/src/websocket/socket.gateway.ts +++ b/BE/src/websocket/socket.gateway.ts @@ -6,11 +6,11 @@ export class SocketGateway { @WebSocketServer() private server: Server; - sendStockIndexListToClient(stockIndex) { - this.server.emit('index', stockIndex); + sendStockIndexListToClient(stockChart) { + this.server.emit('chart', stockChart); } - sendStockIndexValueToClient(stockIndexValue) { - this.server.emit('indexValue', stockIndexValue); + sendStockIndexValueToClient(event, stockIndexValue) { + this.server.emit(event, stockIndexValue); } } diff --git a/BE/src/websocket/socket.service.ts b/BE/src/websocket/socket.service.ts index 68893600..042cd57a 100644 --- a/BE/src/websocket/socket.service.ts +++ b/BE/src/websocket/socket.service.ts @@ -13,6 +13,13 @@ export class SocketService implements OnModuleInit { H0UPCNT0: this.handleStockIndexValue.bind(this), }; + private STOCK_CODE = { + '0001': 'KOSPI', + '1001': 'KOSDAQ', + '2001': 'KOSPI200', + '3003': 'KSQ150', + }; + constructor(private readonly socketGateway: SocketGateway) {} async onModuleInit() { @@ -41,8 +48,8 @@ export class SocketService implements OnModuleInit { private handleStockIndexValue(responseData: string) { const responseList = responseData.split('^'); this.socketGateway.sendStockIndexValueToClient( + this.STOCK_CODE[responseList[0]], new StockIndexValueElementDto( - responseList[0], responseList[2], responseList[4], responseList[9], From d65c70bfef23fc17362613566ac1a07033f24e2d Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Fri, 8 Nov 2024 11:24:23 +0900 Subject: [PATCH 13/16] =?UTF-8?q?=F0=9F=94=A7=20fix:=20service=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=EB=A5=BC=20http=20=EC=97=90=EB=9F=AC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../korea.investment.service.ts | 15 +++-- BE/src/stock/index/stock.index.service.ts | 60 +++++++++++-------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/BE/src/koreaInvestment/korea.investment.service.ts b/BE/src/koreaInvestment/korea.investment.service.ts index 73ebe901..886b68cb 100644 --- a/BE/src/koreaInvestment/korea.investment.service.ts +++ b/BE/src/koreaInvestment/korea.investment.service.ts @@ -1,4 +1,5 @@ import axios from 'axios'; +import { UnauthorizedException } from '@nestjs/common'; import { getFullURL } from '../util/getFullURL'; export class KoreaInvestmentService { @@ -10,11 +11,15 @@ export class KoreaInvestmentService { if (this.accessToken && this.tokenExpireTime > new Date()) { return this.accessToken; } - const response = await axios.post(getFullURL('/oauth2/tokenP'), { - grant_type: 'client_credentials', - appkey: process.env.KOREA_INVESTMENT_APP_KEY, - appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, - }); + const response = await axios + .post(getFullURL('/oauth2/tokenP'), { + grant_type: 'client_credentials', + appkey: process.env.KOREA_INVESTMENT_APP_KEY, + appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, + }) + .catch((err) => { + throw new UnauthorizedException('액세스 토큰을 조회하지 못했습니다.'); + }); const { data } = response; diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index 0d4a97c0..3a14c7fc 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, InternalServerErrorException } from '@nestjs/common'; import axios from 'axios'; import { StockIndexListChartElementDto } from './dto/stock.index.list.chart.element.dto'; import { StockIndexValueElementDto } from './dto/stock.index.value.element.dto'; @@ -17,9 +17,6 @@ export class StockIndexService { accessToken, ); - if (result.rt_cd !== '0') - throw new Error('데이터를 정상적으로 조회하지 못했습니다.'); - return result.output.map((element) => { return new StockIndexListChartElementDto( element.bsop_hour, @@ -34,9 +31,6 @@ export class StockIndexService { accessToken, ); - if (result.rt_cd !== '0') - throw new Error('데이터를 정상적으로 조회하지 못했습니다.'); - const data = result.output; return new StockIndexValueElementDto( @@ -51,17 +45,25 @@ export class StockIndexService { code: string, accessToken: string, ) { - const response = await axios.get( - getFullURL('/uapi/domestic-stock/v1/quotations/inquire-index-timeprice'), - { - headers: getHeader(accessToken, 'FHPUP02110200'), - params: { - fid_input_hour_1: 300, - fid_cond_mrkt_div_code: 'U', - fid_input_iscd: code, + const response = await axios + .get( + getFullURL( + '/uapi/domestic-stock/v1/quotations/inquire-index-timeprice', + ), + { + headers: getHeader(accessToken, 'FHPUP02110200'), + params: { + fid_input_hour_1: 300, + fid_cond_mrkt_div_code: 'U', + fid_input_iscd: code, + }, }, - }, - ); + ) + .catch((err) => { + throw new InternalServerErrorException( + '주가 지수 차트 정보를 조회하지 못했습니다.', + ); + }); return response.data; } @@ -70,16 +72,22 @@ export class StockIndexService { code: string, accessToken: string, ) { - const response = await axios.get( - getFullURL('/uapi/domestic-stock/v1/quotations/inquire-index-price'), - { - headers: getHeader(accessToken, 'FHPUP02100000'), - params: { - fid_cond_mrkt_div_code: 'U', - fid_input_iscd: code, + const response = await axios + .get( + getFullURL('/uapi/domestic-stock/v1/quotations/inquire-index-price'), + { + headers: getHeader(accessToken, 'FHPUP02100000'), + params: { + fid_cond_mrkt_div_code: 'U', + fid_input_iscd: code, + }, }, - }, - ); + ) + .catch((err) => { + throw new InternalServerErrorException( + '주가 지수 값 정보를 조회하지 못했습니다.', + ); + }); return response.data; } From 462c8a189747ec8e15cb25eec87b8e4936543db3 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Fri, 8 Nov 2024 11:42:36 +0900 Subject: [PATCH 14/16] =?UTF-8?q?=F0=9F=94=A7=20fix:=20getAccessToken=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interface/korea.investment.interface.ts | 6 ++++++ BE/src/koreaInvestment/korea.investment.service.ts | 7 ++++--- BE/src/stock/index/stock.index.service.ts | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 BE/src/koreaInvestment/interface/korea.investment.interface.ts diff --git a/BE/src/koreaInvestment/interface/korea.investment.interface.ts b/BE/src/koreaInvestment/interface/korea.investment.interface.ts new file mode 100644 index 00000000..e290a32c --- /dev/null +++ b/BE/src/koreaInvestment/interface/korea.investment.interface.ts @@ -0,0 +1,6 @@ +export interface AccessTokenInterface { + access_token: string; + access_token_token_expired: string; + token_type: string; + expires_in: number; +} diff --git a/BE/src/koreaInvestment/korea.investment.service.ts b/BE/src/koreaInvestment/korea.investment.service.ts index 886b68cb..727c044c 100644 --- a/BE/src/koreaInvestment/korea.investment.service.ts +++ b/BE/src/koreaInvestment/korea.investment.service.ts @@ -1,6 +1,7 @@ import axios from 'axios'; import { UnauthorizedException } from '@nestjs/common'; import { getFullURL } from '../util/getFullURL'; +import { AccessTokenInterface } from './interface/korea.investment.interface'; export class KoreaInvestmentService { private accessToken: string; @@ -12,19 +13,19 @@ export class KoreaInvestmentService { return this.accessToken; } const response = await axios - .post(getFullURL('/oauth2/tokenP'), { + .post(getFullURL('/oauth2/tokenP'), { grant_type: 'client_credentials', appkey: process.env.KOREA_INVESTMENT_APP_KEY, appsecret: process.env.KOREA_INVESTMENT_APP_SECRET, }) - .catch((err) => { + .catch(() => { throw new UnauthorizedException('액세스 토큰을 조회하지 못했습니다.'); }); const { data } = response; this.accessToken = data.access_token; - this.tokenExpireTime = new Date(Date.now() + +data.expires_in); + this.tokenExpireTime = new Date(data.access_token_token_expired); return this.accessToken; } diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index 3a14c7fc..587af43d 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -59,7 +59,7 @@ export class StockIndexService { }, }, ) - .catch((err) => { + .catch(() => { throw new InternalServerErrorException( '주가 지수 차트 정보를 조회하지 못했습니다.', ); @@ -83,7 +83,7 @@ export class StockIndexService { }, }, ) - .catch((err) => { + .catch(() => { throw new InternalServerErrorException( '주가 지수 값 정보를 조회하지 못했습니다.', ); From f210aa0780a7722ab4b74e8d7ec552810fb61fb1 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Sun, 10 Nov 2024 00:35:32 +0900 Subject: [PATCH 15/16] =?UTF-8?q?=E2=9E=95=20add:=20=EC=B0=A8=ED=8A=B8=20r?= =?UTF-8?q?esponse=EC=97=90=20=EC=A0=84=EC=9D=BC=20=EB=8C=80=EB=B9=84=20?= =?UTF-8?q?=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stock/index/dto/stock.index.list.chart.element.dto.ts | 6 +++++- BE/src/stock/index/stock.index.service.ts | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/BE/src/stock/index/dto/stock.index.list.chart.element.dto.ts b/BE/src/stock/index/dto/stock.index.list.chart.element.dto.ts index 1f2abdce..ba6ce1f2 100644 --- a/BE/src/stock/index/dto/stock.index.list.chart.element.dto.ts +++ b/BE/src/stock/index/dto/stock.index.list.chart.element.dto.ts @@ -1,9 +1,10 @@ import { ApiProperty } from '@nestjs/swagger'; export class StockIndexListChartElementDto { - constructor(time: string, value: string) { + constructor(time: string, value: string, diff: string) { this.time = time; this.value = value; + this.diff = diff; } @ApiProperty({ description: 'HHMMSS', example: '130500' }) @@ -11,4 +12,7 @@ export class StockIndexListChartElementDto { @ApiProperty({ description: '주가 지수' }) value: string; + + @ApiProperty({ description: '전일 대비 주가 지수' }) + diff: string; } diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock.index.service.ts index 587af43d..f15326f5 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock.index.service.ts @@ -21,6 +21,7 @@ export class StockIndexService { return new StockIndexListChartElementDto( element.bsop_hour, element.bstp_nmix_prpr, + element.bstp_nmix_prdy_vrss, ); }); } From 19fccb72de3a981e3a60a3724245163d04397953 Mon Sep 17 00:00:00 2001 From: anjdydhody Date: Mon, 11 Nov 2024 10:57:13 +0900 Subject: [PATCH 16/16] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=EB=B0=B1=EC=97=94=EB=93=9C=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/src/app.module.ts | 6 +++--- BE/src/auth/auth.controller.ts | 2 +- BE/src/auth/auth.service.ts | 2 +- ...{authCredentials.dto.ts => auth-credentials.dto.ts} | 0 BE/src/auth/user.repository.ts | 2 +- ...ment.interface.ts => korea-investment.interface.ts} | 0 ...investment.module.ts => korea-investment.module.ts} | 2 +- ...vestment.service.ts => korea-investment.service.ts} | 4 ++-- BE/src/stock/enum/{MarketType.ts => market-type.ts} | 0 ...nt.dto.ts => stock-index-list-chart.element.dto.ts} | 0 ...ment.dto.ts => stock-index-response-element.dto.ts} | 4 ++-- ...dex.response.dto.ts => stock-index-response.dto.ts} | 2 +- ...element.dto.ts => stock-index-value-element.dto.ts} | 0 ...ock.index.interface.ts => stock-index.interface.ts} | 0 ...k.index.controller.ts => stock-index.controller.ts} | 6 +++--- .../{stock.index.module.ts => stock-index.module.ts} | 6 +++--- .../{stock.index.service.ts => stock-index.service.ts} | 10 +++++----- ...topfive.interface.ts => stock-topfive.interface.ts} | 0 ...pfive.controller.ts => stock-topfive.controller.ts} | 4 ++-- ...stock.topfive.module.ts => stock-topfive.module.ts} | 6 +++--- ...ock.topfive.service.ts => stock-topfive.service.ts} | 10 +++++----- BE/src/util/{getFullURL.ts => get-full-URL.ts} | 0 BE/src/util/{getHeader.ts => get-header.ts} | 0 BE/src/websocket/socket.service.ts | 4 ++-- BE/test/stock/index/stock.index.list.e2e-spec.ts | 2 +- BE/test/stock/index/stock.index.value.e2e-spec.ts | 2 +- 26 files changed, 37 insertions(+), 37 deletions(-) rename BE/src/auth/dto/{authCredentials.dto.ts => auth-credentials.dto.ts} (100%) rename BE/src/koreaInvestment/interface/{korea.investment.interface.ts => korea-investment.interface.ts} (100%) rename BE/src/koreaInvestment/{korea.investment.module.ts => korea-investment.module.ts} (76%) rename BE/src/koreaInvestment/{korea.investment.service.ts => korea-investment.service.ts} (89%) rename BE/src/stock/enum/{MarketType.ts => market-type.ts} (100%) rename BE/src/stock/index/dto/{stock.index.list.chart.element.dto.ts => stock-index-list-chart.element.dto.ts} (100%) rename BE/src/stock/index/dto/{stock.index.response.element.dto.ts => stock-index-response-element.dto.ts} (71%) rename BE/src/stock/index/dto/{stock.index.response.dto.ts => stock-index-response.dto.ts} (88%) rename BE/src/stock/index/dto/{stock.index.value.element.dto.ts => stock-index-value-element.dto.ts} (100%) rename BE/src/stock/index/interface/{stock.index.interface.ts => stock-index.interface.ts} (100%) rename BE/src/stock/index/{stock.index.controller.ts => stock-index.controller.ts} (96%) rename BE/src/stock/index/{stock.index.module.ts => stock-index.module.ts} (71%) rename BE/src/stock/index/{stock.index.service.ts => stock-index.service.ts} (87%) rename BE/src/stock/topfive/interface/{stock.topfive.interface.ts => stock-topfive.interface.ts} (100%) rename BE/src/stock/topfive/{stock.topfive.controller.ts => stock-topfive.controller.ts} (88%) rename BE/src/stock/topfive/{stock.topfive.module.ts => stock-topfive.module.ts} (68%) rename BE/src/stock/topfive/{stock.topfive.service.ts => stock-topfive.service.ts} (95%) rename BE/src/util/{getFullURL.ts => get-full-URL.ts} (100%) rename BE/src/util/{getHeader.ts => get-header.ts} (100%) diff --git a/BE/src/app.module.ts b/BE/src/app.module.ts index fbef051f..114ecadf 100644 --- a/BE/src/app.module.ts +++ b/BE/src/app.module.ts @@ -6,9 +6,9 @@ import { AppController } from './app.controller'; import { AppService } from './app.service'; import { AuthModule } from './auth/auth.module'; import { User } from './auth/user.entity'; -import { StockIndexModule } from './stock/index/stock.index.module'; -import { StockTopfiveModule } from './stock/topfive/stock.topfive.module'; -import { KoreaInvestmentModule } from './koreaInvestment/korea.investment.module'; +import { StockIndexModule } from './stock/index/stock-index.module'; +import { StockTopfiveModule } from './stock/topfive/stock-topfive.module'; +import { KoreaInvestmentModule } from './koreaInvestment/korea-investment.module'; import { SocketModule } from './websocket/socket.module'; @Module({ diff --git a/BE/src/auth/auth.controller.ts b/BE/src/auth/auth.controller.ts index 8411eb48..aee104f0 100644 --- a/BE/src/auth/auth.controller.ts +++ b/BE/src/auth/auth.controller.ts @@ -10,7 +10,7 @@ import { import { AuthGuard } from '@nestjs/passport'; import { ApiOperation } from '@nestjs/swagger'; import { AuthService } from './auth.service'; -import { AuthCredentialsDto } from './dto/authCredentials.dto'; +import { AuthCredentialsDto } from './dto/auth-credentials.dto'; @Controller('auth') export class AuthController { diff --git a/BE/src/auth/auth.service.ts b/BE/src/auth/auth.service.ts index cbc4a69f..6f751e1b 100644 --- a/BE/src/auth/auth.service.ts +++ b/BE/src/auth/auth.service.ts @@ -3,7 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { JwtService } from '@nestjs/jwt'; import * as bcrypt from 'bcrypt'; import { UserRepository } from './user.repository'; -import { AuthCredentialsDto } from './dto/authCredentials.dto'; +import { AuthCredentialsDto } from './dto/auth-credentials.dto'; @Injectable() export class AuthService { diff --git a/BE/src/auth/dto/authCredentials.dto.ts b/BE/src/auth/dto/auth-credentials.dto.ts similarity index 100% rename from BE/src/auth/dto/authCredentials.dto.ts rename to BE/src/auth/dto/auth-credentials.dto.ts diff --git a/BE/src/auth/user.repository.ts b/BE/src/auth/user.repository.ts index 0a23f980..429437e7 100644 --- a/BE/src/auth/user.repository.ts +++ b/BE/src/auth/user.repository.ts @@ -3,7 +3,7 @@ import { InjectDataSource } from '@nestjs/typeorm'; import { DataSource, Repository } from 'typeorm'; import * as bcrypt from 'bcrypt'; import { User } from './user.entity'; -import { AuthCredentialsDto } from './dto/authCredentials.dto'; +import { AuthCredentialsDto } from './dto/auth-credentials.dto'; @Injectable() export class UserRepository extends Repository { diff --git a/BE/src/koreaInvestment/interface/korea.investment.interface.ts b/BE/src/koreaInvestment/interface/korea-investment.interface.ts similarity index 100% rename from BE/src/koreaInvestment/interface/korea.investment.interface.ts rename to BE/src/koreaInvestment/interface/korea-investment.interface.ts diff --git a/BE/src/koreaInvestment/korea.investment.module.ts b/BE/src/koreaInvestment/korea-investment.module.ts similarity index 76% rename from BE/src/koreaInvestment/korea.investment.module.ts rename to BE/src/koreaInvestment/korea-investment.module.ts index 69679c6b..8e7dd10a 100644 --- a/BE/src/koreaInvestment/korea.investment.module.ts +++ b/BE/src/koreaInvestment/korea-investment.module.ts @@ -1,5 +1,5 @@ import { Module } from '@nestjs/common'; -import { KoreaInvestmentService } from './korea.investment.service'; +import { KoreaInvestmentService } from './korea-investment.service'; @Module({ imports: [], diff --git a/BE/src/koreaInvestment/korea.investment.service.ts b/BE/src/koreaInvestment/korea-investment.service.ts similarity index 89% rename from BE/src/koreaInvestment/korea.investment.service.ts rename to BE/src/koreaInvestment/korea-investment.service.ts index 727c044c..29dc323c 100644 --- a/BE/src/koreaInvestment/korea.investment.service.ts +++ b/BE/src/koreaInvestment/korea-investment.service.ts @@ -1,7 +1,7 @@ import axios from 'axios'; import { UnauthorizedException } from '@nestjs/common'; -import { getFullURL } from '../util/getFullURL'; -import { AccessTokenInterface } from './interface/korea.investment.interface'; +import { getFullURL } from '../util/get-full-URL'; +import { AccessTokenInterface } from './interface/korea-investment.interface'; export class KoreaInvestmentService { private accessToken: string; diff --git a/BE/src/stock/enum/MarketType.ts b/BE/src/stock/enum/market-type.ts similarity index 100% rename from BE/src/stock/enum/MarketType.ts rename to BE/src/stock/enum/market-type.ts diff --git a/BE/src/stock/index/dto/stock.index.list.chart.element.dto.ts b/BE/src/stock/index/dto/stock-index-list-chart.element.dto.ts similarity index 100% rename from BE/src/stock/index/dto/stock.index.list.chart.element.dto.ts rename to BE/src/stock/index/dto/stock-index-list-chart.element.dto.ts diff --git a/BE/src/stock/index/dto/stock.index.response.element.dto.ts b/BE/src/stock/index/dto/stock-index-response-element.dto.ts similarity index 71% rename from BE/src/stock/index/dto/stock.index.response.element.dto.ts rename to BE/src/stock/index/dto/stock-index-response-element.dto.ts index 09e21102..79cf6af5 100644 --- a/BE/src/stock/index/dto/stock.index.response.element.dto.ts +++ b/BE/src/stock/index/dto/stock-index-response-element.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; -import { StockIndexValueElementDto } from './stock.index.value.element.dto'; -import { StockIndexListChartElementDto } from './stock.index.list.chart.element.dto'; +import { StockIndexValueElementDto } from './stock-index-value-element.dto'; +import { StockIndexListChartElementDto } from './stock-index-list-chart.element.dto'; export class StockIndexResponseElementDto { @ApiProperty({ description: '실시간 값', type: StockIndexValueElementDto }) diff --git a/BE/src/stock/index/dto/stock.index.response.dto.ts b/BE/src/stock/index/dto/stock-index-response.dto.ts similarity index 88% rename from BE/src/stock/index/dto/stock.index.response.dto.ts rename to BE/src/stock/index/dto/stock-index-response.dto.ts index 7f26af32..026fecf3 100644 --- a/BE/src/stock/index/dto/stock.index.response.dto.ts +++ b/BE/src/stock/index/dto/stock-index-response.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { StockIndexResponseElementDto } from './stock.index.response.element.dto'; +import { StockIndexResponseElementDto } from './stock-index-response-element.dto'; export class StockIndexResponseDto { @ApiProperty({ diff --git a/BE/src/stock/index/dto/stock.index.value.element.dto.ts b/BE/src/stock/index/dto/stock-index-value-element.dto.ts similarity index 100% rename from BE/src/stock/index/dto/stock.index.value.element.dto.ts rename to BE/src/stock/index/dto/stock-index-value-element.dto.ts diff --git a/BE/src/stock/index/interface/stock.index.interface.ts b/BE/src/stock/index/interface/stock-index.interface.ts similarity index 100% rename from BE/src/stock/index/interface/stock.index.interface.ts rename to BE/src/stock/index/interface/stock-index.interface.ts diff --git a/BE/src/stock/index/stock.index.controller.ts b/BE/src/stock/index/stock-index.controller.ts similarity index 96% rename from BE/src/stock/index/stock.index.controller.ts rename to BE/src/stock/index/stock-index.controller.ts index 7625e044..330685e2 100644 --- a/BE/src/stock/index/stock.index.controller.ts +++ b/BE/src/stock/index/stock-index.controller.ts @@ -1,9 +1,9 @@ import { Controller, Get } from '@nestjs/common'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { Cron } from '@nestjs/schedule'; -import { StockIndexService } from './stock.index.service'; -import { StockIndexResponseDto } from './dto/stock.index.response.dto'; -import { KoreaInvestmentService } from '../../koreaInvestment/korea.investment.service'; +import { StockIndexService } from './stock-index.service'; +import { StockIndexResponseDto } from './dto/stock-index-response.dto'; +import { KoreaInvestmentService } from '../../koreaInvestment/korea-investment.service'; import { SocketGateway } from '../../websocket/socket.gateway'; @Controller('/api/stocks/index') diff --git a/BE/src/stock/index/stock.index.module.ts b/BE/src/stock/index/stock-index.module.ts similarity index 71% rename from BE/src/stock/index/stock.index.module.ts rename to BE/src/stock/index/stock-index.module.ts index 1227e4f7..64e0c575 100644 --- a/BE/src/stock/index/stock.index.module.ts +++ b/BE/src/stock/index/stock-index.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; -import { StockIndexController } from './stock.index.controller'; -import { StockIndexService } from './stock.index.service'; -import { KoreaInvestmentModule } from '../../koreaInvestment/korea.investment.module'; +import { StockIndexController } from './stock-index.controller'; +import { StockIndexService } from './stock-index.service'; +import { KoreaInvestmentModule } from '../../koreaInvestment/korea-investment.module'; import { SocketModule } from '../../websocket/socket.module'; @Module({ diff --git a/BE/src/stock/index/stock.index.service.ts b/BE/src/stock/index/stock-index.service.ts similarity index 87% rename from BE/src/stock/index/stock.index.service.ts rename to BE/src/stock/index/stock-index.service.ts index f15326f5..fa05ed4c 100644 --- a/BE/src/stock/index/stock.index.service.ts +++ b/BE/src/stock/index/stock-index.service.ts @@ -1,13 +1,13 @@ import { Injectable, InternalServerErrorException } from '@nestjs/common'; import axios from 'axios'; -import { StockIndexListChartElementDto } from './dto/stock.index.list.chart.element.dto'; -import { StockIndexValueElementDto } from './dto/stock.index.value.element.dto'; +import { StockIndexListChartElementDto } from './dto/stock-index-list-chart.element.dto'; +import { StockIndexValueElementDto } from './dto/stock-index-value-element.dto'; import { StockIndexChartInterface, StockIndexValueInterface, -} from './interface/stock.index.interface'; -import { getFullURL } from '../../util/getFullURL'; -import { getHeader } from '../../util/getHeader'; +} from './interface/stock-index.interface'; +import { getFullURL } from '../../util/get-full-URL'; +import { getHeader } from '../../util/get-header'; @Injectable() export class StockIndexService { diff --git a/BE/src/stock/topfive/interface/stock.topfive.interface.ts b/BE/src/stock/topfive/interface/stock-topfive.interface.ts similarity index 100% rename from BE/src/stock/topfive/interface/stock.topfive.interface.ts rename to BE/src/stock/topfive/interface/stock-topfive.interface.ts diff --git a/BE/src/stock/topfive/stock.topfive.controller.ts b/BE/src/stock/topfive/stock-topfive.controller.ts similarity index 88% rename from BE/src/stock/topfive/stock.topfive.controller.ts rename to BE/src/stock/topfive/stock-topfive.controller.ts index f90d300a..bac275e3 100644 --- a/BE/src/stock/topfive/stock.topfive.controller.ts +++ b/BE/src/stock/topfive/stock-topfive.controller.ts @@ -1,8 +1,8 @@ import { ApiOperation, ApiQuery, ApiResponse } from '@nestjs/swagger'; import { Controller, Get, Query } from '@nestjs/common'; -import { StockTopfiveService } from './stock.topfive.service'; +import { StockTopfiveService } from './stock-topfive.service'; import { StockRankingResponseDto } from './dto/stock-ranking-response.dto'; -import { MarketType } from '../enum/MarketType'; +import { MarketType } from '../enum/market-type'; @Controller('/api/stocks') export class StockTopfiveController { diff --git a/BE/src/stock/topfive/stock.topfive.module.ts b/BE/src/stock/topfive/stock-topfive.module.ts similarity index 68% rename from BE/src/stock/topfive/stock.topfive.module.ts rename to BE/src/stock/topfive/stock-topfive.module.ts index 33a63aae..5be62a4f 100644 --- a/BE/src/stock/topfive/stock.topfive.module.ts +++ b/BE/src/stock/topfive/stock-topfive.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; -import { StockTopfiveController } from './stock.topfive.controller'; -import { StockTopfiveService } from './stock.topfive.service'; -import { KoreaInvestmentModule } from '../../koreaInvestment/korea.investment.module'; +import { StockTopfiveController } from './stock-topfive.controller'; +import { StockTopfiveService } from './stock-topfive.service'; +import { KoreaInvestmentModule } from '../../koreaInvestment/korea-investment.module'; @Module({ imports: [ConfigModule, KoreaInvestmentModule], diff --git a/BE/src/stock/topfive/stock.topfive.service.ts b/BE/src/stock/topfive/stock-topfive.service.ts similarity index 95% rename from BE/src/stock/topfive/stock.topfive.service.ts rename to BE/src/stock/topfive/stock-topfive.service.ts index d8da1643..82f659d5 100644 --- a/BE/src/stock/topfive/stock.topfive.service.ts +++ b/BE/src/stock/topfive/stock-topfive.service.ts @@ -3,14 +3,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { StockRankingQueryParameterDto } from './dto/stock-ranking-request.dto'; import { StockRankingResponseDto } from './dto/stock-ranking-response.dto'; import { StockRankingDataDto } from './dto/stock-ranking-data.dto'; -import { MarketType } from '../enum/MarketType'; +import { MarketType } from '../enum/market-type'; import { StockApiOutputData, StockApiResponse, -} from './interface/stock.topfive.interface'; -import { getHeader } from '../../util/getHeader'; -import { getFullURL } from '../../util/getFullURL'; -import { KoreaInvestmentService } from '../../koreaInvestment/korea.investment.service'; +} from './interface/stock-topfive.interface'; +import { getHeader } from '../../util/get-header'; +import { getFullURL } from '../../util/get-full-URL'; +import { KoreaInvestmentService } from '../../koreaInvestment/korea-investment.service'; @Injectable() export class StockTopfiveService { diff --git a/BE/src/util/getFullURL.ts b/BE/src/util/get-full-URL.ts similarity index 100% rename from BE/src/util/getFullURL.ts rename to BE/src/util/get-full-URL.ts diff --git a/BE/src/util/getHeader.ts b/BE/src/util/get-header.ts similarity index 100% rename from BE/src/util/getHeader.ts rename to BE/src/util/get-header.ts diff --git a/BE/src/websocket/socket.service.ts b/BE/src/websocket/socket.service.ts index 042cd57a..0bcb7b64 100644 --- a/BE/src/websocket/socket.service.ts +++ b/BE/src/websocket/socket.service.ts @@ -2,9 +2,9 @@ import { Injectable, OnModuleInit } from '@nestjs/common'; import { WebSocket } from 'ws'; import axios from 'axios'; import { SocketGateway } from './socket.gateway'; -import { StockIndexValueElementDto } from '../stock/index/dto/stock.index.value.element.dto'; +import { StockIndexValueElementDto } from '../stock/index/dto/stock-index-value-element.dto'; import { SocketConnectTokenInterface } from './interface/socket.interface'; -import { getFullURL } from '../util/getFullURL'; +import { getFullURL } from '../util/get-full-URL'; @Injectable() export class SocketService implements OnModuleInit { diff --git a/BE/test/stock/index/stock.index.list.e2e-spec.ts b/BE/test/stock/index/stock.index.list.e2e-spec.ts index 7518b75d..9a844581 100644 --- a/BE/test/stock/index/stock.index.list.e2e-spec.ts +++ b/BE/test/stock/index/stock.index.list.e2e-spec.ts @@ -1,6 +1,6 @@ import { Test } from '@nestjs/testing'; import axios from 'axios'; -import { StockIndexService } from '../../../src/stock/index/stock.index.service'; +import { StockIndexService } from '../../../src/stock/index/stock-index.service'; import { STOCK_INDEX_LIST_MOCK } from './mockdata/stock.index.list.mockdata'; jest.mock('axios'); diff --git a/BE/test/stock/index/stock.index.value.e2e-spec.ts b/BE/test/stock/index/stock.index.value.e2e-spec.ts index 12ff2590..2008f2e4 100644 --- a/BE/test/stock/index/stock.index.value.e2e-spec.ts +++ b/BE/test/stock/index/stock.index.value.e2e-spec.ts @@ -1,6 +1,6 @@ import { Test } from '@nestjs/testing'; import axios from 'axios'; -import { StockIndexService } from '../../../src/stock/index/stock.index.service'; +import { StockIndexService } from '../../../src/stock/index/stock-index.service'; import { STOCK_INDEX_VALUE_MOCK } from './mockdata/stock.index.value.mockdata'; jest.mock('axios');