From 7b71c74147e8e84c451f4a69b52e865e26e0a499 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 14:37:38 +0900 Subject: [PATCH 01/32] =?UTF-8?q?=E2=9C=A8=20feat(module=20openapi-scrappe?= =?UTF-8?q?r=20=EC=B6=94=EA=B0=80):=20module=EB=A1=9C=20=EA=B0=9C=EB=B0=9C?= =?UTF-8?q?=20=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 3 ++- .../src/openapi-scraper/openapi-scraper.controller.ts | 4 ++++ .../src/openapi-scraper/openapi-scraper.module.ts | 9 +++++++++ packages/backend/src/openapi-scraper/openapi-scraper.ts | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.controller.ts create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.module.ts create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.ts diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 86628031..8cf93bee 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -1,9 +1,10 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { OpenapiScraperModule } from './openapi-scraper/openapi-scraper.module'; @Module({ - imports: [], + imports: [OpenapiScraperModule], controllers: [AppController], providers: [AppService], }) diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts b/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts new file mode 100644 index 00000000..56e60188 --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('openapi-scraper') +export class OpenapiScraperController {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts new file mode 100644 index 00000000..ea4f791f --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { OpenapiScraperController } from './openapi-scraper.controller'; +import { OpenapiScraper } from './openapi-scraper'; + +@Module({ + controllers: [OpenapiScraperController], + providers: [OpenapiScraper] +}) +export class OpenapiScraperModule {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.ts b/packages/backend/src/openapi-scraper/openapi-scraper.ts new file mode 100644 index 00000000..621c0988 --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class OpenapiScraper {} From 0daf7a9311c3bf2da89f5ecbc178ecbd14bcd800 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 18:04:46 +0900 Subject: [PATCH 02/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20backend=20packege?= =?UTF-8?q?=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/openapi-scraper/env.service.ts | 23 +++++++++++++++++++ .../openapi-scraper.controller.ts | 4 ---- .../openapi-scraper/openapi-scraper.module.ts | 16 +++++++++---- .../openapi-scraper.service.ts | 12 ++++++++++ .../src/openapi-scraper/openapi-scraper.ts | 4 ---- 5 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 packages/backend/src/openapi-scraper/env.service.ts delete mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.controller.ts create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.service.ts delete mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.ts diff --git a/packages/backend/src/openapi-scraper/env.service.ts b/packages/backend/src/openapi-scraper/env.service.ts new file mode 100644 index 00000000..d6f22a46 --- /dev/null +++ b/packages/backend/src/openapi-scraper/env.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; + +@Injectable() +export class EnvService { + public constructor(private configService: ConfigService) {} + + private getKeyValue(key: string): { key: string; value: string } { + return { key: key, value: this.configService.get(key) }; + } + + public getOpenApiUrl() { + return this.getKeyValue("PROD"); + } + + public getAppKey() { + return this.getKeyValue("PROD_APPKEY"); + } + + public getAppSecret() { + return this.getKeyValue("PROD_APPSECRET"); + } +} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts b/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts deleted file mode 100644 index 56e60188..00000000 --- a/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Controller } from '@nestjs/common'; - -@Controller('openapi-scraper') -export class OpenapiScraperController {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts index ea4f791f..d8c45d28 100644 --- a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts +++ b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts @@ -1,9 +1,15 @@ -import { Module } from '@nestjs/common'; -import { OpenapiScraperController } from './openapi-scraper.controller'; -import { OpenapiScraper } from './openapi-scraper'; +import { Module } from "@nestjs/common"; +import { ConfigModule } from "@nestjs/config"; +import { OpenapiScraperService } from "./openapi-scraper.service"; +import { EnvService } from "./env.service"; @Module({ - controllers: [OpenapiScraperController], - providers: [OpenapiScraper] + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + }), + ], + controllers: [], + providers: [OpenapiScraperService, EnvService], }) export class OpenapiScraperModule {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.service.ts b/packages/backend/src/openapi-scraper/openapi-scraper.service.ts new file mode 100644 index 00000000..69c366f0 --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.service.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { EnvService } from "./env.service"; + +@Injectable() +export class OpenapiScraperService { + private token: string; + public constructor(private env: EnvService) {} + + private async fetchOpenApiSpec(url: string): Promise {} + + private getToken() {} +} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.ts b/packages/backend/src/openapi-scraper/openapi-scraper.ts deleted file mode 100644 index 621c0988..00000000 --- a/packages/backend/src/openapi-scraper/openapi-scraper.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class OpenapiScraper {} From 8550f8cb240555b45841a9dcdc4160981520281d Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 18:06:00 +0900 Subject: [PATCH 03/32] =?UTF-8?q?=E2=9C=A8=20feat:=20backend/stock-price?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 3 +++ packages/backend/src/app.controller.spec.ts | 22 ------------------- packages/backend/src/app.controller.ts | 16 -------------- packages/backend/src/app.module.ts | 9 ++++---- packages/backend/src/app.service.ts | 8 ------- .../src/stock-price/stock-price.module.ts | 4 ++++ 6 files changed, 11 insertions(+), 51 deletions(-) delete mode 100644 packages/backend/src/app.controller.spec.ts delete mode 100644 packages/backend/src/app.controller.ts delete mode 100644 packages/backend/src/app.service.ts create mode 100644 packages/backend/src/stock-price/stock-price.module.ts diff --git a/packages/backend/package.json b/packages/backend/package.json index bdd11622..338862d4 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -21,8 +21,10 @@ }, "dependencies": { "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.3.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", + "dotenv": "^16.4.5", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, @@ -36,6 +38,7 @@ "@types/supertest": "^6.0.0", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", + "cz-emoji-conventional": "^1.1.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", diff --git a/packages/backend/src/app.controller.spec.ts b/packages/backend/src/app.controller.spec.ts deleted file mode 100644 index d22f3890..00000000 --- a/packages/backend/src/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile(); - - appController = app.get(AppController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(appController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/packages/backend/src/app.controller.ts b/packages/backend/src/app.controller.ts deleted file mode 100644 index d87f0844..00000000 --- a/packages/backend/src/app.controller.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Controller, Get } from "@nestjs/common"; -import { AppService } from "./app.service"; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - getHello(): string { - return this.appService.getHello(); - } - - getHi(a: any): string { - return "hi"; - } -} diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 8cf93bee..38fa4dea 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -1,11 +1,10 @@ import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; +import { StockPriceModule } from './stock-price/stock-price.module'; import { OpenapiScraperModule } from './openapi-scraper/openapi-scraper.module'; @Module({ - imports: [OpenapiScraperModule], - controllers: [AppController], - providers: [AppService], + imports: [OpenapiScraperModule, StockPriceModule], + controllers: [], + providers: [], }) export class AppModule {} diff --git a/packages/backend/src/app.service.ts b/packages/backend/src/app.service.ts deleted file mode 100644 index 927d7cca..00000000 --- a/packages/backend/src/app.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class AppService { - getHello(): string { - return 'Hello World!'; - } -} diff --git a/packages/backend/src/stock-price/stock-price.module.ts b/packages/backend/src/stock-price/stock-price.module.ts new file mode 100644 index 00000000..c6df3a29 --- /dev/null +++ b/packages/backend/src/stock-price/stock-price.module.ts @@ -0,0 +1,4 @@ +import { Module } from '@nestjs/common'; + +@Module({}) +export class StockPriceModule {} From 4a3a04ddbc8525b439e3503158f95e6892c54847 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 18:06:33 +0900 Subject: [PATCH 04/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20yarn.lock=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yarn.lock | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 27daad31..42756536 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1066,6 +1066,15 @@ iterare "1.2.1" tslib "2.7.0" +"@nestjs/config@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@nestjs/config/-/config-3.3.0.tgz#ddc520ba26a8453ee5e690e18fb7b35e9bac7974" + integrity sha512-pdGTp8m9d0ZCrjTpjkUbZx6gyf2IKf+7zlkrPNMsJzYZ4bFRRTpXrnj+556/5uiI6AfL5mMrJc2u7dB6bvM+VA== + dependencies: + dotenv "16.4.5" + dotenv-expand "10.0.0" + lodash "4.17.21" + "@nestjs/core@^10.0.0": version "10.4.6" resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-10.4.6.tgz#797b381f12bd62d2e425897058fa219da4c3689d" @@ -2377,7 +2386,7 @@ comment-json@4.2.5: has-own-prop "^2.0.0" repeat-string "^1.6.1" -commitizen@^4.0.3, commitizen@^4.3.1: +commitizen@^4.0.3, commitizen@^4.3.0, commitizen@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/commitizen/-/commitizen-4.3.1.tgz#f0e0e4b7ae3fafc92e444bbb78f2ded5a1d4311a" integrity sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw== @@ -2594,6 +2603,15 @@ cz-customizable@^7.2.1: temp "^0.9.0" word-wrap "^1.2.3" +cz-emoji-conventional@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cz-emoji-conventional/-/cz-emoji-conventional-1.1.0.tgz#c42c34828619a5c2c7337afd4798c7da4366c753" + integrity sha512-W0EHK/Ek9ZHwJ+UaClF/xBHp6lkLuJgkiREiCVnwGuIz8Jhp/khoQzLcRI9AAF6vfT2slfz7E+RgGelmsVfzoQ== + dependencies: + chalk "4.1.2" + commitizen "^4.3.0" + word-wrap "^1.2.3" + dargs@^8.0.0: version "8.1.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-8.1.0.tgz#a34859ea509cbce45485e5aa356fef70bfcc7272" @@ -2721,6 +2739,16 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" +dotenv-expand@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== + +dotenv@16.4.5, dotenv@^16.4.5: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" From 2f40f4b4b719087ab1e30684c4066b1d83d87420 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Thu, 7 Nov 2024 14:43:20 +0900 Subject: [PATCH 05/32] =?UTF-8?q?=E2=9C=A8=20feat(korea-stock-info.*.ts):?= =?UTF-8?q?=20=ED=95=9C=EA=B5=AD=20=EC=A3=BC=EC=8B=9D=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EB=A5=BC=20=ED=8C=8C=EC=8B=B1=ED=95=98=EA=B3=A0,=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20=EA=B2=83=EC=9D=84=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.controller.ts | 16 -- packages/backend/src/app.module.ts | 6 +- .../src/openapi-scraper/env.service.ts | 23 --- .../korea-stock-info/dto/download.dto.ts | 3 + .../korea-stock-info/entities/stock.entity.ts | 22 +++ .../korea-stock-info.controller.spec.ts | 18 +++ .../korea-stock-info.controller.ts | 4 + .../korea-stock-info.service.spec.ts | 18 +++ .../korea-stock-info.service.ts | 140 ++++++++++++++++++ .../openapi-scraper/openapi-scraper.module.ts | 14 +- .../openapi-scraper.service.ts | 35 ++++- .../src/openapi-scraper/openapi.config.ts | 12 ++ 12 files changed, 255 insertions(+), 56 deletions(-) delete mode 100644 packages/backend/src/app.controller.ts delete mode 100644 packages/backend/src/openapi-scraper/env.service.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.spec.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.spec.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts create mode 100644 packages/backend/src/openapi-scraper/openapi.config.ts diff --git a/packages/backend/src/app.controller.ts b/packages/backend/src/app.controller.ts deleted file mode 100644 index 8de39f5b..00000000 --- a/packages/backend/src/app.controller.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { AppService } from './app.service'; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - getHello(): string { - return this.appService.getHello(); - } - - getHi(a: any): string { - return 'hi'; - } -} diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 17340480..2270d70a 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -5,7 +5,11 @@ import { OpenapiScraperModule } from './openapi-scraper/openapi-scraper.module'; import { typeormConfig } from '@/configs/typeorm.config'; @Module({ - imports: [TypeOrmModule.forRoot(typeormConfig)OpenapiScraperModule, StockPriceModule], + imports: [ + TypeOrmModule.forRoot(typeormConfig), + OpenapiScraperModule, + StockPriceModule, + ], controllers: [], providers: [], }) diff --git a/packages/backend/src/openapi-scraper/env.service.ts b/packages/backend/src/openapi-scraper/env.service.ts deleted file mode 100644 index d6f22a46..00000000 --- a/packages/backend/src/openapi-scraper/env.service.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; - -@Injectable() -export class EnvService { - public constructor(private configService: ConfigService) {} - - private getKeyValue(key: string): { key: string; value: string } { - return { key: key, value: this.configService.get(key) }; - } - - public getOpenApiUrl() { - return this.getKeyValue("PROD"); - } - - public getAppKey() { - return this.getKeyValue("PROD_APPKEY"); - } - - public getAppSecret() { - return this.getKeyValue("PROD_APPSECRET"); - } -} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts b/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts new file mode 100644 index 00000000..c4c886b8 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts @@ -0,0 +1,3 @@ +export class DownloadDto { + baseDir!: string; +} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts b/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts new file mode 100644 index 00000000..4c52f1c6 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts @@ -0,0 +1,22 @@ +import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity() +export class KospiMaster { + @PrimaryGeneratedColumn({ type: 'int', unsigned: true }) + id?: number; + + @Column() + shortCode?: string; + + @Column() + standardCode?: string; + + @Column() + koreanName?: string; + + @Column() + groupCode?: string; + + @Column() + marketCapSize?: string; +} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.spec.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.spec.ts new file mode 100644 index 00000000..6818fba0 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { KoreaStockInfoController } from './korea-stock-info.controller'; + +describe('KoreaStockInfoController', () => { + let controller: KoreaStockInfoController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [KoreaStockInfoController], + }).compile(); + + controller = module.get(KoreaStockInfoController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.ts new file mode 100644 index 00000000..0171b0d6 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('korea-stock-info') +export class KoreaStockInfoController {} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.spec.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.spec.ts new file mode 100644 index 00000000..c8197ee4 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { KoreaStockInfoService } from './korea-stock-info.service'; + +describe('KoreaStockInfoService', () => { + let service: KoreaStockInfoService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [KoreaStockInfoService], + }).compile(); + + service = module.get(KoreaStockInfoService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts new file mode 100644 index 00000000..87de51d9 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts @@ -0,0 +1,140 @@ +import { Injectable } from '@nestjs/common'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as https from 'https'; +import * as readline from 'readline'; +import * as iconv from 'iconv-lite'; +import * as unzipper from 'unzipper'; +import { DownloadDto } from './dto/download.dto'; +import { KospiMaster } from './entities/stock.entity'; + +@Injectable() +export class KoreaStockInfoService { + constructor() { + this.downloadKosdaqMaster({ baseDir: './' }); + this.downloadKospiMaster({ baseDir: './' }); + + this.getKospiMasterData('./'); + this.getKosdaqMasterData('./'); + } + + private async downloadFile(url: string, filePath: string): Promise { + return new Promise((resolve, reject) => { + const file = fs.createWriteStream(filePath); + https + .get(url, (response) => { + response.pipe(file); + file.on('finish', () => { + file.close(); + resolve(); + }); + }) + .on('error', (error) => { + fs.unlinkSync(filePath); + reject(error); + }); + }); + } + + private async extractZip(filePath: string, extractTo: string): Promise { + await fs + .createReadStream(filePath) + .pipe(unzipper.Extract({ path: extractTo })) + .promise(); + } + + public async downloadKosdaqMaster(downloadDto: DownloadDto): Promise { + const { baseDir } = downloadDto; + const fileName = 'kosdaq_code.zip'; + const filePath = path.join(baseDir, fileName); + const extractedFile = path.join(baseDir, 'kosdaq_code.mst'); + + await this.downloadFile( + 'https://new.real.download.dws.co.kr/common/master/kosdaq_code.mst.zip', + filePath, + ); + await this.extractZip(filePath, baseDir); + + fs.unlink(filePath, (err) => { + if (err) throw err; + }); + + return extractedFile; + } + + public async downloadKospiMaster(downloadDto: DownloadDto): Promise { + const { baseDir } = downloadDto; + const fileName = 'kospi_code.zip'; + const filePath = path.join(baseDir, fileName); + const extractedFile = path.join(baseDir, 'kospi_code.mst'); + + await this.downloadFile( + 'https://new.real.download.dws.co.kr/common/master/kospi_code.mst.zip', + filePath, + ); + await this.extractZip(filePath, baseDir); + fs.unlink(filePath, (err) => { + if (err) throw err; + }); + + return extractedFile; + } + + public async getKospiMasterData(baseDir: string): Promise { + const fileName = path.join(baseDir, 'kospi_code.mst'); + const kospiMasters: KospiMaster[] = []; + + const rl = readline.createInterface({ + input: fs.createReadStream(fileName).pipe(iconv.decodeStream('cp949')), + crlfDelay: Infinity, + }); + + for await (const row of rl) { + const shortCode = row.slice(0, 9).trim(); + const standardCode = row.slice(9, 21).trim(); + const koreanName = row.slice(21, row.length - 228).trim(); + const groupCode = row.slice(-228, -226).trim(); + const marketCapSize = row.slice(-226, -225).trim(); + + kospiMasters.push({ + shortCode, + standardCode, + koreanName, + groupCode, + marketCapSize, + }); + } + + console.log('Done'); + return kospiMasters; + } + + public async getKosdaqMasterData(baseDir: string): Promise { + const fileName = path.join(baseDir, 'kosdaq_code.mst'); + const kosdaqMasters: KospiMaster[] = []; + + const rl = readline.createInterface({ + input: fs.createReadStream(fileName).pipe(iconv.decodeStream('cp949')), + crlfDelay: Infinity, + }); + + for await (const row of rl) { + const shortCode = row.slice(0, 9).trim(); + const standardCode = row.slice(9, 21).trim(); + const koreanName = row.slice(21, row.length - 222).trim(); + const groupCode = row.slice(-222, -220).trim(); + const marketCapSize = row.slice(-220, -219).trim(); + + kosdaqMasters.push({ + shortCode, + standardCode, + koreanName, + groupCode, + marketCapSize, + }); + } + + console.log('Done'); + return kosdaqMasters; + } +} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts index d8c45d28..7f272bd9 100644 --- a/packages/backend/src/openapi-scraper/openapi-scraper.module.ts +++ b/packages/backend/src/openapi-scraper/openapi-scraper.module.ts @@ -1,15 +1,9 @@ -import { Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { OpenapiScraperService } from "./openapi-scraper.service"; -import { EnvService } from "./env.service"; +import { Module } from '@nestjs/common'; +import { OpenapiScraperService } from './openapi-scraper.service'; @Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - }), - ], + imports: [], controllers: [], - providers: [OpenapiScraperService, EnvService], + providers: [OpenapiScraperService], }) export class OpenapiScraperModule {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.service.ts b/packages/backend/src/openapi-scraper/openapi-scraper.service.ts index 69c366f0..a4b14527 100644 --- a/packages/backend/src/openapi-scraper/openapi-scraper.service.ts +++ b/packages/backend/src/openapi-scraper/openapi-scraper.service.ts @@ -1,12 +1,35 @@ -import { Injectable } from "@nestjs/common"; -import { EnvService } from "./env.service"; +import { Injectable } from '@nestjs/common'; +import axios from 'axios'; +import { openApiConfig } from './openapi.config'; @Injectable() export class OpenapiScraperService { - private token: string; - public constructor(private env: EnvService) {} + private readonly config: typeof openApiConfig; + public constructor() { + this.config = openApiConfig; + this.getToken(); + } - private async fetchOpenApiSpec(url: string): Promise {} + private async fetchOpenApi( + url: string, + query: {} | undefined, + body: {}, + ): Promise { + try { + const response = await axios.post(url + "/oauth2/tokenP", body); + return response.data; // 응답에서 data 부분만 추출 + } catch (error) { + throw new Error(`Request failed: ${error}`); + } + } - private getToken() {} + private async getToken() { + const body = { + grant_type: 'client_credentials', + appkey: this.config.APPKEY, + appsecret: this.config.APPSECRET, + }; + const tmp = await this.fetchOpenApi(this.config.PROD!, undefined, body); + console.log(tmp.access_token); + } } diff --git a/packages/backend/src/openapi-scraper/openapi.config.ts b/packages/backend/src/openapi-scraper/openapi.config.ts new file mode 100644 index 00000000..3f3410ed --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi.config.ts @@ -0,0 +1,12 @@ +import * as dotenv from 'dotenv'; + +dotenv.config({ + path: './.env', +}); + +export const openApiConfig = { + PROD: process.env.PROD, + CANO_REAL: process.env.CANO_REAL, + APPKEY: process.env.PROD_APPKEY, + APPSECRET: process.env.PROD_APPSECRET, +}; From 33a64f10b5bbfb5308fdb947e2c9bb1723960d7e Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 14:18:02 +0900 Subject: [PATCH 06/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20deploy=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20front,=20backend=20dockerfile=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 66 +++++++++++++++++++ packages/backend/Dockerfile | 7 ++ .../stock-price.controller.spec.ts | 18 +++++ .../src/stock-price/stock-price.controller.ts | 5 ++ packages/frontend/Dockerfile | 11 ++++ 5 files changed, 107 insertions(+) create mode 100644 .github/workflows/deploy.yml create mode 100644 packages/backend/Dockerfile create mode 100644 packages/backend/src/stock-price/stock-price.controller.spec.ts create mode 100644 packages/backend/src/stock-price/stock-price.controller.ts create mode 100644 packages/frontend/Dockerfile diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..7ac3d1bc --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,66 @@ +name: Deploy Monorepo + +on: + push: + branches: + - dev + pull_request: + branches: + - dev + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + services: + docker: + image: docker:20.10.7 + options: --privileged + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Build frontend + run: | + yarn workspace frontend build + + - name: Build backend + run: | + yarn workspace backend build + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push frontend Docker image + run: | + docker build -t ${{ secrets.DOCKER_USERNAME }}/frontend:latest -f packages/frontend/Dockerfile . + docker push ${{ secrets.DOCKER_USERNAME }}/frontend:latest + + - name: Build and push backend Docker image + run: | + docker build -t ${{ secrets.DOCKER_USERNAME }}/backend:latest -f packages/backend/Dockerfile . + docker push ${{ secrets.DOCKER_USERNAME }}/backend:latest + + - name: Deploy to server + uses: appleboy/ssh-action@v1.1.0 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + key: ${{ secrets.SERVER_SSH_KEY }} + script: | + docker pull ${{ secrets.DOCKER_USERNAME }}/frontend:latest + docker pull ${{ secrets.DOCKER_USERNAME }}/backend:latest + docker-compose up -d diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile new file mode 100644 index 00000000..64d3605c --- /dev/null +++ b/packages/backend/Dockerfile @@ -0,0 +1,7 @@ +FROM node:18-alpine +WORKDIR /packages +COPY . . +RUN yarn install --frozen-lockfile +RUN yarn workspace backend build +EXPOSE 3000 +CMD ["yarn", "workspace", "backend", "start:prod"] diff --git a/packages/backend/src/stock-price/stock-price.controller.spec.ts b/packages/backend/src/stock-price/stock-price.controller.spec.ts new file mode 100644 index 00000000..a6fe3fb6 --- /dev/null +++ b/packages/backend/src/stock-price/stock-price.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StockPriceController } from './stock-price.controller'; + +describe('StockPriceController', () => { + let controller: StockPriceController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [StockPriceController], + }).compile(); + + controller = module.get(StockPriceController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/packages/backend/src/stock-price/stock-price.controller.ts b/packages/backend/src/stock-price/stock-price.controller.ts new file mode 100644 index 00000000..1436c6a1 --- /dev/null +++ b/packages/backend/src/stock-price/stock-price.controller.ts @@ -0,0 +1,5 @@ +import { Controller, HttpCode, Post } from '@nestjs/common'; + +@Controller('stock-price') +export class StockPriceController { +} diff --git a/packages/frontend/Dockerfile b/packages/frontend/Dockerfile new file mode 100644 index 00000000..e7f9eb0c --- /dev/null +++ b/packages/frontend/Dockerfile @@ -0,0 +1,11 @@ +FROM node:18-alpine AS builder +WORKDIR /packages +COPY . . +RUN yarn install --frozen-lockfile +RUN yarn workspace frontend build + +# Nginx 서버로 빌드된 파일 서빙 +FROM nginx:alpine +COPY --from=builder /packages/frontend/build /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] From 4167006458bd76dc7abfcf49e65a806b0d24d3bd Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 14:44:44 +0900 Subject: [PATCH 07/32] commit after merge --- .vscode/settings.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..0997a4dd --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "prettier.prettierPath": "./node_modules/prettier", + "prettier.configPath": "./.prettierrc", + "prettier.embeddedLanguageFormatting": "auto", + "editor.defaultFormatter": "esbenp.prettier-vscode" +} From f2cb471973009a776fa9cd9b98c5cb32063b84fb Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 15:01:35 +0900 Subject: [PATCH 08/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20yarn.lock,=20pack?= =?UTF-8?q?age.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISSUES CLOSED: unzipper, axios 설치 --- packages/backend/package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/backend/package.json b/packages/backend/package.json index c3a14aff..1fc0b895 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -28,6 +28,7 @@ "@nestjs/swagger": "^8.0.5", "@nestjs/typeorm": "^10.0.2", "@nestjs/websockets": "^10.4.7", + "axios": "^1.7.7", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", "dotenv": "^16.4.5", @@ -37,6 +38,7 @@ "rxjs": "^7.8.1", "socket.io": "^4.8.1", "typeorm": "^0.3.20", + "unzipper": "^0.12.3", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" }, From 63074dc881bf7f48eea331409987730422390410 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 15:16:05 +0900 Subject: [PATCH 09/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20yarn.lock,=20work?= =?UTF-8?q?flows=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20-=20dev,fe,be=20?= =?UTF-8?q?=EB=AA=A8=EB=91=90=20=EC=9E=91=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 4 +++ yarn.lock | 60 +++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7ac3d1bc..d46ea996 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,9 +4,13 @@ on: push: branches: - dev + - dev-fe + - dev-be pull_request: branches: - dev + - dev-fe + - dev-be jobs: build-and-deploy: diff --git a/yarn.lock b/yarn.lock index 8f096155..d3f72fe8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2222,6 +2222,15 @@ aws-ssl-profiles@^1.1.1: resolved "https://registry.yarnpkg.com/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz#157dd77e9f19b1d123678e93f120e6f193022641" integrity sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g== +axios@^1.7.7: + version "1.7.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -2319,6 +2328,11 @@ bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" +bluebird@~3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + body-parser@1.20.3: version "1.20.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" @@ -3120,15 +3134,17 @@ dotenv-expand@10.0.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== -dotenv@16.4.5, dotenv@^16.4.5: +dotenv@16.4.5, dotenv@^16.0.3, dotenv@^16.4.5: version "16.4.5" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== -dotenv@^16.0.3, dotenv@^16.4.5: - version "16.4.5" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" - integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +duplexer2@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA== + dependencies: + readable-stream "^2.0.2" eastasianwidth@^0.2.0: version "0.2.0" @@ -3916,6 +3932,11 @@ fn.name@1.x.x: resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -4001,6 +4022,15 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-monkey@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" @@ -4211,7 +4241,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -6190,6 +6220,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -6266,7 +6301,7 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -readable-stream@^2.2.2: +readable-stream@^2.0.2, readable-stream@^2.2.2: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -7387,6 +7422,17 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== +unzipper@^0.12.3: + version "0.12.3" + resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.12.3.tgz#31958f5eed7368ed8f57deae547e5a673e984f87" + integrity sha512-PZ8hTS+AqcGxsaQntl3IRBw65QrBI6lxzqDEL7IAo/XCEqRTKGfOX56Vea5TH9SZczRVxuzk1re04z/YjuYCJA== + dependencies: + bluebird "~3.7.2" + duplexer2 "~0.1.4" + fs-extra "^11.2.0" + graceful-fs "^4.2.2" + node-int64 "^0.4.0" + update-browserslist-db@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" From 51274295414b2d44d7a2ab82cd28c0b71bcd967a Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 15:20:03 +0900 Subject: [PATCH 10/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20type=20unzipper?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 1 + yarn.lock | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/packages/backend/package.json b/packages/backend/package.json index d3ca7219..11d04e86 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -54,6 +54,7 @@ "@types/node": "^20.3.1", "@types/passport-google-oauth20": "^2.0.16", "@types/supertest": "^6.0.0", + "@types/unzipper": "^0.10.10", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", "cz-emoji-conventional": "^1.1.0", diff --git a/yarn.lock b/yarn.lock index d3f72fe8..d66341fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1666,6 +1666,13 @@ resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== +"@types/unzipper@^0.10.10": + version "0.10.10" + resolved "https://registry.yarnpkg.com/@types/unzipper/-/unzipper-0.10.10.tgz#4407f7f633db0c5cf20f05257352cb8197fb9e5a" + integrity sha512-jKJdNxhmCHTZsaKW5x0qjn6rB+gHk0w5VFbEKsw84i+RJqXZyfTmGnpjDcKqzMpjz7VVLsUBMtO5T3mVidpt0g== + dependencies: + "@types/node" "*" + "@types/validator@^13.11.8": version "13.12.2" resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.12.2.tgz#760329e756e18a4aab82fc502b51ebdfebbe49f5" From 65051636ae8cb05512340e972aef29290d1f75ae Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 16:03:48 +0900 Subject: [PATCH 11/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20path=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20-=20build=20-\>=20dist,=20pack?= =?UTF-8?q?ages/fronted/dist=20=3D\>=20dist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/Dockerfile | 2 +- packages/frontend/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile index 64d3605c..41ae4118 100644 --- a/packages/backend/Dockerfile +++ b/packages/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine +FROM node:20-alpine WORKDIR /packages COPY . . RUN yarn install --frozen-lockfile diff --git a/packages/frontend/Dockerfile b/packages/frontend/Dockerfile index e7f9eb0c..c18a99c1 100644 --- a/packages/frontend/Dockerfile +++ b/packages/frontend/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS builder +FROM node:20-alpine AS builder WORKDIR /packages COPY . . RUN yarn install --frozen-lockfile @@ -6,6 +6,6 @@ RUN yarn workspace frontend build # Nginx 서버로 빌드된 파일 서빙 FROM nginx:alpine -COPY --from=builder /packages/frontend/build /usr/share/nginx/html +COPY --from=builder /packages/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] From 2a243c3eb7c62fcab173fbc9015c8c84d4f5ace2 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 16:25:45 +0900 Subject: [PATCH 12/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20server=20password?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d46ea996..6be4883e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -63,7 +63,7 @@ jobs: with: host: ${{ secrets.SERVER_HOST }} username: ${{ secrets.SERVER_USER }} - key: ${{ secrets.SERVER_SSH_KEY }} + password: ${{ secrets.SERVER_PASSWORD}} script: | docker pull ${{ secrets.DOCKER_USERNAME }}/frontend:latest docker pull ${{ secrets.DOCKER_USERNAME }}/backend:latest From 30029ec64501323d3456a874aa1b8406c1be63b7 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 19:19:37 +0900 Subject: [PATCH 13/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20tsconfig.buildjso?= =?UTF-8?q?n=20output=20dir=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/tsconfig.build.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/tsconfig.build.json b/packages/backend/tsconfig.build.json index c4fad51c..d0417b3a 100644 --- a/packages/backend/tsconfig.build.json +++ b/packages/backend/tsconfig.build.json @@ -5,6 +5,7 @@ "baseUrl": ".", "paths": { "@/*": ["src/*"] - } + }, + "outDir": "./dist" } } From b49fcb506815d7edc261e2d18586bb5dce47715f Mon Sep 17 00:00:00 2001 From: sunghwki Date: Mon, 11 Nov 2024 19:46:18 +0900 Subject: [PATCH 14/32] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20frontend=20?= =?UTF-8?q?dockerfile=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/Dockerfile b/packages/frontend/Dockerfile index c18a99c1..cbeb22e3 100644 --- a/packages/frontend/Dockerfile +++ b/packages/frontend/Dockerfile @@ -6,6 +6,6 @@ RUN yarn workspace frontend build # Nginx 서버로 빌드된 파일 서빙 FROM nginx:alpine -COPY --from=builder /packages/dist /usr/share/nginx/html +COPY --from=builder /packages/packages/frontend/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] From 17640c5580a3d5d9dea3815e6e8701dc59ddb60e Mon Sep 17 00:00:00 2001 From: kimminsu Date: Mon, 11 Nov 2024 14:51:40 +0900 Subject: [PATCH 15/32] =?UTF-8?q?=E2=9C=A8=20feat:=20=EA=B5=AC=EA=B8=80=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EA=B4=80=EB=A0=A8=20swagger=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/auth/googleAuth.controller.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/backend/src/auth/googleAuth.controller.ts b/packages/backend/src/auth/googleAuth.controller.ts index 15ba11d6..c9616b6e 100644 --- a/packages/backend/src/auth/googleAuth.controller.ts +++ b/packages/backend/src/auth/googleAuth.controller.ts @@ -1,8 +1,14 @@ import { Controller, Get, UseGuards } from '@nestjs/common'; import { GoogleAuthGuard } from '@/auth/guard/google.guard'; +import { ApiOperation, ApiTags } from '@nestjs/swagger'; +@ApiTags('Auth') @Controller('auth/google') export class GoogleAuthController { + @ApiOperation({ + summary: '구글 로그인 전용 페이지 이동', + description: '페이지를 이동하여 구글 로그인을 진행합니다.', + }) @Get('/login') @UseGuards(GoogleAuthGuard) async handleLogin() { From 08fecd920643d4b9a1259f99b25705ebb5b89ffc Mon Sep 17 00:00:00 2001 From: kimminsu Date: Mon, 11 Nov 2024 15:45:53 +0900 Subject: [PATCH 16/32] =?UTF-8?q?=E2=9C=A8=20feat:=20=EA=B5=AC=EA=B8=80=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=84=B1=EA=B3=B5=EC=8B=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/auth/googleAuth.controller.ts | 10 ++++++++-- packages/backend/src/auth/guard/google.guard.ts | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/auth/googleAuth.controller.ts b/packages/backend/src/auth/googleAuth.controller.ts index c9616b6e..eeb8fbbb 100644 --- a/packages/backend/src/auth/googleAuth.controller.ts +++ b/packages/backend/src/auth/googleAuth.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, UseGuards } from '@nestjs/common'; +import { Controller, Get, Req, UseGuards } from '@nestjs/common'; import { GoogleAuthGuard } from '@/auth/guard/google.guard'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; @@ -13,7 +13,13 @@ export class GoogleAuthController { @UseGuards(GoogleAuthGuard) async handleLogin() { return { - msg: 'Google Authentication', + message: 'Google Authentication', }; } + + @Get('/redirect') + @UseGuards(GoogleAuthGuard) + async handleRedirect(@Req() request: any) { + return request.user; + } } diff --git a/packages/backend/src/auth/guard/google.guard.ts b/packages/backend/src/auth/guard/google.guard.ts index 0f9f7ba8..bfb85f36 100644 --- a/packages/backend/src/auth/guard/google.guard.ts +++ b/packages/backend/src/auth/guard/google.guard.ts @@ -7,9 +7,9 @@ export class GoogleAuthGuard extends AuthGuard('google') { super(); } async canActivate(context: ExecutionContext) { - const activate = (await super.canActivate(context)) as boolean; + const isActivate = (await super.canActivate(context)) as boolean; const request = context.switchToHttp().getRequest(); await super.logIn(request); - return activate; + return isActivate; } } \ No newline at end of file From 533abb761b35b7d30477232ded5aa9e83e7f3b6a Mon Sep 17 00:00:00 2001 From: kimminsu Date: Mon, 11 Nov 2024 15:48:38 +0900 Subject: [PATCH 17/32] =?UTF-8?q?=E2=9C=A8=20feat:=20=EA=B5=AC=EA=B8=80=20?= =?UTF-8?q?oauth=20=EC=84=9C=EB=B2=84=EB=A1=9C=EB=B6=80=ED=84=B0=20access?= =?UTF-8?q?=20token=20=ED=9A=8D=EB=93=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/auth/google.strategy.ts | 25 +++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/auth/google.strategy.ts b/packages/backend/src/auth/google.strategy.ts index 288d9d55..9a69a723 100644 --- a/packages/backend/src/auth/google.strategy.ts +++ b/packages/backend/src/auth/google.strategy.ts @@ -1,8 +1,10 @@ +import { Inject } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; -import { Strategy } from 'passport-google-oauth20'; +import { Profile, Strategy, VerifyCallback } from 'passport-google-oauth20'; +import { Logger } from 'winston'; export class GoogleStrategy extends PassportStrategy(Strategy) { - constructor() { + constructor(@Inject('winston') private readonly logger: Logger) { super({ clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, @@ -10,4 +12,21 @@ export class GoogleStrategy extends PassportStrategy(Strategy) { scope: ['email', 'profile'], }); } -} \ No newline at end of file + + authorizationParams(): { [key: string]: string } { + return { + access_type: 'offline', + prompt: 'select_account', + }; + } + + async validate( + accessToken: string, + refreshToken: string, + profile: Profile, + done: VerifyCallback, + ) { + this.logger.info(`accessToken: ${accessToken.slice(0, 10)}...`); + done(null, false); + } +} From 2bcb26b0259d3abbde3f0a4b0ecd00f9332808c5 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Mon, 11 Nov 2024 16:31:48 +0900 Subject: [PATCH 18/32] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20request?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/auth/googleAuth.controller.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/auth/googleAuth.controller.ts b/packages/backend/src/auth/googleAuth.controller.ts index eeb8fbbb..40b841ff 100644 --- a/packages/backend/src/auth/googleAuth.controller.ts +++ b/packages/backend/src/auth/googleAuth.controller.ts @@ -1,6 +1,7 @@ import { Controller, Get, Req, UseGuards } from '@nestjs/common'; -import { GoogleAuthGuard } from '@/auth/guard/google.guard'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { Request } from 'express'; +import { GoogleAuthGuard } from '@/auth/guard/google.guard'; @ApiTags('Auth') @Controller('auth/google') @@ -19,7 +20,7 @@ export class GoogleAuthController { @Get('/redirect') @UseGuards(GoogleAuthGuard) - async handleRedirect(@Req() request: any) { + async handleRedirect(@Req() request: Request) { return request.user; } } From 7e45b225bca84ad279a79dead1e40d14c2089bed Mon Sep 17 00:00:00 2001 From: kimminsu Date: Mon, 11 Nov 2024 16:37:09 +0900 Subject: [PATCH 19/32] =?UTF-8?q?=E2=9C=A8=20feat:=20=EA=B5=AC=EA=B8=80=20?= =?UTF-8?q?oauth=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=84=B1=EA=B3=B5=20?= =?UTF-8?q?=ED=9B=84=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EB=A5=BC=20=ED=9A=8D=EB=93=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/auth/google.strategy.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/auth/google.strategy.ts b/packages/backend/src/auth/google.strategy.ts index 9a69a723..4eb9c648 100644 --- a/packages/backend/src/auth/google.strategy.ts +++ b/packages/backend/src/auth/google.strategy.ts @@ -1,4 +1,4 @@ -import { Inject } from '@nestjs/common'; +import { Inject, UnauthorizedException } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Profile, Strategy, VerifyCallback } from 'passport-google-oauth20'; import { Logger } from 'winston'; @@ -26,7 +26,22 @@ export class GoogleStrategy extends PassportStrategy(Strategy) { profile: Profile, done: VerifyCallback, ) { - this.logger.info(`accessToken: ${accessToken.slice(0, 10)}...`); + const { id, emails, name, provider } = profile; + if (!emails) { + done(new UnauthorizedException('email is required'), false); + return; + } + if (!name) { + done(new UnauthorizedException('name is required'), false); + return; + } + const userInfo = { + type: provider, + oauthId: id, + emails: emails[0].value, + nickname: `${name.givenName} ${name.familyName}`, + }; + this.logger.info(`google user info: ${JSON.stringify(userInfo)}`); done(null, false); } } From 6c544390f788bb4ff7fb58acc1241949ddb0ec28 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 14:37:38 +0900 Subject: [PATCH 20/32] =?UTF-8?q?=E2=9C=A8=20feat(module=20openapi-scrappe?= =?UTF-8?q?r=20=EC=B6=94=EA=B0=80):=20module=EB=A1=9C=20=EA=B0=9C=EB=B0=9C?= =?UTF-8?q?=20=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 8 +++----- .../src/openapi-scraper/openapi-scraper.controller.ts | 4 ++++ packages/backend/src/openapi-scraper/openapi-scraper.ts | 4 ++++ 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.controller.ts create mode 100644 packages/backend/src/openapi-scraper/openapi-scraper.ts diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 946aaa8b..297ede1d 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -10,13 +10,11 @@ import { UserModule } from '@/user/user.module'; import { AuthModule } from '@/auth/auth.module'; @Module({ - imports: [ - TypeOrmModule.forRoot(typeormConfig), - WinstonModule.forRoot(logger), + imports: [OpenapiScraperModule, StockModule, UserModule, - OpenapiScraperModule, - StockPriceModule, + TypeOrmModule.forRoot(typeormConfig), + WinstonModule.forRoot(logger), AuthModule, ], controllers: [], diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts b/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts new file mode 100644 index 00000000..56e60188 --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('openapi-scraper') +export class OpenapiScraperController {} diff --git a/packages/backend/src/openapi-scraper/openapi-scraper.ts b/packages/backend/src/openapi-scraper/openapi-scraper.ts new file mode 100644 index 00000000..621c0988 --- /dev/null +++ b/packages/backend/src/openapi-scraper/openapi-scraper.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class OpenapiScraper {} From ab25b1b14cd6b9d456acc736e57aad4b7741f1e4 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 6 Nov 2024 18:06:00 +0900 Subject: [PATCH 21/32] =?UTF-8?q?=E2=9C=A8=20feat:=20backend/stock-price?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 1 + packages/backend/src/app.module.ts | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 11d04e86..4045079c 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -37,6 +37,7 @@ "nest-winston": "^1.9.7", "passport": "^0.7.0", "passport-google-oauth20": "^2.0.0", + "dotenv": "^16.4.5", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", "socket.io": "^4.8.1", diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 297ede1d..8c050c5e 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -1,16 +1,16 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { WinstonModule } from 'nest-winston'; -import { StockPriceModule } from './stock-price/stock-price.module'; -import { OpenapiScraperModule } from './openapi-scraper/openapi-scraper.module'; import { logger } from '@/configs/logger.config'; import { typeormConfig } from '@/configs/typeorm.config'; import { StockModule } from '@/stock/stock.module'; import { UserModule } from '@/user/user.module'; import { AuthModule } from '@/auth/auth.module'; +import { OpenapiScraperModule } from '@/openapi-scraper/openapi-scraper.module'; +import { StockPriceModule } from '@/stock-price/stock-price.module'; @Module({ - imports: [OpenapiScraperModule, + imports: [OpenapiScraperModule, StockPriceModule, StockModule, UserModule, TypeOrmModule.forRoot(typeormConfig), From 4eec90d6f330f0fa5f304a383c0075765b597dd2 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Thu, 7 Nov 2024 14:43:20 +0900 Subject: [PATCH 22/32] =?UTF-8?q?=E2=9C=A8=20feat(korea-stock-info.*.ts):?= =?UTF-8?q?=20=ED=95=9C=EA=B5=AD=20=EC=A3=BC=EC=8B=9D=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EB=A5=BC=20=ED=8C=8C=EC=8B=B1=ED=95=98=EA=B3=A0,=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20=EA=B2=83=EC=9D=84=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 8c050c5e..f0c4fc66 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -10,7 +10,9 @@ import { OpenapiScraperModule } from '@/openapi-scraper/openapi-scraper.module'; import { StockPriceModule } from '@/stock-price/stock-price.module'; @Module({ - imports: [OpenapiScraperModule, StockPriceModule, + imports: [ + OpenapiScraperModule, + StockPriceModule, StockModule, UserModule, TypeOrmModule.forRoot(typeormConfig), From b97d82f154b85d4edae13c84f7f5985fb2acf85f Mon Sep 17 00:00:00 2001 From: sunghwki Date: Tue, 12 Nov 2024 11:45:31 +0900 Subject: [PATCH 23/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EB=A6=AC=EB=B7=B0?= =?UTF-8?q?=20=EB=B0=98=EC=98=81=20-=20=20env,=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0,=20.vscode=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20/=20dto=20=EC=82=AC=EC=9A=A9=20=ED=99=95=EB=8C=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- .vscode/settings.json | 6 -- .../korea-stock-info/dto/download.dto.ts | 3 - .../dto/master-download.dto.ts | 14 +++ .../korea-stock-info/dto/master-split.dto.ts | 32 ++++++ .../korea-stock-info/entities/stock.entity.ts | 3 +- .../korea-stock-info.service.ts | 97 +++++++++---------- 7 files changed, 100 insertions(+), 60 deletions(-) delete mode 100644 .vscode/settings.json delete mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/dto/master-download.dto.ts create mode 100644 packages/backend/src/openapi-scraper/korea-stock-info/dto/master-split.dto.ts diff --git a/.gitignore b/.gitignore index e3881704..66b03b45 100644 --- a/.gitignore +++ b/.gitignore @@ -53,4 +53,7 @@ pids *.pid.lock # Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json \ No newline at end of file +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# vscode setting +.vscode diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 0997a4dd..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prettier.prettierPath": "./node_modules/prettier", - "prettier.configPath": "./.prettierrc", - "prettier.embeddedLanguageFormatting": "auto", - "editor.defaultFormatter": "esbenp.prettier-vscode" -} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts b/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts deleted file mode 100644 index c4c886b8..00000000 --- a/packages/backend/src/openapi-scraper/korea-stock-info/dto/download.dto.ts +++ /dev/null @@ -1,3 +0,0 @@ -export class DownloadDto { - baseDir!: string; -} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/dto/master-download.dto.ts b/packages/backend/src/openapi-scraper/korea-stock-info/dto/master-download.dto.ts new file mode 100644 index 00000000..d21c9a80 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/dto/master-download.dto.ts @@ -0,0 +1,14 @@ +import { IsString } from "class-validator"; + +export class MasterDownloadDto { + @IsString() + baseDir!: string; + + @IsString() + target: string; + + constructor(baseDir: string, target: string) { + this.baseDir = baseDir; + this.target = target; + } +} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/dto/master-split.dto.ts b/packages/backend/src/openapi-scraper/korea-stock-info/dto/master-split.dto.ts new file mode 100644 index 00000000..d58a1147 --- /dev/null +++ b/packages/backend/src/openapi-scraper/korea-stock-info/dto/master-split.dto.ts @@ -0,0 +1,32 @@ +import { IsArray } from 'class-validator'; + +export class MasterSplit { + @IsArray() + shortCode: [number, number]; + + @IsArray() + standardCode: [number, number]; + + @IsArray() + koreanName: [number, number]; + + @IsArray() + groupCode: [number, number]; + + @IsArray() + marketCapSize: [number, number]; + + constructor( + shortCode: [number, number], + standardCode: [number, number], + koreanName: [number, number], + groupCode: [number, number], + marketCapSize: [number, number], + ) { + this.shortCode = shortCode; + this.standardCode = standardCode; + this.koreanName = koreanName; + this.groupCode = groupCode; + this.marketCapSize = marketCapSize; + } +} diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts b/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts index 4c52f1c6..ad721147 100644 --- a/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts +++ b/packages/backend/src/openapi-scraper/korea-stock-info/entities/stock.entity.ts @@ -1,7 +1,8 @@ import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; +//TODO : entity update require @Entity() -export class KospiMaster { +export class Master { @PrimaryGeneratedColumn({ type: 'int', unsigned: true }) id?: number; diff --git a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts index 87de51d9..dd9aad35 100644 --- a/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts +++ b/packages/backend/src/openapi-scraper/korea-stock-info/korea-stock-info.service.ts @@ -5,17 +5,20 @@ import * as https from 'https'; import * as readline from 'readline'; import * as iconv from 'iconv-lite'; import * as unzipper from 'unzipper'; -import { DownloadDto } from './dto/download.dto'; -import { KospiMaster } from './entities/stock.entity'; +import { MasterDownloadDto } from './dto/master-download.dto'; +import { Master } from './entities/stock.entity'; +import { config as dotenvConfig } from 'dotenv'; + +dotenvConfig(); @Injectable() export class KoreaStockInfoService { constructor() { - this.downloadKosdaqMaster({ baseDir: './' }); - this.downloadKospiMaster({ baseDir: './' }); + this.downloadMaster({ baseDir: './', target: 'kosdaq_code' }); + this.downloadMaster({ baseDir: './', target: 'kosdaq_code' }); - this.getKospiMasterData('./'); - this.getKosdaqMasterData('./'); + this.getKospiMasterData({ baseDir: './', target: 'kosdaq_code' }); + this.getKosdaqMasterData({ baseDir: './', target: 'kosdaq_code' }); } private async downloadFile(url: string, filePath: string): Promise { @@ -43,36 +46,24 @@ export class KoreaStockInfoService { .promise(); } - public async downloadKosdaqMaster(downloadDto: DownloadDto): Promise { - const { baseDir } = downloadDto; - const fileName = 'kosdaq_code.zip'; - const filePath = path.join(baseDir, fileName); - const extractedFile = path.join(baseDir, 'kosdaq_code.mst'); - - await this.downloadFile( - 'https://new.real.download.dws.co.kr/common/master/kosdaq_code.mst.zip', - filePath, - ); - await this.extractZip(filePath, baseDir); - - fs.unlink(filePath, (err) => { - if (err) throw err; - }); - - return extractedFile; + private getValueFromMst(row: string, start: number, end: number) { + return row.slice(start, end).trim(); } - public async downloadKospiMaster(downloadDto: DownloadDto): Promise { - const { baseDir } = downloadDto; - const fileName = 'kospi_code.zip'; + public async downloadMaster(downloadDto: MasterDownloadDto): Promise { + const { baseDir, target } = downloadDto; + const fileName = target + '.zip'; + const targetFileName = target + '.mst'; + const url = + process.env.MST_URL + + target + + '.mst.zip'; const filePath = path.join(baseDir, fileName); - const extractedFile = path.join(baseDir, 'kospi_code.mst'); + const extractedFile = path.join(baseDir, targetFileName); - await this.downloadFile( - 'https://new.real.download.dws.co.kr/common/master/kospi_code.mst.zip', - filePath, - ); + await this.downloadFile(url, filePath); await this.extractZip(filePath, baseDir); + fs.unlink(filePath, (err) => { if (err) throw err; }); @@ -80,21 +71,25 @@ export class KoreaStockInfoService { return extractedFile; } - public async getKospiMasterData(baseDir: string): Promise { - const fileName = path.join(baseDir, 'kospi_code.mst'); - const kospiMasters: KospiMaster[] = []; + public async getKospiMasterData( + downloadDto: MasterDownloadDto, + ): Promise { + const targetFileName = downloadDto.target + '.mst'; + const fileName = path.join(downloadDto.baseDir, targetFileName); + const encoding = 'cp949'; + const kospiMasters: Master[] = []; const rl = readline.createInterface({ - input: fs.createReadStream(fileName).pipe(iconv.decodeStream('cp949')), + input: fs.createReadStream(fileName).pipe(iconv.decodeStream(encoding)), crlfDelay: Infinity, }); for await (const row of rl) { - const shortCode = row.slice(0, 9).trim(); - const standardCode = row.slice(9, 21).trim(); - const koreanName = row.slice(21, row.length - 228).trim(); - const groupCode = row.slice(-228, -226).trim(); - const marketCapSize = row.slice(-226, -225).trim(); + const shortCode = this.getValueFromMst(row, 0, 9); + const standardCode = this.getValueFromMst(row, 9, 21); + const koreanName = this.getValueFromMst(row, 21, row.length - 228); + const groupCode = this.getValueFromMst(row, row.length - 228, row.length - 226); + const marketCapSize = this.getValueFromMst(row, row.length - 226, row.length - 225); kospiMasters.push({ shortCode, @@ -109,21 +104,25 @@ export class KoreaStockInfoService { return kospiMasters; } - public async getKosdaqMasterData(baseDir: string): Promise { - const fileName = path.join(baseDir, 'kosdaq_code.mst'); - const kosdaqMasters: KospiMaster[] = []; + public async getKosdaqMasterData( + downloadDto: MasterDownloadDto, + ): Promise { + const targetFileName = downloadDto.target + '.mst'; + const fileName = path.join(downloadDto.baseDir, targetFileName); + const encoding = 'cp949'; + const kosdaqMasters: Master[] = []; const rl = readline.createInterface({ - input: fs.createReadStream(fileName).pipe(iconv.decodeStream('cp949')), + input: fs.createReadStream(fileName).pipe(iconv.decodeStream(encoding)), crlfDelay: Infinity, }); for await (const row of rl) { - const shortCode = row.slice(0, 9).trim(); - const standardCode = row.slice(9, 21).trim(); - const koreanName = row.slice(21, row.length - 222).trim(); - const groupCode = row.slice(-222, -220).trim(); - const marketCapSize = row.slice(-220, -219).trim(); + const shortCode = this.getValueFromMst(row, 0, 9); + const standardCode = this.getValueFromMst(row, 9, 21); + const koreanName = this.getValueFromMst(row, 21, row.length - 222); + const groupCode = this.getValueFromMst(row, row.length - 222, row.length - 220); + const marketCapSize = this.getValueFromMst(row, row.length - 220, row.length - 219); kosdaqMasters.push({ shortCode, From e1a4689aa23f2fd8b9f0a6da9c8094880da20e26 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Tue, 12 Nov 2024 18:43:48 +0900 Subject: [PATCH 24/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20backend=20package?= =?UTF-8?q?=20prod=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 5b57dbb2..15cc0219 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -11,7 +11,7 @@ "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", - "start:prod": "node dist/main", + "start:prod": "node ../../dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", From 8b0e87df9eba84b773fee9f476d0b9aeeb71ccb7 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Tue, 12 Nov 2024 18:45:53 +0900 Subject: [PATCH 25/32] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20package.jso?= =?UTF-8?q?n=20=EC=88=98=EC=A0=95=20-=20..=EC=A2=8B=EC=9D=80=20=EB=B0=A9?= =?UTF-8?q?=EB=B2=95=EC=9D=80=20=EC=95=84=EB=8B=88=EC=A7=80=EB=A7=8C..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 4045079c..c53f3ad7 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -11,7 +11,7 @@ "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", - "start:prod": "node dist/main", + "start:prod": "node ../../dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", From 8cd4e6979ef497c03ade4ab3fdb180bc8847068c Mon Sep 17 00:00:00 2001 From: sunghwki Date: Tue, 12 Nov 2024 18:47:08 +0900 Subject: [PATCH 26/32] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20packages.js?= =?UTF-8?q?on=20=EC=A4=91=EB=B3=B5=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index c53f3ad7..b688d4d4 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -37,7 +37,6 @@ "nest-winston": "^1.9.7", "passport": "^0.7.0", "passport-google-oauth20": "^2.0.0", - "dotenv": "^16.4.5", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", "socket.io": "^4.8.1", From de9da7bfa90b19fb96412edfaaf38a27a324128e Mon Sep 17 00:00:00 2001 From: sunghwki Date: Tue, 12 Nov 2024 21:06:14 +0900 Subject: [PATCH 27/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=B6=A9=EB=8F=8C?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9C=EC=83=9D=ED=95=9C=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 2 +- packages/backend/src/auth/google.strategy.ts | 5 +++-- packages/backend/tsconfig.build.json | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index f0c4fc66..8b2f9153 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -11,7 +11,7 @@ import { StockPriceModule } from '@/stock-price/stock-price.module'; @Module({ imports: [ - OpenapiScraperModule, + //OpenapiScraperModule, StockPriceModule, StockModule, UserModule, diff --git a/packages/backend/src/auth/google.strategy.ts b/packages/backend/src/auth/google.strategy.ts index afd13cb8..f936a2cc 100644 --- a/packages/backend/src/auth/google.strategy.ts +++ b/packages/backend/src/auth/google.strategy.ts @@ -1,8 +1,9 @@ -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Profile, Strategy, VerifyCallback } from 'passport-google-oauth20'; import { GoogleAuthService } from '@/auth/googleAuth.service'; import { OauthType } from '@/user/domain/ouathType'; +import { Logger } from 'winston'; export interface OauthUserInfo { type: OauthType; @@ -14,7 +15,7 @@ export interface OauthUserInfo { @Injectable() export class GoogleStrategy extends PassportStrategy(Strategy) { - constructor(private readonly googleAuthService: GoogleAuthService@Inject('winston') private readonly logger: Logger) { + constructor(private readonly googleAuthService: GoogleAuthService, @Inject('winston') private readonly logger: Logger) { super({ clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, diff --git a/packages/backend/tsconfig.build.json b/packages/backend/tsconfig.build.json index d0417b3a..8aea2aaa 100644 --- a/packages/backend/tsconfig.build.json +++ b/packages/backend/tsconfig.build.json @@ -6,6 +6,5 @@ "paths": { "@/*": ["src/*"] }, - "outDir": "./dist" } } From 32d2f47ff90b6c4b42760d01a15ae9198745ab82 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Tue, 12 Nov 2024 22:51:37 +0900 Subject: [PATCH 28/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20deploy.yml=20back?= =?UTF-8?q?end=20=EB=B6=80=ED=84=B0=20=EB=A7=8C=EB=93=A4=EA=B2=8C=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6be4883e..6b3b86df 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -48,16 +48,16 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build and push frontend Docker image - run: | - docker build -t ${{ secrets.DOCKER_USERNAME }}/frontend:latest -f packages/frontend/Dockerfile . - docker push ${{ secrets.DOCKER_USERNAME }}/frontend:latest - - name: Build and push backend Docker image run: | docker build -t ${{ secrets.DOCKER_USERNAME }}/backend:latest -f packages/backend/Dockerfile . docker push ${{ secrets.DOCKER_USERNAME }}/backend:latest + - name: Build and push frontend Docker image + run: | + docker build -t ${{ secrets.DOCKER_USERNAME }}/frontend:latest -f packages/frontend/Dockerfile . + docker push ${{ secrets.DOCKER_USERNAME }}/frontend:latest + - name: Deploy to server uses: appleboy/ssh-action@v1.1.0 with: From 70d65d1da237b016bf805afdb75560ba29e4c7f6 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Tue, 12 Nov 2024 23:13:15 +0900 Subject: [PATCH 29/32] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20deploy=20docker-d?= =?UTF-8?q?own=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6b3b86df..77b2a3a2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -67,4 +67,5 @@ jobs: script: | docker pull ${{ secrets.DOCKER_USERNAME }}/frontend:latest docker pull ${{ secrets.DOCKER_USERNAME }}/backend:latest + docker-compose down docker-compose up -d From 2f0832511d23800e0b6551dbfb446c06df3ed195 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 13 Nov 2024 10:50:08 +0900 Subject: [PATCH 30/32] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20=ED=8E=B8-?= =?UTF-8?q?=EC=95=88=ED=95=98=EA=B2=8C=20ssh=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?,=20pull=20request=20=EC=9E=91=EB=8F=99=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 77b2a3a2..e695905e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -6,11 +6,6 @@ on: - dev - dev-fe - dev-be - pull_request: - branches: - - dev - - dev-fe - - dev-be jobs: build-and-deploy: @@ -63,7 +58,8 @@ jobs: with: host: ${{ secrets.SERVER_HOST }} username: ${{ secrets.SERVER_USER }} - password: ${{ secrets.SERVER_PASSWORD}} + key: ${{ secrets.SERVER_SSH_KEY}} + port: ${{ secrets.SERVER_PORT }} script: | docker pull ${{ secrets.DOCKER_USERNAME }}/frontend:latest docker pull ${{ secrets.DOCKER_USERNAME }}/backend:latest From 16e97874c84994986d612c9c78309326b31c9dfc Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 13 Nov 2024 11:27:19 +0900 Subject: [PATCH 31/32] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20front,=20ba?= =?UTF-8?q?ckend=20action=20=EB=8B=A4=EB=A5=B4=EA=B2=8C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-backend.yml | 65 +++++++++++++++++++ .../{deploy.yml => deploy-frontend.yml} | 22 +++---- 2 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/deploy-backend.yml rename .github/workflows/{deploy.yml => deploy-frontend.yml} (77%) diff --git a/.github/workflows/deploy-backend.yml b/.github/workflows/deploy-backend.yml new file mode 100644 index 00000000..e12e3954 --- /dev/null +++ b/.github/workflows/deploy-backend.yml @@ -0,0 +1,65 @@ +name: Deploy Monorepo + +on: + push: + branches: + - dev-be + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + services: + docker: + image: docker:20.10.7 + options: --privileged + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache Yarn dependencies + uses: actions/cache@v3 + with: + path: | + **/node_modules + ~/.yarn-cache + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Build backend + run: | + yarn workspace backend build + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push backend Docker image + run: | + docker build -t ${{ secrets.DOCKER_USERNAME }}/backend:latest -f packages/backend/Dockerfile . + docker push ${{ secrets.DOCKER_USERNAME }}/backend:latest + + - name: Deploy to server + uses: appleboy/ssh-action@v1.1.0 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + key: ${{ secrets.SERVER_SSH_KEY}} + port: ${{ secrets.SERVER_PORT }} + script: | + docker pull ${{ secrets.DOCKER_USERNAME }}/backend:latest + docker-compose down + docker-compose up -d diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy-frontend.yml similarity index 77% rename from .github/workflows/deploy.yml rename to .github/workflows/deploy-frontend.yml index e695905e..97d60f7d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy-frontend.yml @@ -3,9 +3,7 @@ name: Deploy Monorepo on: push: branches: - - dev - dev-fe - - dev-be jobs: build-and-deploy: @@ -20,6 +18,16 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Cache Yarn dependencies + uses: actions/cache@v3 + with: + path: | + **/node_modules + ~/.yarn-cache + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Set up Node.js uses: actions/setup-node@v4 with: @@ -33,10 +41,6 @@ jobs: run: | yarn workspace frontend build - - name: Build backend - run: | - yarn workspace backend build - - name: Log in to Docker Hub uses: docker/login-action@v3 with: @@ -48,11 +52,6 @@ jobs: docker build -t ${{ secrets.DOCKER_USERNAME }}/backend:latest -f packages/backend/Dockerfile . docker push ${{ secrets.DOCKER_USERNAME }}/backend:latest - - name: Build and push frontend Docker image - run: | - docker build -t ${{ secrets.DOCKER_USERNAME }}/frontend:latest -f packages/frontend/Dockerfile . - docker push ${{ secrets.DOCKER_USERNAME }}/frontend:latest - - name: Deploy to server uses: appleboy/ssh-action@v1.1.0 with: @@ -62,6 +61,5 @@ jobs: port: ${{ secrets.SERVER_PORT }} script: | docker pull ${{ secrets.DOCKER_USERNAME }}/frontend:latest - docker pull ${{ secrets.DOCKER_USERNAME }}/backend:latest docker-compose down docker-compose up -d From ac5fa437f0835b28975065f79aecfba8fbe2f6d2 Mon Sep 17 00:00:00 2001 From: sunghwki Date: Wed, 13 Nov 2024 11:28:27 +0900 Subject: [PATCH 32/32] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-backend.yml | 2 +- .github/workflows/deploy-frontend.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-backend.yml b/.github/workflows/deploy-backend.yml index e12e3954..fee8078e 100644 --- a/.github/workflows/deploy-backend.yml +++ b/.github/workflows/deploy-backend.yml @@ -1,4 +1,4 @@ -name: Deploy Monorepo +name: Deploy Backend in Monorepo on: push: diff --git a/.github/workflows/deploy-frontend.yml b/.github/workflows/deploy-frontend.yml index 97d60f7d..79cd98e2 100644 --- a/.github/workflows/deploy-frontend.yml +++ b/.github/workflows/deploy-frontend.yml @@ -1,4 +1,4 @@ -name: Deploy Monorepo +name: Deploy Frontend in Monorepo on: push: