diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..7facb817 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,30 @@ +name: 공식 문서 배포 + +on: + push: + branches: + - develop +permissions: + contents: write +defaults: + run: + working-directory: docs + +jobs: + docs: + name: Deploy Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: 3.9.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + clear-keys: | + mkdocs-material- + - run: pip install mkdocs-material + - run: mkdocs gh-deploy --force diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e0dab728..68a3c6fd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,9 +40,10 @@ jobs: working-directory: backend run: pnpm install - - name: build backend - working-directory: backend - run: pnpm build + # TODO(@scarf005): #594 + # - name: build backend + # working-directory: backend + # run: pnpm build - name: create .env file run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..55774f95 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,36 @@ +name: Test + +on: + pull_request: + +jobs: + test: + name: Test PR + runs-on: ubuntu-latest + environment: development + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: setup node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + + - name: setup pnpm + run: | + corepack enable + corepack prepare pnpm@latest-8 --activate + pnpm config set store-dir .pnpm-store + + - name: install dependencies + working-directory: backend + run: pnpm install + + # TODO(@scarf005): #594 + # - name: build backend + # working-directory: backend + # run: pnpm build + + # TODO: 테스트 실행 diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7f..189f4c80 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,5 +1,12 @@ + + + diff --git a/README.md b/README.md index dd7dd85d..dfe27c03 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ # 💻 기술 스택 ![typescript](https://img.shields.io/badge/TypeScript-^4.5.5-3178C6?logo=TypeScript) ![Express](https://img.shields.io/badge/Express-^4.17.2-000000?logo=Express) ![jest](https://img.shields.io/badge/Jest-^27.5.1-C21325?logo=Jest) ![.ENV](https://img.shields.io/badge/.ENV-^2.3.3-ECD53F?logo=.ENV) ![MySQL2](https://img.shields.io/badge/MySQL2-^2.3.3-4479A1?logo=MySQL) ![docker-compose](https://img.shields.io/badge/docker--compose-v2-2496ED?logo=Docker) ![swagger](https://img.shields.io/badge/swagger-3.x-85EA2D?logo=swagger) -# 🗒 ERD (Updated at 2022.10.26) +# 🗄️ERD (Updated at 2022.10.26) ![erd_backend](https://user-images.githubusercontent.com/50291995/198007446-0259fd24-1b8a-4d40-a2b8-cb8cce2bddc2.png) # 💡 기능 관련 건의 diff --git a/backend/.eslintrc.json b/backend/.eslintrc.json index 8a283079..8051b279 100644 --- a/backend/.eslintrc.json +++ b/backend/.eslintrc.json @@ -7,28 +7,26 @@ "root": true, "extends": ["airbnb-base", "plugin:@typescript-eslint/recommended"], "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], + "plugins": ["@typescript-eslint", "import"], "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "rules": { - "import/extensions": [ - "error", - "ignorePackages", - { - "js": "never", - "ts": "never", - "json": "never" - } - ], + "import/extensions": "off", "linebreak-style": "off", "no-use-before-define": "off", "@typescript-eslint/no-use-before-define": "error" }, "settings": { + "import/parsers": { + "@typescript-eslint/parser": [".ts", ".tsx"] + }, "import/resolver": { - "node": { "extensions": [".js", ".jsx", ".ts", ".tsx"] } + "node": { "extensions": [".js", ".jsx", ".ts", ".tsx"] }, + "typescript": { + "project": "./tsconfig.json" + } } } } diff --git a/backend/Dockerfile b/backend/Dockerfile index c5b27131..a9763416 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -7,7 +7,10 @@ RUN npm install --global pnpm COPY . . RUN pnpm install -RUN pnpm install --global pm2 -RUN pm2-runtime --version || exit 1 +ENTRYPOINT [ "pnpm", "prod" ] -ENTRYPOINT [ "sh", "start.sh"] +# RUN pnpm install --global pm2 +# RUN pm2-runtime --version || exit 1 + +# TODO(@scarf005): #594 +# ENTRYPOINT [ "sh", "start.sh"] diff --git a/backend/jest.config.js b/backend/jest.config.js index e86e13ba..38a1e837 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -1,5 +1,10 @@ -/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ +/** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { preset: 'ts-jest', testEnvironment: 'node', + transform: { + '^.+\\.[tj]sx?$': ['ts-jest', { + tsconfig: './tsconfig.json', + }], + }, }; diff --git a/backend/package.json b/backend/package.json index 612b5250..eb8313e6 100644 --- a/backend/package.json +++ b/backend/package.json @@ -10,10 +10,10 @@ "node": ">=20.3.1 || >=18.16.1 <20.0.0" }, "scripts": { - "start": "node dist/server.js", - "build": "npx tsc -p ./tsconfig.prod.json", - "dev": "nodemon --watch \"src/**/*.ts\" --exec \"ts-node\" src/server.ts", - "prod": "npx tsc -p ./tsconfig.prod.json && npm start", + "start": "ts-node -r tsconfig-paths/register --project ./tsconfig.prod.json src/server.ts", + "build": "echo '번들러 사용중이지 않아 빌드시 tsconfig paths 적용이 불가합니다' && exit 1", + "dev": "nodemon --watch \"src/**/*.ts\" --exec ts-node -r tsconfig-paths/register src/server.ts", + "prod": "pnpm start", "lint": "eslint --fix --ext .js,.ts src", "test": "jest" }, @@ -36,6 +36,7 @@ "@typescript-eslint/parser": "^5.60.0", "eslint": "^8.43.0", "eslint-config-airbnb-base": "^15.0.0", + "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-import": "^2.27.5", "jest": "^29.5.0", "nodemon": "^2.0.22", diff --git a/backend/pnpm-lock.yaml b/backend/pnpm-lock.yaml index d1a4c381..36a83492 100644 --- a/backend/pnpm-lock.yaml +++ b/backend/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: true @@ -157,9 +157,12 @@ devDependencies: eslint-config-airbnb-base: specifier: ^15.0.0 version: 15.0.0(eslint-plugin-import@2.27.5)(eslint@8.43.0) + eslint-import-resolver-typescript: + specifier: ^3.5.5 + version: 3.5.5(eslint-plugin-import@2.27.5)(eslint@8.43.0) eslint-plugin-import: specifier: ^2.27.5 - version: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint@8.43.0) + version: 2.27.5(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0) jest: specifier: ^29.5.0 version: 29.5.0(@types/node@18.16.1)(ts-node@10.9.1) @@ -985,6 +988,18 @@ packages: uuid: 3.4.0 dev: false + /@pkgr/utils@2.4.2: + resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + dependencies: + cross-spawn: 7.0.3 + fast-glob: 3.3.0 + is-glob: 4.0.3 + open: 9.1.0 + picocolors: 1.0.0 + tslib: 2.6.0 + dev: true + /@pm2/agent@2.0.1: resolution: {integrity: sha512-QKHMm6yexcvdDfcNE7PL9D6uEjoQPGRi+8dh+rc4Hwtbpsbh5IAvZbz3BVGjcd4HaX6pt2xGpOohG7/Y2L4QLw==} dependencies: @@ -1875,6 +1890,11 @@ packages: - supports-color dev: false + /big-integer@1.6.51: + resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} + engines: {node: '>=0.6'} + dev: true + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -1917,6 +1937,13 @@ packages: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} dev: false + /bplist-parser@0.2.0: + resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} + engines: {node: '>= 5.10.0'} + dependencies: + big-integer: 1.6.51 + dev: true + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -1970,6 +1997,13 @@ packages: ieee754: 1.2.1 dev: false + /bundle-name@3.0.0: + resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} + engines: {node: '>=12'} + dependencies: + run-applescript: 5.0.0 + dev: true + /bytes@3.1.1: resolution: {integrity: sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==} engines: {node: '>= 0.8'} @@ -2380,6 +2414,17 @@ packages: ms: 2.0.0 dev: false + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + /debug@3.2.7(supports-color@5.5.0): resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -2412,6 +2457,29 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + /default-browser-id@3.0.0: + resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} + engines: {node: '>=12'} + dependencies: + bplist-parser: 0.2.0 + untildify: 4.0.0 + dev: true + + /default-browser@4.0.0: + resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} + engines: {node: '>=14.16'} + dependencies: + bundle-name: 3.0.0 + default-browser-id: 3.0.0 + execa: 7.1.1 + titleize: 3.0.0 + dev: true + + /define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + dev: true + /define-properties@1.2.0: resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} engines: {node: '>= 0.4'} @@ -2559,6 +2627,14 @@ packages: dev: false optional: true + /enhanced-resolve@5.15.0: + resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + /enquirer@2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} @@ -2697,13 +2773,36 @@ packages: /eslint-import-resolver-node@0.3.7: resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 is-core-module: 2.12.1 resolve: 1.22.2 transitivePeerDependencies: - supports-color dev: true + /eslint-import-resolver-typescript@3.5.5(eslint-plugin-import@2.27.5)(eslint@8.43.0): + resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + dependencies: + debug: 4.3.4 + enhanced-resolve: 5.15.0 + eslint: 8.43.0 + eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0) + eslint-plugin-import: 2.27.5(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0) + get-tsconfig: 4.6.2 + globby: 13.2.2 + is-core-module: 2.12.1 + is-glob: 4.0.3 + synckit: 0.8.5 + transitivePeerDependencies: + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint@8.43.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} @@ -2733,6 +2832,35 @@ packages: - supports-color dev: true + /eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + debug: 3.2.7 + eslint: 8.43.0 + eslint-import-resolver-node: 0.3.7 + eslint-import-resolver-typescript: 3.5.5(eslint-plugin-import@2.27.5)(eslint@8.43.0) + transitivePeerDependencies: + - supports-color + dev: true + /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.60.0)(eslint@8.43.0): resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} @@ -2766,6 +2894,38 @@ packages: - supports-color dev: true + /eslint-plugin-import@2.27.5(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0): + resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + array-includes: 3.1.6 + array.prototype.flat: 1.3.1 + array.prototype.flatmap: 1.3.1 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.43.0 + eslint-import-resolver-node: 0.3.7 + eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0) + has: 1.0.3 + is-core-module: 2.12.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.2 + semver: 6.3.0 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -2920,6 +3080,21 @@ packages: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + /execa@7.1.1: + resolution: {integrity: sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + dev: true + /exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} @@ -2995,6 +3170,17 @@ packages: micromatch: 4.0.5 dev: true + /fast-glob@3.3.0: + resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + /fast-json-patch@3.1.1: resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==} dev: false @@ -3293,6 +3479,12 @@ packages: get-intrinsic: 1.2.1 dev: true + /get-tsconfig@4.6.2: + resolution: {integrity: sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + /get-uri@3.0.2: resolution: {integrity: sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==} engines: {node: '>= 6'} @@ -3385,6 +3577,17 @@ packages: slash: 3.0.0 dev: true + /globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.0 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 4.0.0 + dev: true + /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -3538,6 +3741,11 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + /human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + dev: true + /humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} dependencies: @@ -3725,6 +3933,18 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + + /is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + dev: true + /is-electron@2.2.0: resolution: {integrity: sha512-SpMppC2XR3YdxSzczXReBjqs2zGscWQpBIKqwXYBFic0ERaxNVgwLCHwOLZeESfdJQjX0RDvrJ1lBXX2ij+G1Q==} dev: false @@ -3747,6 +3967,14 @@ packages: dependencies: is-extglob: 2.1.1 + /is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + dependencies: + is-docker: 3.0.0 + dev: true + /is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} dev: false @@ -3808,6 +4036,11 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -3839,6 +4072,13 @@ packages: call-bind: 1.0.2 dev: true + /is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + /isarray@0.0.1: resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} dev: false @@ -4630,6 +4870,11 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -4928,6 +5173,13 @@ packages: dependencies: path-key: 3.1.1 + /npm-run-path@5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + /npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} dependencies: @@ -5035,6 +5287,23 @@ packages: dependencies: mimic-fn: 2.1.0 + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /open@9.1.0: + resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} + engines: {node: '>=14.16'} + dependencies: + default-browser: 4.0.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 2.2.0 + dev: true + /openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} dev: false @@ -5285,6 +5554,11 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -5714,6 +5988,10 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + /resolve.exports@2.0.2: resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} engines: {node: '>=10'} @@ -5772,6 +6050,13 @@ packages: semver-compare: 1.0.0 dev: false + /run-applescript@5.0.0: + resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} + engines: {node: '>=12'} + dependencies: + execa: 5.1.1 + dev: true + /run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -5959,6 +6244,11 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + /slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: true + /smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -6159,6 +6449,11 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -6223,6 +6518,14 @@ packages: swagger-ui-dist: 4.19.0 dev: false + /synckit@0.8.5: + resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} + engines: {node: ^14.18.0 || >=16.0.0} + dependencies: + '@pkgr/utils': 2.4.2 + tslib: 2.5.3 + dev: true + /systeminformation@5.18.6: resolution: {integrity: sha512-pLXv6kjJZ1xUcVs9SrCqbQ9y0x1rgRWxBUc8/KxpOp9IRxFGFfzVK5efsxBn/KdYog4C9rPcKk+kHNIL2SB/8Q==} engines: {node: '>=8.0.0'} @@ -6231,6 +6534,11 @@ packages: dev: false optional: true + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + /tar@6.1.15: resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==} engines: {node: '>=10'} @@ -6301,6 +6609,11 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: false + /titleize@3.0.0: + resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} + engines: {node: '>=12'} + dev: true + /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -6453,7 +6766,10 @@ packages: /tslib@2.5.3: resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} - dev: false + + /tslib@2.6.0: + resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==} + dev: true /tsutils@3.21.0(typescript@5.0.4): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -6785,6 +7101,11 @@ packages: engines: {node: '>= 0.8'} dev: false + /untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + dev: true + /update-browserslist-db@1.0.11(browserslist@4.21.9): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} hasBin: true diff --git a/backend/src/app-data-source.ts b/backend/src/app-data-source.ts index 2220b88b..afeb9f06 100644 --- a/backend/src/app-data-source.ts +++ b/backend/src/app-data-source.ts @@ -1,5 +1,5 @@ import { DataSource, DataSourceOptions } from 'typeorm'; -import { connectOption } from './config'; +import { connectOption } from '~/config'; export const option: DataSourceOptions = { type: 'mysql', diff --git a/backend/src/app.ts b/backend/src/app.ts index ac42924d..4fad2309 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -4,14 +4,14 @@ import express from 'express'; import passport from 'passport'; import swaggerJsdoc from 'swagger-jsdoc'; import swaggerUi from 'swagger-ui-express'; -import jipDataSource from './app-data-source'; -import { FtAuthentication, FtStrategy, JwtStrategy } from './auth/auth.strategy'; -import { connectMode } from './config'; -import router from './routes'; -import swaggerOptions from './swagger/swagger'; -import errorConverter from './utils/error/errorConverter'; -import errorHandler from './utils/error/errorHandler'; -import { logger, morganMiddleware } from './utils/logger'; +import { FtAuthentication, FtStrategy, JwtStrategy } from '~/v1/auth/auth.strategy'; +import swaggerOptions from '~/v1/swagger/swagger'; +import errorConverter from '~/v1/utils/error/errorConverter'; +import errorHandler from '~/v1/utils/error/errorHandler'; +import { logger, morganMiddleware } from '~/v1/utils/logger'; +import { connectMode } from '~/config'; +import jipDataSource from '~/app-data-source'; +import router from './v1/routes'; const app: express.Application = express(); diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index fbb54bff..21138f6d 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -15,7 +15,7 @@ dotenv.config(); const runtimeMode = getRuntimeMode(process.env); // graceful shutdown시 서버 종료 대기 시간 -export const gracefulTerminationTimeout = runtimeMode === 'development' ? 0 : 30 * 1000; +export const gracefulTerminationTimeout = runtimeMode === 'production' ? 30 * 1000 : 0; export const logLevelOption = getLogLevelOption(runtimeMode); export const connectMode = getModeOption(process.env); diff --git a/backend/src/config/logOption.ts b/backend/src/config/logOption.ts index f2bc0580..f087656f 100644 --- a/backend/src/config/logOption.ts +++ b/backend/src/config/logOption.ts @@ -18,7 +18,7 @@ export const colors: Record = { } as const; export const getLogLevelOption = (mode: RuntimeMode): LogLevelOption => { - const logLevel = (mode === 'development' ? 'debug' : 'http'); + const logLevel = (mode === 'production' ? 'http' : 'debug'); const consoleLogLevel = (mode === 'production' ? 'error' : 'debug'); return { logLevel, consoleLogLevel } as const; diff --git a/backend/src/config/runtimeOption.ts b/backend/src/config/runtimeOption.ts index a13689a0..151f636e 100644 --- a/backend/src/config/runtimeOption.ts +++ b/backend/src/config/runtimeOption.ts @@ -1,7 +1,7 @@ import { z } from 'zod'; export type RuntimeMode = z.infer; -export const runtimeModeSchema = z.enum(['development', 'production']); +export const runtimeModeSchema = z.enum(['development', 'production', 'test']); export const runtimeSchema = z.object({ NODE_ENV: runtimeModeSchema.default('development') }); diff --git a/backend/src/mysql.ts b/backend/src/mysql.ts index 8e028c53..260c7b4a 100644 --- a/backend/src/mysql.ts +++ b/backend/src/mysql.ts @@ -1,7 +1,7 @@ import { FieldPacket } from 'mysql2'; import mysql from 'mysql2/promise'; -import { connectOption } from './config'; -import { logger } from './utils/logger'; +import { logger } from '~/v1/utils/logger'; +import { connectOption } from '~/config'; export const DBError = 'DB error'; diff --git a/backend/src/server.ts b/backend/src/server.ts index f256cfd6..52ba0693 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -1,9 +1,9 @@ import { createHttpTerminator } from 'http-terminator'; +import { logger } from '~/v1/utils/logger'; +import scheduler from '~/v1/utils/scheduler'; +import { gracefulTerminationTimeout } from '~/config'; +import jipDataSource from '~/app-data-source'; import app from './app'; -import jipDataSource from './app-data-source'; -import { logger } from './utils/logger'; -import scheduler from './utils/scheduler'; -import { gracefulTerminationTimeout } from './config'; const port = '3000'; diff --git a/backend/src/DTO/common.interface.ts b/backend/src/v1/DTO/common.interface.ts similarity index 100% rename from backend/src/DTO/common.interface.ts rename to backend/src/v1/DTO/common.interface.ts diff --git a/backend/src/DTO/tags.model.ts b/backend/src/v1/DTO/tags.model.ts similarity index 100% rename from backend/src/DTO/tags.model.ts rename to backend/src/v1/DTO/tags.model.ts diff --git a/backend/src/DTO/users.model.ts b/backend/src/v1/DTO/users.model.ts similarity index 100% rename from backend/src/DTO/users.model.ts rename to backend/src/v1/DTO/users.model.ts diff --git a/backend/src/auth/auth.controller.ts b/backend/src/v1/auth/auth.controller.ts similarity index 96% rename from backend/src/auth/auth.controller.ts rename to backend/src/v1/auth/auth.controller.ts index 4e935f74..1d048045 100644 --- a/backend/src/auth/auth.controller.ts +++ b/backend/src/v1/auth/auth.controller.ts @@ -1,13 +1,14 @@ import * as bcrypt from 'bcrypt'; import { NextFunction, Request, Response } from 'express'; import * as status from 'http-status'; +import { randomUUID } from 'node:crypto'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { logger } from '~/v1/utils/logger'; +import { oauth42ApiOption, oauthUrlOption } from '~/config'; +import UsersService from '~/v1/users/users.service'; import * as models from '../DTO/users.model'; -import { oauth42ApiOption, oauthUrlOption } from '../config'; import { updateSlackIdByUserId } from '../slack/slack.service'; -import UsersService from '../users/users.service'; -import * as errorCode from '../utils/error/errorCode'; -import ErrorResponse from '../utils/error/errorResponse'; -import { logger } from '../utils/logger'; import * as authJwt from './auth.jwt'; import * as authService from './auth.service'; import { role } from './auth.type'; @@ -30,7 +31,7 @@ export const getToken = async (req: Request, res: Response, next: NextFunction): // 회원가입 try { const email = `${nickName}@student.42seoul.kr`; - await usersService.createUser(String(email), await bcrypt.hash(String(email), 10)); + await usersService.createUser(String(email), await bcrypt.hash(randomUUID(), 10)); const newUser: { items: models.User[] } = await usersService.searchUserByEmail(email); await authService.updateAuthenticationUser(newUser.items[0].id, id, nickName); await updateSlackIdByUserId(newUser.items[0].id); diff --git a/backend/src/auth/auth.jwt.ts b/backend/src/v1/auth/auth.jwt.ts similarity index 97% rename from backend/src/auth/auth.jwt.ts rename to backend/src/v1/auth/auth.jwt.ts index 1a4a917d..7d7419c1 100644 --- a/backend/src/auth/auth.jwt.ts +++ b/backend/src/v1/auth/auth.jwt.ts @@ -1,7 +1,7 @@ import { Request, Response } from 'express'; import * as jwt from 'jsonwebtoken'; +import { jwtOption } from '~/config'; import { User } from '../DTO/users.model'; -import { jwtOption } from '../config'; /** * User 정보를 가지고 token 만들기 diff --git a/backend/src/auth/auth.service.ts b/backend/src/v1/auth/auth.service.ts similarity index 91% rename from backend/src/auth/auth.service.ts rename to backend/src/v1/auth/auth.service.ts index f79f5367..84c4d05e 100644 --- a/backend/src/auth/auth.service.ts +++ b/backend/src/v1/auth/auth.service.ts @@ -1,5 +1,5 @@ import { ResultSetHeader } from 'mysql2'; -import { executeQuery } from '../mysql'; +import { executeQuery } from '~/mysql'; import { role } from './auth.type'; // eslint-disable-next-line import/prefer-default-export diff --git a/backend/src/auth/auth.strategy.ts b/backend/src/v1/auth/auth.strategy.ts similarity index 95% rename from backend/src/auth/auth.strategy.ts rename to backend/src/v1/auth/auth.strategy.ts index e1dc9e1f..86b8834a 100644 --- a/backend/src/auth/auth.strategy.ts +++ b/backend/src/v1/auth/auth.strategy.ts @@ -1,7 +1,7 @@ import { Request } from 'express'; import { Strategy as FortyTwoStrategy } from 'passport-42'; import { ExtractJwt, Strategy as JWTStrategy, VerifiedCallback } from 'passport-jwt'; -import { jwtOption, oauth42ApiOption, oauthUrlOption } from '../config'; +import { jwtOption, oauth42ApiOption, oauthUrlOption } from '~/config'; const credentials = { clientID: oauth42ApiOption.id, diff --git a/backend/src/auth/auth.type.ts b/backend/src/v1/auth/auth.type.ts similarity index 100% rename from backend/src/auth/auth.type.ts rename to backend/src/v1/auth/auth.type.ts diff --git a/backend/src/auth/auth.validate.ts b/backend/src/v1/auth/auth.validate.ts similarity index 88% rename from backend/src/auth/auth.validate.ts rename to backend/src/v1/auth/auth.validate.ts index b27635d2..eb874f22 100644 --- a/backend/src/auth/auth.validate.ts +++ b/backend/src/v1/auth/auth.validate.ts @@ -1,12 +1,12 @@ import { Request, Response } from 'express'; import * as status from 'http-status'; import { verify } from 'jsonwebtoken'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { logger } from '~/v1/utils/logger'; +import { jwtOption } from '~/config'; +import UsersService from '~/v1/users/users.service'; import { User } from '../DTO/users.model'; -import { jwtOption } from '../config'; -import UsersService from '../users/users.service'; -import * as errorCode from '../utils/error/errorCode'; -import ErrorResponse from '../utils/error/errorResponse'; -import { logger } from '../utils/logger'; import { role } from './auth.type'; const usersService = new UsersService(); diff --git a/backend/src/auth/auth.validateDefaultNullUser.ts b/backend/src/v1/auth/auth.validateDefaultNullUser.ts similarity index 89% rename from backend/src/auth/auth.validateDefaultNullUser.ts rename to backend/src/v1/auth/auth.validateDefaultNullUser.ts index e7c3cbe4..3af67506 100644 --- a/backend/src/auth/auth.validateDefaultNullUser.ts +++ b/backend/src/v1/auth/auth.validateDefaultNullUser.ts @@ -1,12 +1,12 @@ import { Request, Response } from 'express'; import * as status from 'http-status'; import { verify } from 'jsonwebtoken'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { logger } from '~/v1/utils/logger'; +import { jwtOption } from '~/config'; +import UsersService from '~/v1/users/users.service'; import { User } from '../DTO/users.model'; -import { jwtOption } from '../config'; -import UsersService from '../users/users.service'; -import * as errorCode from '../utils/error/errorCode'; -import ErrorResponse from '../utils/error/errorResponse'; -import { logger } from '../utils/logger'; import { role } from './auth.type'; const usersService = new UsersService(); diff --git a/backend/src/book-info-reviews/controller/bookInfoReviews.controller.ts b/backend/src/v1/book-info-reviews/controller/bookInfoReviews.controller.ts similarity index 100% rename from backend/src/book-info-reviews/controller/bookInfoReviews.controller.ts rename to backend/src/v1/book-info-reviews/controller/bookInfoReviews.controller.ts index c5b81400..af7255c5 100644 --- a/backend/src/book-info-reviews/controller/bookInfoReviews.controller.ts +++ b/backend/src/v1/book-info-reviews/controller/bookInfoReviews.controller.ts @@ -2,9 +2,9 @@ import { NextFunction, Request, Response, } from 'express'; import * as status from 'http-status'; +import * as parseCheck from './utils/parseCheck'; import * as bookInfoReviewsService from '../service/bookInfoReviews.service'; import * as errorCheck from './utils/errorCheck'; -import * as parseCheck from './utils/parseCheck'; export const getBookInfoReviewsPage = async ( req: Request, diff --git a/backend/src/book-info-reviews/controller/utils/errorCheck.ts b/backend/src/v1/book-info-reviews/controller/utils/errorCheck.ts similarity index 73% rename from backend/src/book-info-reviews/controller/utils/errorCheck.ts rename to backend/src/v1/book-info-reviews/controller/utils/errorCheck.ts index 6b0d2efc..45419aeb 100644 --- a/backend/src/book-info-reviews/controller/utils/errorCheck.ts +++ b/backend/src/v1/book-info-reviews/controller/utils/errorCheck.ts @@ -1,5 +1,5 @@ -import * as errorCode from '../../../utils/error/errorCode'; -import ErrorResponse from '../../../utils/error/errorResponse'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; export const bookInfoParseCheck = ( bookInfoId : string, diff --git a/backend/src/book-info-reviews/controller/utils/parseCheck.ts b/backend/src/v1/book-info-reviews/controller/utils/parseCheck.ts similarity index 100% rename from backend/src/book-info-reviews/controller/utils/parseCheck.ts rename to backend/src/v1/book-info-reviews/controller/utils/parseCheck.ts diff --git a/backend/src/book-info-reviews/repository/bookInfoReviews.repository.ts b/backend/src/v1/book-info-reviews/repository/bookInfoReviews.repository.ts similarity index 97% rename from backend/src/book-info-reviews/repository/bookInfoReviews.repository.ts rename to backend/src/v1/book-info-reviews/repository/bookInfoReviews.repository.ts index de5c6594..3d233509 100644 --- a/backend/src/book-info-reviews/repository/bookInfoReviews.repository.ts +++ b/backend/src/v1/book-info-reviews/repository/bookInfoReviews.repository.ts @@ -1,4 +1,4 @@ -import { executeQuery } from '../../mysql'; +import { executeQuery } from '~/mysql'; export const getBookinfoReviewsPageNoOffset = async (bookInfoId: number, reviewsId: number, sort: 'asc' | 'desc', limit: number) => { const bookInfoIdQuery = (Number.isNaN(bookInfoId)) ? '' : `AND reviews.bookInfoId = ${bookInfoId}`; diff --git a/backend/src/book-info-reviews/service/bookInfoReviews.service.ts b/backend/src/v1/book-info-reviews/service/bookInfoReviews.service.ts similarity index 100% rename from backend/src/book-info-reviews/service/bookInfoReviews.service.ts rename to backend/src/v1/book-info-reviews/service/bookInfoReviews.service.ts diff --git a/backend/src/books/Likes.repository.ts b/backend/src/v1/books/Likes.repository.ts similarity index 87% rename from backend/src/books/Likes.repository.ts rename to backend/src/v1/books/Likes.repository.ts index 64f453a7..32c9304f 100644 --- a/backend/src/books/Likes.repository.ts +++ b/backend/src/v1/books/Likes.repository.ts @@ -1,6 +1,6 @@ import { QueryRunner, Repository } from 'typeorm'; -import jipDataSource from '../app-data-source'; -import Likes from '../entity/entities/Likes'; +import Likes from '~/entity/entities/Likes'; +import jipDataSource from '~/app-data-source'; class LikesRepository extends Repository { constructor(transactionQueryRunner?: QueryRunner) { diff --git a/backend/src/books/books.controller.spec.ts b/backend/src/v1/books/books.controller.spec.ts similarity index 98% rename from backend/src/books/books.controller.spec.ts rename to backend/src/v1/books/books.controller.spec.ts index a71f26aa..5a8572e1 100644 --- a/backend/src/books/books.controller.spec.ts +++ b/backend/src/v1/books/books.controller.spec.ts @@ -1,7 +1,7 @@ import * as status from 'http-status'; -import { pool } from '../mysql'; +import { pool } from '~/mysql'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; import * as BooksController from './books.controller'; -import ErrorResponse from '../utils/error/errorResponse'; describe('BooksController', () => { afterAll(() => { diff --git a/backend/src/books/books.controller.ts b/backend/src/v1/books/books.controller.ts similarity index 98% rename from backend/src/books/books.controller.ts rename to backend/src/v1/books/books.controller.ts index ad4cf8c7..054593a4 100644 --- a/backend/src/books/books.controller.ts +++ b/backend/src/v1/books/books.controller.ts @@ -2,10 +2,10 @@ import { NextFunction, Request, RequestHandler, Response, } from 'express'; import * as status from 'http-status'; -import * as errorCode from '../utils/error/errorCode'; -import ErrorResponse from '../utils/error/errorResponse'; -import isNullish from '../utils/isNullish'; -import { logger } from '../utils/logger'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import isNullish from '~/v1/utils/isNullish'; +import { logger } from '~/v1/utils/logger'; import * as BooksService from './books.service'; import * as types from './books.type'; import LikesService from './likes.service'; diff --git a/backend/src/books/books.model.ts b/backend/src/v1/books/books.model.ts similarity index 100% rename from backend/src/books/books.model.ts rename to backend/src/v1/books/books.model.ts diff --git a/backend/src/books/books.repository.ts b/backend/src/v1/books/books.repository.ts similarity index 92% rename from backend/src/books/books.repository.ts rename to backend/src/v1/books/books.repository.ts index 8fb90b03..4ffa31e8 100644 --- a/backend/src/books/books.repository.ts +++ b/backend/src/v1/books/books.repository.ts @@ -1,17 +1,17 @@ import { Like, QueryRunner, Repository } from 'typeorm'; import * as Status from 'http-status'; -import jipDataSource from '../app-data-source'; -import { VSearchBook } from '../entity/entities/VSearchBook'; +import { VSearchBook } from '~/entity/entities/VSearchBook'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import Book from '~/entity/entities/Book'; +import BookInfo from '~/entity/entities/BookInfo'; +import Lending from '~/entity/entities/Lending'; +import Category from '~/entity/entities/Category'; +import User from '~/entity/entities/User'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import jipDataSource from '~/app-data-source'; import { CreateBookInfo, LendingBookList, UpdateBook, UpdateBookInfo, } from './books.type'; -import * as errorCode from '../utils/error/errorCode'; -import Book from '../entity/entities/Book'; -import BookInfo from '../entity/entities/BookInfo'; -import Lending from '../entity/entities/Lending'; -import Category from '../entity/entities/Category'; -import User from '../entity/entities/User'; -import ErrorResponse from '../utils/error/errorResponse'; class BooksRepository extends Repository { private readonly searchBook: Repository; diff --git a/backend/src/books/books.service.spec.ts b/backend/src/v1/books/books.service.spec.ts similarity index 95% rename from backend/src/books/books.service.spec.ts rename to backend/src/v1/books/books.service.spec.ts index 772fcf5a..4317cc80 100644 --- a/backend/src/books/books.service.spec.ts +++ b/backend/src/v1/books/books.service.spec.ts @@ -1,6 +1,6 @@ +import jipDataSource from '~/app-data-source'; import * as BooksService from './books.service'; import { CreateBookInfo } from './books.type'; -import jipDataSource from '../app-data-source'; describe('BooksService', () => { beforeAll(async () => { diff --git a/backend/src/books/books.service.ts b/backend/src/v1/books/books.service.ts similarity index 97% rename from backend/src/books/books.service.ts rename to backend/src/v1/books/books.service.ts index f8efcc53..657542d5 100644 --- a/backend/src/books/books.service.ts +++ b/backend/src/v1/books/books.service.ts @@ -1,12 +1,12 @@ /* eslint-disable prefer-regex-literals */ /* eslint-disable prefer-destructuring */ import axios from 'axios'; -import jipDataSource from '../app-data-source'; -import { nationalIsbnApiKey, naverBookApiOption } from '../config'; -import { executeQuery } from '../mysql'; -import * as errorCode from '../utils/error/errorCode'; -import { logger } from '../utils/logger'; -import { StringRows } from '../utils/types'; +import { nationalIsbnApiKey, naverBookApiOption } from '~/config'; +import { executeQuery } from '~/mysql'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import { logger } from '~/v1/utils/logger'; +import { StringRows } from '~/v1/utils/types'; +import jipDataSource from '~/app-data-source'; import * as models from './books.model'; import BooksRepository from './books.repository'; import { diff --git a/backend/src/books/books.type.ts b/backend/src/v1/books/books.type.ts similarity index 100% rename from backend/src/books/books.type.ts rename to backend/src/v1/books/books.type.ts diff --git a/backend/src/books/likes.service.ts b/backend/src/v1/books/likes.service.ts similarity index 96% rename from backend/src/books/likes.service.ts rename to backend/src/v1/books/likes.service.ts index f922dada..6abf729e 100644 --- a/backend/src/books/likes.service.ts +++ b/backend/src/v1/books/likes.service.ts @@ -1,6 +1,6 @@ +import * as errorCode from '~/v1/utils/error/errorCode'; +import jipDataSource from '~/app-data-source'; import LikesRepository from './Likes.repository'; -import * as errorCode from '../utils/error/errorCode'; -import jipDataSource from '../app-data-source'; export default class LikesService { private readonly likesRepository : LikesRepository; diff --git a/backend/src/histories/histories.controller.ts b/backend/src/v1/histories/histories.controller.ts similarity index 92% rename from backend/src/histories/histories.controller.ts rename to backend/src/v1/histories/histories.controller.ts index e863a522..7bdb65ac 100644 --- a/backend/src/histories/histories.controller.ts +++ b/backend/src/v1/histories/histories.controller.ts @@ -2,10 +2,10 @@ import { NextFunction, Request, Response, } from 'express'; import * as status from 'http-status'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { logger } from '~/v1/utils/logger'; +import * as errorCode from '~/v1/utils/error/errorCode'; import * as historiesService from './histories.service'; -import ErrorResponse from '../utils/error/errorResponse'; -import { logger } from '../utils/logger'; -import * as errorCode from '../utils/error/errorCode'; // eslint-disable-next-line import/prefer-default-export export const histories = async ( diff --git a/backend/src/histories/histories.repository.ts b/backend/src/v1/histories/histories.repository.ts similarity index 87% rename from backend/src/histories/histories.repository.ts rename to backend/src/v1/histories/histories.repository.ts index f27badda..a1c475c8 100644 --- a/backend/src/histories/histories.repository.ts +++ b/backend/src/v1/histories/histories.repository.ts @@ -1,6 +1,6 @@ import { QueryRunner, Repository } from 'typeorm'; -import VHistories from '../entity/entities/VHistories'; -import jipDataSource from '../app-data-source'; +import VHistories from '~/entity/entities/VHistories'; +import jipDataSource from '~/app-data-source'; class HistoriesRepository extends Repository { constructor(transactionQueryRunner?: QueryRunner) { diff --git a/backend/src/histories/histories.service.ts b/backend/src/v1/histories/histories.service.ts similarity index 95% rename from backend/src/histories/histories.service.ts rename to backend/src/v1/histories/histories.service.ts index 41a59939..6cdaffc8 100644 --- a/backend/src/histories/histories.service.ts +++ b/backend/src/v1/histories/histories.service.ts @@ -1,7 +1,7 @@ import { Like } from 'typeorm'; +import UsersRepository from '~/v1/users/users.repository'; import { Meta } from '../DTO/common.interface'; import HistoriesRepository from './histories.repository'; -import UsersRepository from '../users/users.repository'; // eslint-disable-next-line import/prefer-default-export export const getHistories = async ( diff --git a/backend/src/histories/histories.type.ts b/backend/src/v1/histories/histories.type.ts similarity index 100% rename from backend/src/histories/histories.type.ts rename to backend/src/v1/histories/histories.type.ts diff --git a/backend/src/inversify.config.ts b/backend/src/v1/inversify.config.ts similarity index 100% rename from backend/src/inversify.config.ts rename to backend/src/v1/inversify.config.ts diff --git a/backend/src/lendings/lendings.controller.spec.ts b/backend/src/v1/lendings/lendings.controller.spec.ts similarity index 99% rename from backend/src/lendings/lendings.controller.spec.ts rename to backend/src/v1/lendings/lendings.controller.spec.ts index 142c2195..2328f409 100644 --- a/backend/src/lendings/lendings.controller.spec.ts +++ b/backend/src/v1/lendings/lendings.controller.spec.ts @@ -1,5 +1,5 @@ import * as status from 'http-status'; -import { pool } from '../mysql'; +import { pool } from '~/mysql'; import * as lendingsController from './lendings.controller'; describe('LendingsController', () => { diff --git a/backend/src/lendings/lendings.controller.ts b/backend/src/v1/lendings/lendings.controller.ts similarity index 96% rename from backend/src/lendings/lendings.controller.ts rename to backend/src/v1/lendings/lendings.controller.ts index 9df4ecd6..9e79cad1 100644 --- a/backend/src/lendings/lendings.controller.ts +++ b/backend/src/v1/lendings/lendings.controller.ts @@ -2,9 +2,9 @@ import { NextFunction, Request, RequestHandler, Response, } from 'express'; import * as status from 'http-status'; -import * as errorCode from '../utils/error/errorCode'; -import ErrorResponse from '../utils/error/errorResponse'; -import { logger } from '../utils/logger'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { logger } from '~/v1/utils/logger'; import * as lendingsService from './lendings.service'; export const create: RequestHandler = async ( diff --git a/backend/src/lendings/lendings.repository.ts b/backend/src/v1/lendings/lendings.repository.ts similarity index 92% rename from backend/src/lendings/lendings.repository.ts rename to backend/src/v1/lendings/lendings.repository.ts index ad185beb..e4444e08 100644 --- a/backend/src/lendings/lendings.repository.ts +++ b/backend/src/v1/lendings/lendings.repository.ts @@ -2,14 +2,14 @@ import { IsNull, MoreThan, QueryRunner, Repository, UpdateResult, } from 'typeorm'; import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; -import User from '../entity/entities/User'; -import jipDataSource from '../app-data-source'; -import Lending from '../entity/entities/Lending'; -import VUserLending from '../entity/entities/VUserLending'; -import Book from '../entity/entities/Book'; -import Reservation from '../entity/entities/Reservation'; -import VLending from '../entity/entities/VLending'; -import { formatDate } from '../utils/dateFormat'; +import User from '~/entity/entities/User'; +import jipDataSource from '~/app-data-source'; +import Lending from '~/entity/entities/Lending'; +import VUserLending from '~/entity/entities/VUserLending'; +import Book from '~/entity/entities/Book'; +import Reservation from '~/entity/entities/Reservation'; +import VLending from '~/entity/entities/VLending'; +import { formatDate } from '~/v1/utils/dateFormat'; class LendingRepository extends Repository { private readonly userRepo: Repository; diff --git a/backend/src/lendings/lendings.service.spec.ts b/backend/src/v1/lendings/lendings.service.spec.ts similarity index 99% rename from backend/src/lendings/lendings.service.spec.ts rename to backend/src/v1/lendings/lendings.service.spec.ts index 6af3b97e..ce9e9672 100644 --- a/backend/src/lendings/lendings.service.spec.ts +++ b/backend/src/v1/lendings/lendings.service.spec.ts @@ -1,4 +1,4 @@ -import { pool } from '../mysql'; +import { pool } from '~/mysql'; import * as lendingsService from './lendings.service'; describe('LendingsService', () => { diff --git a/backend/src/lendings/lendings.service.ts b/backend/src/v1/lendings/lendings.service.ts similarity index 97% rename from backend/src/lendings/lendings.service.ts rename to backend/src/v1/lendings/lendings.service.ts index 39d50818..a310456c 100644 --- a/backend/src/lendings/lendings.service.ts +++ b/backend/src/v1/lendings/lendings.service.ts @@ -1,13 +1,13 @@ /* eslint-disable prefer-destructuring */ /* eslint-disable consistent-return */ import { IsNull, Like } from 'typeorm'; +import { formatDate } from '~/v1/utils/dateFormat'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import jipDataSource from '~/app-data-source'; +import UsersRepository from '~/v1/users/users.repository'; import { publishMessage } from '../slack/slack.service'; import { Meta } from '../DTO/common.interface'; -import { formatDate } from '../utils/dateFormat'; -import * as errorCode from '../utils/error/errorCode'; -import UsersRepository from '../users/users.repository'; import LendingRepository from './lendings.repository'; -import jipDataSource from '../app-data-source'; export const create = async ( userId: number, diff --git a/backend/src/middlewares/wrapAsyncController.ts b/backend/src/v1/middlewares/wrapAsyncController.ts similarity index 77% rename from backend/src/middlewares/wrapAsyncController.ts rename to backend/src/v1/middlewares/wrapAsyncController.ts index 95d9f55e..64563f55 100644 --- a/backend/src/middlewares/wrapAsyncController.ts +++ b/backend/src/v1/middlewares/wrapAsyncController.ts @@ -3,8 +3,8 @@ import { NextFunction, Request, Response, } from 'express'; -import ErrorResponse from '../utils/error/errorResponse'; -import * as errorCode from '../utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import * as errorCode from '~/v1/utils/error/errorCode'; const wrapAsyncController = (fn: Function) => (req: Request, res: Response, next: NextFunction) => { fn(req, res, next) diff --git a/backend/src/notifications/notifications.service.ts b/backend/src/v1/notifications/notifications.service.ts similarity index 98% rename from backend/src/notifications/notifications.service.ts rename to backend/src/v1/notifications/notifications.service.ts index 523e74d4..1be21ee6 100644 --- a/backend/src/notifications/notifications.service.ts +++ b/backend/src/v1/notifications/notifications.service.ts @@ -1,4 +1,4 @@ -import { executeQuery, makeExecuteQuery, pool } from '../mysql'; +import { executeQuery, makeExecuteQuery, pool } from '~/mysql'; import { publishMessage } from '../slack/slack.service'; const succeedReservation = async (reservation: { diff --git a/backend/src/reservations/reservations.controller.spec.ts b/backend/src/v1/reservations/reservations.controller.spec.ts similarity index 99% rename from backend/src/reservations/reservations.controller.spec.ts rename to backend/src/v1/reservations/reservations.controller.spec.ts index 03de95b1..e83e721a 100644 --- a/backend/src/reservations/reservations.controller.spec.ts +++ b/backend/src/v1/reservations/reservations.controller.spec.ts @@ -1,5 +1,5 @@ import * as status from 'http-status'; -import { pool } from '../mysql'; +import { pool } from '~/mysql'; import * as reservationsController from './reservations.controller'; describe('ReservationsController', () => { diff --git a/backend/src/reservations/reservations.controller.ts b/backend/src/v1/reservations/reservations.controller.ts similarity index 96% rename from backend/src/reservations/reservations.controller.ts rename to backend/src/v1/reservations/reservations.controller.ts index e762c6d7..576c947f 100644 --- a/backend/src/reservations/reservations.controller.ts +++ b/backend/src/v1/reservations/reservations.controller.ts @@ -2,11 +2,11 @@ import { NextFunction, Request, RequestHandler, Response, } from 'express'; import * as status from 'http-status'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { logger } from '~/v1/utils/logger'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import * as userUtils from '~/v1/users/users.utils'; import * as reservationsService from './reservations.service'; -import ErrorResponse from '../utils/error/errorResponse'; -import { logger } from '../utils/logger'; -import * as errorCode from '../utils/error/errorCode'; -import * as userUtils from '../users/users.utils'; export const create: RequestHandler = async ( req: Request, diff --git a/backend/src/reservations/reservations.repository.ts b/backend/src/v1/reservations/reservations.repository.ts similarity index 95% rename from backend/src/reservations/reservations.repository.ts rename to backend/src/v1/reservations/reservations.repository.ts index e98617e5..9182d66b 100644 --- a/backend/src/reservations/reservations.repository.ts +++ b/backend/src/v1/reservations/reservations.repository.ts @@ -2,12 +2,12 @@ import { Brackets, IsNull, MoreThan, Not, QueryRunner, Repository, } from 'typeorm'; -import jipDataSource from '../app-data-source'; -import BookInfo from '../entity/entities/BookInfo'; -import User from '../entity/entities/User'; -import Lending from '../entity/entities/Lending'; -import Book from '../entity/entities/Book'; -import reservation from '../entity/entities/Reservation'; +import BookInfo from '~/entity/entities/BookInfo'; +import User from '~/entity/entities/User'; +import Lending from '~/entity/entities/Lending'; +import Book from '~/entity/entities/Book'; +import reservation from '~/entity/entities/Reservation'; +import jipDataSource from '~/app-data-source'; import { Meta } from '../DTO/common.interface'; class ReservationsRepository extends Repository { diff --git a/backend/src/reservations/reservations.service.spec.ts b/backend/src/v1/reservations/reservations.service.spec.ts similarity index 99% rename from backend/src/reservations/reservations.service.spec.ts rename to backend/src/v1/reservations/reservations.service.spec.ts index 6f163e42..7887a354 100644 --- a/backend/src/reservations/reservations.service.spec.ts +++ b/backend/src/v1/reservations/reservations.service.spec.ts @@ -1,4 +1,4 @@ -import { pool } from '../mysql'; +import { pool } from '~/mysql'; import * as reservationsService from './reservations.service'; describe('ReservationsServices', () => { diff --git a/backend/src/reservations/reservations.service.ts b/backend/src/v1/reservations/reservations.service.ts similarity index 97% rename from backend/src/reservations/reservations.service.ts rename to backend/src/v1/reservations/reservations.service.ts index 28ec4f03..1cd9063d 100644 --- a/backend/src/reservations/reservations.service.ts +++ b/backend/src/v1/reservations/reservations.service.ts @@ -1,10 +1,10 @@ -import * as errorCode from '../utils/error/errorCode'; -import { executeQuery, makeExecuteQuery, pool } from '../mysql'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import { executeQuery, makeExecuteQuery, pool } from '~/mysql'; +import jipDataSource from '~/app-data-source'; +import BooksRepository from '~/v1/books/books.repository'; import { queriedReservationInfo, reservationInfo } from './reservations.type'; import { publishMessage } from '../slack/slack.service'; import ReservationsRepository from './reservations.repository'; -import jipDataSource from '../app-data-source'; -import BooksRepository from '../books/books.repository'; export const count = async (bookInfoId: number) => { const numberOfBookInfo = await executeQuery(` diff --git a/backend/src/reservations/reservations.type.ts b/backend/src/v1/reservations/reservations.type.ts similarity index 100% rename from backend/src/reservations/reservations.type.ts rename to backend/src/v1/reservations/reservations.type.ts diff --git a/backend/src/reviews/controller/reviews.controller.ts b/backend/src/v1/reviews/controller/reviews.controller.ts similarity index 95% rename from backend/src/reviews/controller/reviews.controller.ts rename to backend/src/v1/reviews/controller/reviews.controller.ts index bcb8b395..11097d6a 100644 --- a/backend/src/reviews/controller/reviews.controller.ts +++ b/backend/src/v1/reviews/controller/reviews.controller.ts @@ -2,8 +2,10 @@ import { Request, RequestHandler, Response, } from 'express'; import * as status from 'http-status'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import * as parseCheck from '~/v1/utils/parseCheck'; import * as errorCheck from './utils/errorCheck'; -import * as parseCheck from './utils/parseCheck'; import ReviewsService from '../service/reviews.service'; import { createReviewsSchema, @@ -13,8 +15,6 @@ import { queryOptionSchema, userSchema, } from './reviews.type'; -import ErrorResponse from '../../utils/error/errorResponse'; -import * as errorCode from '../../utils/error/errorCode'; const reviewsService = new ReviewsService(); diff --git a/backend/src/reviews/controller/reviews.type.ts b/backend/src/v1/reviews/controller/reviews.type.ts similarity index 100% rename from backend/src/reviews/controller/reviews.type.ts rename to backend/src/v1/reviews/controller/reviews.type.ts diff --git a/backend/src/reviews/controller/utils/errorCheck.ts b/backend/src/v1/reviews/controller/utils/errorCheck.ts similarity index 90% rename from backend/src/reviews/controller/utils/errorCheck.ts rename to backend/src/v1/reviews/controller/utils/errorCheck.ts index 6029a49a..bd9c2338 100644 --- a/backend/src/reviews/controller/utils/errorCheck.ts +++ b/backend/src/v1/reviews/controller/utils/errorCheck.ts @@ -1,6 +1,6 @@ -import * as errorCode from '../../../utils/error/errorCode'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; import ReviewsService from '../../service/reviews.service'; -import ErrorResponse from '../../../utils/error/errorResponse'; const reviewsService = new ReviewsService(); diff --git a/backend/src/reviews/controller/utils/parseCheck.ts b/backend/src/v1/reviews/controller/utils/parseCheck.ts similarity index 100% rename from backend/src/reviews/controller/utils/parseCheck.ts rename to backend/src/v1/reviews/controller/utils/parseCheck.ts diff --git a/backend/src/reviews/repository/reviews.repository.ts b/backend/src/v1/reviews/repository/reviews.repository.ts similarity index 92% rename from backend/src/reviews/repository/reviews.repository.ts rename to backend/src/v1/reviews/repository/reviews.repository.ts index 790d42df..bd4a7c0b 100644 --- a/backend/src/reviews/repository/reviews.repository.ts +++ b/backend/src/v1/reviews/repository/reviews.repository.ts @@ -1,10 +1,10 @@ import { Like, QueryRunner, Repository } from 'typeorm'; -import jipDataSource from '../../app-data-source'; -import Reviews from '../../entity/entities/Reviews'; -import * as errorCode from '../../utils/error/errorCode'; -import BookInfo from '../../entity/entities/BookInfo'; -import User from '../../entity/entities/User'; -import ErrorResponse from '../../utils/error/errorResponse'; +import Reviews from '~/entity/entities/Reviews'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import BookInfo from '~/entity/entities/BookInfo'; +import User from '~/entity/entities/User'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import jipDataSource from '~/app-data-source'; export default class ReviewsRepository extends Repository { private readonly bookInfoRepo: Repository; diff --git a/backend/src/reviews/service/reviews.service.ts b/backend/src/v1/reviews/service/reviews.service.ts similarity index 100% rename from backend/src/reviews/service/reviews.service.ts rename to backend/src/v1/reviews/service/reviews.service.ts diff --git a/backend/src/reviews/service/utils/errorCheck.ts b/backend/src/v1/reviews/service/utils/errorCheck.ts similarity index 85% rename from backend/src/reviews/service/utils/errorCheck.ts rename to backend/src/v1/reviews/service/utils/errorCheck.ts index 7483ccde..ab3af1f0 100644 --- a/backend/src/reviews/service/utils/errorCheck.ts +++ b/backend/src/v1/reviews/service/utils/errorCheck.ts @@ -1,6 +1,6 @@ -import * as errorCode from '../../../utils/error/errorCode'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; import ReviewsRepository from '../../repository/reviews.repository'; -import ErrorResponse from '../../../utils/error/errorResponse'; const reviewsRepository = new ReviewsRepository(); diff --git a/backend/src/routes/auth.routes.ts b/backend/src/v1/routes/auth.routes.ts similarity index 97% rename from backend/src/routes/auth.routes.ts rename to backend/src/v1/routes/auth.routes.ts index 08992f78..d1b81915 100644 --- a/backend/src/routes/auth.routes.ts +++ b/backend/src/v1/routes/auth.routes.ts @@ -1,13 +1,14 @@ import { Router } from 'express'; import passport from 'passport'; + +import { roleSet } from '~/v1/auth/auth.type'; +import authValidate from '~/v1/auth/auth.validate'; +import { oauthUrlOption } from '~/config'; +import * as errorCode from '~/v1/utils/error/errorCode'; import { getIntraAuthentication, getMe, getOAuth, getToken, intraAuthentication, login, logout, -} from '../auth/auth.controller'; -import { roleSet } from '../auth/auth.type'; -import authValidate from '../auth/auth.validate'; -import { oauthUrlOption } from '../config'; -import * as errorCode from '../utils/error/errorCode'; +} from '~/v1/auth/auth.controller'; export const path = '/auth'; export const router = Router(); diff --git a/backend/src/routes/bookInfoReviews.routes.ts b/backend/src/v1/routes/bookInfoReviews.routes.ts similarity index 96% rename from backend/src/routes/bookInfoReviews.routes.ts rename to backend/src/v1/routes/bookInfoReviews.routes.ts index af4b659f..219d70a0 100644 --- a/backend/src/routes/bookInfoReviews.routes.ts +++ b/backend/src/v1/routes/bookInfoReviews.routes.ts @@ -1,8 +1,8 @@ import { Router } from 'express'; +import wrapAsyncController from '~/v1/middlewares/wrapAsyncController'; import { getBookInfoReviewsPage, -} from '../book-info-reviews/controller/bookInfoReviews.controller'; -import wrapAsyncController from '../middlewares/wrapAsyncController'; +} from '~/v1/book-info-reviews/controller/bookInfoReviews.controller'; export const path = '/book-info'; export const router = Router(); diff --git a/backend/src/routes/books.routes.ts b/backend/src/v1/routes/books.routes.ts similarity index 99% rename from backend/src/routes/books.routes.ts rename to backend/src/v1/routes/books.routes.ts index 95836420..d3a5a044 100644 --- a/backend/src/routes/books.routes.ts +++ b/backend/src/v1/routes/books.routes.ts @@ -11,10 +11,10 @@ import { deleteLike, getLikeInfo, updateBookInfo, -} from '../books/books.controller'; -import authValidate from '../auth/auth.validate'; -import authValidateDefaultNullUser from '../auth/auth.validateDefaultNullUser'; -import { roleSet } from '../auth/auth.type'; +} from '~/v1/books/books.controller'; +import authValidate from '~/v1/auth/auth.validate'; +import authValidateDefaultNullUser from '~/v1/auth/auth.validateDefaultNullUser'; +import { roleSet } from '~/v1/auth/auth.type'; export const path = '/books'; export const router = Router(); diff --git a/backend/src/routes/histories.routes.ts b/backend/src/v1/routes/histories.routes.ts similarity index 98% rename from backend/src/routes/histories.routes.ts rename to backend/src/v1/routes/histories.routes.ts index 8c4298e1..cc3b8e8c 100644 --- a/backend/src/routes/histories.routes.ts +++ b/backend/src/v1/routes/histories.routes.ts @@ -1,9 +1,9 @@ import { Router } from 'express'; import { histories, -} from '../histories/histories.controller'; -import authValidate from '../auth/auth.validate'; -import { roleSet } from '../auth/auth.type'; +} from '~/v1/histories/histories.controller'; +import authValidate from '~/v1/auth/auth.validate'; +import { roleSet } from '~/v1/auth/auth.type'; export const path = '/histories'; export const router = Router(); diff --git a/backend/src/routes/index.ts b/backend/src/v1/routes/index.ts similarity index 100% rename from backend/src/routes/index.ts rename to backend/src/v1/routes/index.ts diff --git a/backend/src/routes/lendings.routes.ts b/backend/src/v1/routes/lendings.routes.ts similarity index 98% rename from backend/src/routes/lendings.routes.ts rename to backend/src/v1/routes/lendings.routes.ts index b02415cf..3ad119c9 100644 --- a/backend/src/routes/lendings.routes.ts +++ b/backend/src/v1/routes/lendings.routes.ts @@ -1,9 +1,9 @@ import { Router } from 'express'; import { create, search, lendingId, returnBook, -} from '../lendings/lendings.controller'; -import authValidate from '../auth/auth.validate'; -import { roleSet } from '../auth/auth.type'; +} from '~/v1/lendings/lendings.controller'; +import authValidate from '~/v1/auth/auth.validate'; +import { roleSet } from '~/v1/auth/auth.type'; export const path = '/lendings'; export const router = Router(); diff --git a/backend/src/routes/reservations.routes.ts b/backend/src/v1/routes/reservations.routes.ts similarity index 98% rename from backend/src/routes/reservations.routes.ts rename to backend/src/v1/routes/reservations.routes.ts index c05faaec..8d83ebd5 100644 --- a/backend/src/routes/reservations.routes.ts +++ b/backend/src/v1/routes/reservations.routes.ts @@ -1,9 +1,9 @@ import { Router } from 'express'; import { cancel, create, search, count, userReservations, -} from '../reservations/reservations.controller'; -import authValidate from '../auth/auth.validate'; -import { roleSet } from '../auth/auth.type'; +} from '~/v1/reservations/reservations.controller'; +import authValidate from '~/v1/auth/auth.validate'; +import { roleSet } from '~/v1/auth/auth.type'; export const path = '/reservations'; export const router = Router(); diff --git a/backend/src/routes/reviews.routes.ts b/backend/src/v1/routes/reviews.routes.ts similarity index 99% rename from backend/src/routes/reviews.routes.ts rename to backend/src/v1/routes/reviews.routes.ts index 304b86d7..e4ef1030 100644 --- a/backend/src/routes/reviews.routes.ts +++ b/backend/src/v1/routes/reviews.routes.ts @@ -1,10 +1,10 @@ import { Router } from 'express'; import { createReviews, updateReviews, getReviews, deleteReviews, patchReviews, -} from '../reviews/controller/reviews.controller'; -import authValidate from '../auth/auth.validate'; -import { roleSet } from '../auth/auth.type'; -import wrapAsyncController from '../middlewares/wrapAsyncController'; +} from '~/v1/reviews/controller/reviews.controller'; +import authValidate from '~/v1/auth/auth.validate'; +import { roleSet } from '~/v1/auth/auth.type'; +import wrapAsyncController from '~/v1/middlewares/wrapAsyncController'; export const path = '/reviews'; export const router = Router(); diff --git a/backend/src/routes/slack.routes.ts b/backend/src/v1/routes/slack.routes.ts similarity index 96% rename from backend/src/routes/slack.routes.ts rename to backend/src/v1/routes/slack.routes.ts index 0babf24f..247c288b 100644 --- a/backend/src/routes/slack.routes.ts +++ b/backend/src/v1/routes/slack.routes.ts @@ -1,5 +1,5 @@ import { Router } from 'express'; -import { updateSlackList } from '../slack/slack.controller'; +import { updateSlackList } from '~/v1/slack/slack.controller'; export const path = '/slack'; export const router = Router(); diff --git a/backend/src/routes/stock.routes.ts b/backend/src/v1/routes/stock.routes.ts similarity index 98% rename from backend/src/routes/stock.routes.ts rename to backend/src/v1/routes/stock.routes.ts index 6a3fda21..652ab929 100644 --- a/backend/src/routes/stock.routes.ts +++ b/backend/src/v1/routes/stock.routes.ts @@ -1,5 +1,5 @@ import { Router } from 'express'; -import { stockSearch, stockUpdate } from '../stocks/stocks.controller'; +import { stockSearch, stockUpdate } from '~/v1/stocks/stocks.controller'; export const path = '/stock'; diff --git a/backend/src/routes/tags.routes.ts b/backend/src/v1/routes/tags.routes.ts similarity index 90% rename from backend/src/routes/tags.routes.ts rename to backend/src/v1/routes/tags.routes.ts index aa19ec9f..97a60b76 100644 --- a/backend/src/routes/tags.routes.ts +++ b/backend/src/v1/routes/tags.routes.ts @@ -10,9 +10,9 @@ import { searchSuperDefaultTags, deleteSubTags, deleteSuperTags, -} from '../tags/tags.controller'; -import authValidate from '../auth/auth.validate'; -import { roleSet } from '../auth/auth.type'; +} from '~/v1/tags/tags.controller'; +import authValidate from '~/v1/auth/auth.validate'; +import { roleSet } from '~/v1/auth/auth.type'; export const path = '/tags'; export const router = Router(); @@ -638,7 +638,7 @@ router * get: * tags: * - tags - * summary: 슈퍼 태그에 속한 서브 태그 목록을 가져온다. + * summary: 슈퍼 태그에 속한 서브 태그 목록을 가져온다. 이는 일반 사용자를 위해 사용된다. * description: superTagId에 해당하는 슈퍼 태그에 속한 서브 태그 목록을 가져온다. 태그 병합 페이지에서 슈퍼 태그의 * 서브 태그를 가져올 때 사용한다. * parameters: @@ -686,7 +686,64 @@ router * '500': * description: db 에러 */ - .get('/:superTagId/sub', authValidate(roleSet.librarian), searchSubTags); + .get('/:superTagId/sub', authValidate(roleSet.all), searchSubTags); + +router + /** + * @openapi + * /api/tags/manage/{superTagId}/sub: + * get: + * tags: + * - tags + * summary: 슈퍼 태그에 속한 서브 태그 목록을 가져온다. 이는 태그 관리를 위해 사용된다. + * description: superTagId에 해당하는 슈퍼 태그에 속한 서브 태그 목록을 가져온다. 태그 병합 페이지에서 슈퍼 태그의 + * 서브 태그를 가져올 때 사용한다. + * parameters: + * - in: path + * name: superTagId + * description: 서브 태그를 조회할 슈퍼 태그의 id + * required: true + * responses: + * '200': + * description: 슈퍼 태그에 속한 서브 태그들을 반환한다. + * content: + * application/json: + * schema: + * type: object + * properties: + * items: + * description: 슈퍼 태그에 속한 서브 태그 목록 + * type: array + * items: + * type: object + * properties: + * id: + * description: 서브 태그 고유 id + * type: integer + * content: + * description: 서브 태그의 내용 + * type: string + * login: + * description: 서브 태그를 작성한 카뎃의 인트라 id + * type: string + * example: + * - id: 0 + * content: 도커_쿠버네티스 + * login: yena + * - id: 42 + * content: 도커 + * login: yena + * - id: 50 + * content: 도커 + * login: jang-cho + * '400': + * description: 잘못된 요청. 잘못 입력된 json key, 유효하지 않은 value 등 + * '401': + * description: 태그 기록을 조회할 권한이 없는 사용자 + * '500': + * description: db 에러 + */ + .get('/manage/:superTagId/sub', authValidate(roleSet.librarian), searchSubTags); router /** @@ -761,4 +818,4 @@ router * '500': * description: db 에러 */ - .get('/:bookInfoId', authValidate(roleSet.all), searchSuperDefaultTags); + .get('/:bookInfoId', searchSuperDefaultTags); diff --git a/backend/src/routes/users.routes.ts b/backend/src/v1/routes/users.routes.ts similarity index 97% rename from backend/src/routes/users.routes.ts rename to backend/src/v1/routes/users.routes.ts index 2514643a..b5e4efa2 100644 --- a/backend/src/routes/users.routes.ts +++ b/backend/src/v1/routes/users.routes.ts @@ -1,9 +1,9 @@ import { Router } from 'express'; -import { roleSet } from '../auth/auth.type'; -import authValidate from '../auth/auth.validate'; +import { roleSet } from '~/v1/auth/auth.type'; +import authValidate from '~/v1/auth/auth.validate'; import { create, getVersion, myupdate, search, update, -} from '../users/users.controller'; +} from '~/v1/users/users.controller'; export const path = '/users'; export const router = Router(); @@ -168,7 +168,7 @@ export const router = Router(); * application/json: * schema: * type: object - * description: 200, 201, 205 에러 가능 + * description: 200, 201, 205, 209 에러 가능 * properties: * errorCode: * type: number @@ -363,3 +363,5 @@ router.get('/search', search) .patch('/update/:id', authValidate(roleSet.librarian), update) .patch('/myupdate', authValidate(roleSet.all), myupdate) .get('/EasterEgg', getVersion); + +// .delete('/delete/:id', authValidate(roleSet.librarian), deleteUser); \ No newline at end of file diff --git a/backend/src/slack/slack.controller.ts b/backend/src/v1/slack/slack.controller.ts similarity index 83% rename from backend/src/slack/slack.controller.ts rename to backend/src/v1/slack/slack.controller.ts index d7d460d2..6c4b20d0 100644 --- a/backend/src/slack/slack.controller.ts +++ b/backend/src/v1/slack/slack.controller.ts @@ -1,9 +1,9 @@ import { NextFunction, Request, Response } from 'express'; import * as status from 'http-status'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { logger } from '~/v1/utils/logger'; import * as slack from './slack.service'; -import * as errorCode from '../utils/error/errorCode'; -import ErrorResponse from '../utils/error/errorResponse'; -import { logger } from '../utils/logger'; export const updateSlackList = async ( req: Request, diff --git a/backend/src/slack/slack.service.ts b/backend/src/v1/slack/slack.service.ts similarity index 91% rename from backend/src/slack/slack.service.ts rename to backend/src/v1/slack/slack.service.ts index 3114dd4b..33eadf60 100644 --- a/backend/src/slack/slack.service.ts +++ b/backend/src/v1/slack/slack.service.ts @@ -1,10 +1,10 @@ import { WebClient } from '@slack/web-api'; import { ResultSetHeader } from 'mysql2'; +import { logger } from '~/v1/utils/logger'; +import { botOAuthToken as token } from '~/config'; +import { executeQuery } from '~/mysql'; +import UsersService from '~/v1/users/users.service'; import * as models from '../DTO/users.model'; -import { botOAuthToken as token } from '../config'; -import { executeQuery } from '../mysql'; -import UsersService from '../users/users.service'; -import { logger } from '../utils/logger'; const usersService = new UsersService(); diff --git a/backend/src/stocks/stocks.controller.ts b/backend/src/v1/stocks/stocks.controller.ts similarity index 91% rename from backend/src/stocks/stocks.controller.ts rename to backend/src/v1/stocks/stocks.controller.ts index 6d25bba9..8cafd3dd 100644 --- a/backend/src/stocks/stocks.controller.ts +++ b/backend/src/v1/stocks/stocks.controller.ts @@ -2,8 +2,8 @@ import { NextFunction, Request, RequestHandler, Response, } from 'express'; import * as status from 'http-status'; -import * as errorCode from '../utils/error/errorCode'; -import ErrorResponse from '../utils/error/errorResponse'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; import * as stocksService from './stocks.service'; export const stockSearch: RequestHandler = async ( diff --git a/backend/src/stocks/stocks.repository.ts b/backend/src/v1/stocks/stocks.repository.ts similarity index 89% rename from backend/src/stocks/stocks.repository.ts rename to backend/src/v1/stocks/stocks.repository.ts index 4cab5145..6c0904b6 100644 --- a/backend/src/stocks/stocks.repository.ts +++ b/backend/src/v1/stocks/stocks.repository.ts @@ -3,9 +3,9 @@ import { QueryRunner, Repository, } from 'typeorm'; import { startOfDay, addDays } from 'date-fns'; -import jipDataSource from '../app-data-source'; -import book from '../entity/entities/Book'; -import VStock from '../entity/entities/VStock'; +import book from '~/entity/entities/Book'; +import VStock from '~/entity/entities/VStock'; +import jipDataSource from '~/app-data-source'; class StocksRepository extends Repository { private readonly vStock: Repository; diff --git a/backend/src/stocks/stocks.service.ts b/backend/src/v1/stocks/stocks.service.ts similarity index 95% rename from backend/src/stocks/stocks.service.ts rename to backend/src/v1/stocks/stocks.service.ts index 9648082b..1b7e675f 100644 --- a/backend/src/stocks/stocks.service.ts +++ b/backend/src/v1/stocks/stocks.service.ts @@ -1,6 +1,6 @@ +import jipDataSource from '~/app-data-source'; import { Meta } from '../DTO/common.interface'; import StocksRepository from './stocks.repository'; -import jipDataSource from '../app-data-source'; export const getAllStocks = async ( page: number, diff --git a/backend/src/swagger/swagger.ts b/backend/src/v1/swagger/swagger.ts similarity index 100% rename from backend/src/swagger/swagger.ts rename to backend/src/v1/swagger/swagger.ts diff --git a/backend/src/tags/tags.controller.ts b/backend/src/v1/tags/tags.controller.ts similarity index 97% rename from backend/src/tags/tags.controller.ts rename to backend/src/v1/tags/tags.controller.ts index 71a8dbcd..94235d30 100644 --- a/backend/src/tags/tags.controller.ts +++ b/backend/src/v1/tags/tags.controller.ts @@ -2,10 +2,10 @@ import { NextFunction, Request, Response, } from 'express'; import * as status from 'http-status'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import * as parseCheck from '~/v1/utils/parseCheck'; +import * as errorCode from '~/v1/utils/error/errorCode'; import TagsService from './tags.service'; -import ErrorResponse from '../utils/error/errorResponse'; -import * as parseCheck from '../utils/parseCheck'; -import * as errorCode from '../utils/error/errorCode'; export const createDefaultTags = async ( req: Request, diff --git a/backend/src/tags/tags.repository.ts b/backend/src/v1/tags/tags.repository.ts similarity index 93% rename from backend/src/tags/tags.repository.ts rename to backend/src/v1/tags/tags.repository.ts index 0448ca04..18dbfa10 100644 --- a/backend/src/tags/tags.repository.ts +++ b/backend/src/v1/tags/tags.repository.ts @@ -2,15 +2,15 @@ import { In, InsertResult, Like, QueryRunner, Repository, } from 'typeorm'; import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; -import jipDataSource from '../app-data-source'; -import SubTag from '../entity/entities/SubTag'; -import * as errorCode from '../utils/error/errorCode'; -import User from '../entity/entities/User'; -import SuperTag from '../entity/entities/SuperTag'; -import ErrorResponse from '../utils/error/errorResponse'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import SubTag from '~/entity/entities/SubTag'; +import User from '~/entity/entities/User'; +import SuperTag from '~/entity/entities/SuperTag'; +import VTagsSubDefault from '~/entity/entities/VTagsSubDefault'; +import BookInfo from '~/entity/entities/BookInfo'; +import jipDataSource from '~/app-data-source'; import { subDefaultTag, superDefaultTag } from '../DTO/tags.model'; -import VTagsSubDefault from '../entity/entities/VTagsSubDefault'; -import BookInfo from '../entity/entities/BookInfo'; export class SubTagRepository extends Repository { private readonly vSubDefaultRepo: Repository; diff --git a/backend/src/tags/tags.service.ts b/backend/src/v1/tags/tags.service.ts similarity index 95% rename from backend/src/tags/tags.service.ts rename to backend/src/v1/tags/tags.service.ts index cec1501c..37d20568 100644 --- a/backend/src/tags/tags.service.ts +++ b/backend/src/v1/tags/tags.service.ts @@ -1,13 +1,13 @@ import { In, Like, QueryRunner } from 'typeorm'; import { ErrorCode } from '@slack/web-api'; -import SuperTag from '../entity/entities/SuperTag'; +import * as errorCode from '~/v1/utils/error/errorCode'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { DBError } from '~/mysql'; +import SuperTag from '~/entity/entities/SuperTag'; +import VTagsSubDefault from '~/entity/entities/VTagsSubDefault'; +import jipDataSource from '~/app-data-source'; import { SubTagRepository, SuperTagRepository } from './tags.repository'; -import jipDataSource from '../app-data-source'; -import * as errorCode from '../utils/error/errorCode'; -import ErrorResponse from '../utils/error/errorResponse'; -import { DBError } from '../mysql'; import { superDefaultTag } from '../DTO/tags.model'; -import VTagsSubDefault from '../entity/entities/VTagsSubDefault'; export class TagsService { private readonly subTagRepository : SubTagRepository; @@ -37,9 +37,13 @@ export class TagsService { } else { defaultTagId = defaultTag.id; } - const subTagId = await this.subTagRepository.createDefaultTags(userId, bookInfoId, content, defaultTagId); + const subTagId = await this.subTagRepository.createDefaultTags( + userId, + bookInfoId, + content, + defaultTagId, + ); const subTag = await this.subTagRepository.getSubTags({ id: subTagId }); - defaultTagsInsertion = { id: subTag[0].id, content: subTag[0].content, @@ -54,7 +58,6 @@ export class TagsService { } finally { await this.queryRunner.release(); } - return defaultTagsInsertion; } @@ -293,6 +296,7 @@ export class TagsService { const subDefaultTag: VTagsSubDefault[] = await this.subTagRepository.getSubTags({ content, bookInfoId, + isDeleted: 0, }); if (subDefaultTag.length === 0) { return false; @@ -304,6 +308,7 @@ export class TagsService { const superTag: SuperTag[] = await this.superTagRepository.getSuperTags({ content, bookInfoId, + isDeleted: 0, }); if (superTag.length === 0) { return false; diff --git a/backend/src/users/users.controller.spec.ts b/backend/src/v1/users/users.controller.spec.ts similarity index 100% rename from backend/src/users/users.controller.spec.ts rename to backend/src/v1/users/users.controller.spec.ts diff --git a/backend/src/users/users.controller.ts b/backend/src/v1/users/users.controller.ts similarity index 94% rename from backend/src/users/users.controller.ts rename to backend/src/v1/users/users.controller.ts index a91115cd..e15674c2 100644 --- a/backend/src/users/users.controller.ts +++ b/backend/src/v1/users/users.controller.ts @@ -3,11 +3,11 @@ import { NextFunction, Request, Response } from 'express'; import PasswordValidator from 'password-validator'; import * as status from 'http-status'; import { z } from 'zod'; -import ErrorResponse from '../utils/error/errorResponse'; +import ErrorResponse from '~/v1/utils/error/errorResponse'; +import { logger } from '~/v1/utils/logger'; +import * as errorCode from '~/v1/utils/error/errorCode'; import { User } from '../DTO/users.model'; import UsersService from './users.service'; -import { logger } from '../utils/logger'; -import * as errorCode from '../utils/error/errorCode'; import { searchSchema } from './users.types'; const usersService = new UsersService(); @@ -67,6 +67,10 @@ export const create = async (req: Request, res: Response, next: NextFunction) => if (!email || !password) { return next(new ErrorResponse(errorCode.INVALID_INPUT, status.BAD_REQUEST)); } + const regex = /@student\.42seoul\.kr$/; + if (regex.test(email)) { + return next(new ErrorResponse(errorCode.STUDENT_42_SUBSCRIPTION_FORBIDDEN, status.BAD_REQUEST)); + } try { pwSchema .is().min(10) @@ -188,3 +192,5 @@ export const getVersion = async ( res.status(200).send({ version: 'gshim.v1' }); return 0; }; + +// TODO: user Delete API diff --git a/backend/src/users/users.repository.ts b/backend/src/v1/users/users.repository.ts similarity index 90% rename from backend/src/users/users.repository.ts rename to backend/src/v1/users/users.repository.ts index 7adcb418..307eba9c 100644 --- a/backend/src/users/users.repository.ts +++ b/backend/src/v1/users/users.repository.ts @@ -1,13 +1,13 @@ import { QueryRunner } from 'typeorm/query-runner/QueryRunner'; import { Repository } from 'typeorm'; -import Reservation from '../entity/entities/Reservation'; -import UserReservation from '../entity/entities/UserReservation'; +import Reservation from '~/entity/entities/Reservation'; +import UserReservation from '~/entity/entities/UserReservation'; +import { formatDate } from '~/v1/utils/dateFormat'; +import VUserLending from '~/entity/entities/VUserLending'; +import VLendingForSearchUser from '~/entity/entities/VLendingForSearchUser'; +import User from '~/entity/entities/User'; +import jipDataSource from '~/app-data-source'; import * as models from '../DTO/users.model'; -import { formatDate } from '../utils/dateFormat'; -import VUserLending from '../entity/entities/VUserLending'; -import VLendingForSearchUser from '../entity/entities/VLendingForSearchUser'; -import User from '../entity/entities/User'; -import jipDataSource from '../app-data-source'; export default class UsersRepository extends Repository { private readonly userLendingRepo: Repository; diff --git a/backend/src/users/users.service.spec.ts b/backend/src/v1/users/users.service.spec.ts similarity index 97% rename from backend/src/users/users.service.spec.ts rename to backend/src/v1/users/users.service.spec.ts index 190f15f4..f36b6bed 100644 --- a/backend/src/users/users.service.spec.ts +++ b/backend/src/v1/users/users.service.spec.ts @@ -1,8 +1,8 @@ /* eslint no-console: "off" */ import { QueryRunner } from 'typeorm'; -import jipDataSource from '../app-data-source'; -import { connectMode } from '../config'; -import { logger } from '../utils/logger'; +import jipDataSource from '~/app-data-source'; +import { connectMode } from '~/config'; +import { logger } from '~/v1/utils/logger'; import UsersService from './users.service'; const usersService = new UsersService(); diff --git a/backend/src/users/users.service.ts b/backend/src/v1/users/users.service.ts similarity index 81% rename from backend/src/users/users.service.ts rename to backend/src/v1/users/users.service.ts index 12d61010..b641e6a9 100644 --- a/backend/src/users/users.service.ts +++ b/backend/src/v1/users/users.service.ts @@ -1,5 +1,5 @@ import { Like, Not } from 'typeorm'; -import * as errorCode from '../utils/error/errorCode'; +import * as errorCode from '~/v1/utils/error/errorCode'; import * as models from '../DTO/users.model'; import * as types from '../DTO/common.interface'; import UsersRepository from './users.repository'; @@ -11,24 +11,22 @@ export default class UsersService { this.usersRepository = new UsersRepository(); } - async setOverDueDay(items: models.User[]): Promise { - const usersIdList = items.map((user: models.User) => ({ userId: user.id })); + /** + * 기존 사용자 배열에 대출과 연체 정보를 추가하여 반환합니다. + * + * @returns 사용자의 대출 정보를 포함한 사용자 정보 배열 + * @todo 대출 정보까지 함께 쿼리하는 searchUsersBy 메서드를 만들고 searchUserBy* 에서 사용하도록 수정 + */ + async withLendingInfo(users: models.User[]): Promise { + const usersIdList = users.map((user) => ({ userId: user.id })); const lending = await this.usersRepository .getLending(usersIdList) as unknown as models.Lending[]; - if (items) { - return items.map((item: models.User) => { - const rtnObj: models.User = Object.assign(item); - rtnObj.lendings = lending.filter((lend) => lend.userId === item.id); - rtnObj.overDueDay = 0; - if (rtnObj.lendings.length) { - rtnObj.lendings.forEach((lend: models.Lending) => { - rtnObj.overDueDay += (+lend.overDueDay); - }); - } - return rtnObj; - }); - } - return items; + + return users.map((user) => { + const lendings = lending.filter((lend) => lend.userId === user.id); + const overDueDay = lendings.reduce((acc, cur) => acc + cur.overDueDay, 0); + return { ...user, lendings, overDueDay }; + }); } async userLendings(userId: number) { @@ -46,7 +44,7 @@ export default class UsersService { { nickname: Like(`%${nicknameOrEmail}%`) }, { email: Like(`%${nicknameOrEmail}`) }, ], limit, page); - const setItems = await this.setOverDueDay(items); + const setItems = await this.withLendingInfo(items); const meta: types.Meta = { totalItems: count, itemCount: setItems.length, @@ -59,7 +57,7 @@ export default class UsersService { async searchUserById(id: number) { let items = (await this.usersRepository.searchUserBy({ id }, 0, 0))[0]; - items = await this.setOverDueDay(items); + items = await this.withLendingInfo(items); return { items }; } @@ -80,7 +78,7 @@ export default class UsersService { async searchAllUsers(limit: number, page: number) { const [items, count] = await this.usersRepository.searchUserBy(1, limit, page); - const setItems = await this.setOverDueDay(items); + const setItems = await this.withLendingInfo(items); const meta: types.Meta = { totalItems: count, itemCount: setItems.length, diff --git a/backend/src/users/users.types.ts b/backend/src/v1/users/users.types.ts similarity index 100% rename from backend/src/users/users.types.ts rename to backend/src/v1/users/users.types.ts diff --git a/backend/src/users/users.utils.ts b/backend/src/v1/users/users.utils.ts similarity index 100% rename from backend/src/users/users.utils.ts rename to backend/src/v1/users/users.utils.ts diff --git a/backend/src/utils/dateFormat.ts b/backend/src/v1/utils/dateFormat.ts similarity index 100% rename from backend/src/utils/dateFormat.ts rename to backend/src/v1/utils/dateFormat.ts diff --git a/backend/src/utils/error/errorCode.ts b/backend/src/v1/utils/error/errorCode.ts similarity index 98% rename from backend/src/utils/error/errorCode.ts rename to backend/src/v1/utils/error/errorCode.ts index 018ff66e..9cb9adce 100644 --- a/backend/src/utils/error/errorCode.ts +++ b/backend/src/v1/utils/error/errorCode.ts @@ -22,6 +22,7 @@ export const INVALIDATE_PASSWORD = '205'; export const INVALID_ROLE = '206'; export const SLACK_OVERLAP = '207'; export const INTRA_AUTHENTICATE_SUCCESS = '208'; +export const STUDENT_42_SUBSCRIPTION_FORBIDDEN = '209'; export const SLACKID_OVERLAP = '301'; export const NO_ISBN = '302'; diff --git a/backend/src/utils/error/errorConverter.ts b/backend/src/v1/utils/error/errorConverter.ts similarity index 100% rename from backend/src/utils/error/errorConverter.ts rename to backend/src/v1/utils/error/errorConverter.ts diff --git a/backend/src/utils/error/errorHandler.ts b/backend/src/v1/utils/error/errorHandler.ts similarity index 100% rename from backend/src/utils/error/errorHandler.ts rename to backend/src/v1/utils/error/errorHandler.ts diff --git a/backend/src/utils/error/errorResponse.ts b/backend/src/v1/utils/error/errorResponse.ts similarity index 100% rename from backend/src/utils/error/errorResponse.ts rename to backend/src/v1/utils/error/errorResponse.ts diff --git a/backend/src/utils/isNullish.ts b/backend/src/v1/utils/isNullish.ts similarity index 100% rename from backend/src/utils/isNullish.ts rename to backend/src/v1/utils/isNullish.ts diff --git a/backend/src/utils/logger.ts b/backend/src/v1/utils/logger.ts similarity index 95% rename from backend/src/utils/logger.ts rename to backend/src/v1/utils/logger.ts index aced8508..3a6c6409 100644 --- a/backend/src/utils/logger.ts +++ b/backend/src/v1/utils/logger.ts @@ -7,11 +7,11 @@ import { transports, } from 'winston'; import WinstonDaily from 'winston-daily-rotate-file'; -import { logLevelOption } from '../config'; +import { logLevelOption } from '~/config'; import { colors, levels, -} from '../config/logOption'; +} from '~/config/logOption'; const { combine, timestamp, printf, colorize, errors, diff --git a/backend/src/utils/parseCheck.ts b/backend/src/v1/utils/parseCheck.ts similarity index 100% rename from backend/src/utils/parseCheck.ts rename to backend/src/v1/utils/parseCheck.ts diff --git a/backend/src/utils/scheduler.ts b/backend/src/v1/utils/scheduler.ts similarity index 100% rename from backend/src/utils/scheduler.ts rename to backend/src/v1/utils/scheduler.ts diff --git a/backend/src/utils/types.ts b/backend/src/v1/utils/types.ts similarity index 100% rename from backend/src/utils/types.ts rename to backend/src/v1/utils/types.ts diff --git a/backend/tsconfig.json b/backend/tsconfig.json index ebc3fab4..6ec0e920 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -28,7 +28,9 @@ // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + "paths": { + "~/*": ["./src/*"], + }, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ "typeRoots": [ "./node_modules/@types", diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..ecaa72a3 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +/site \ No newline at end of file diff --git a/docs/docs/convention.md b/docs/docs/convention.md new file mode 100644 index 00000000..a5cde2e5 --- /dev/null +++ b/docs/docs/convention.md @@ -0,0 +1,47 @@ +# Commit 전략 + +## commit의 기준 + +- commit은 아래 커밋 타입에 맞게 commit들을 분리한다. + +## commit의 타입 + +- FEAT: 기능을 추가 또는 수정 +- ENV: 개발 환경을 추가 또는 수정 (eslint 변경, dockerfile 변경 등) +- FIX: 버그를 해결 +- DOCS: 문서를 수정 ([README.md](http://readme.md/) 변경, swagger) +- STYLE: 코드 스타일 변경 (prettier, npm run lint 등) +- REFACT: 코드를 리팩토링, 기능은 같고 코드가 변경 +- TEST: 테스트 코드를 추가 또는 수정 +- MERGE: 풀 리퀘스트 머지할 경우 +- CHORE: 단순오타 +- WIP: working in process 아직 작업중인 내용 + +## commit 예시 + +``` +ex) +FIX: 모델 validation 오류 수정 + +- Book title 제목 default 값 추가 +- User intra 최소 길이 0으로 변경 + +ex) +FEAT: 로그인 기능 추가 + +- auth/ api 추가 + +ex) +TEST: bookController 테스트 코드 추가 + +- 책 제목에 대한 유효성 테스트 추가 +``` + +## 네이밍 +**변수명, 함수명, 칼럼명, 파일명**은 **camelCase**를 사용한다. +**클래스명, 타입명**은 **PascalCase**를 사용한다. +**테이블명**은 **snake_case**를 사용한다. + +## ts파일의 import +(*).service.ts 파일을 import할 때는 카멜케이스로 (*)Service라고 import한다. +e.g.) users.service.ts를 import할 경우 `import * as usersService from ../users/users.service.ts`같이 적는다. diff --git a/docs/docs/error.md b/docs/docs/error.md new file mode 100644 index 00000000..eab6eee3 --- /dev/null +++ b/docs/docs/error.md @@ -0,0 +1,130 @@ +# 에러 코드 (Error code) +## Common Error Code (0번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|0| UNKNOWN_ERROR |unknown error| +|1| QUERY_EXECUTION_FAILED |executeQuery SQL 에러| +|2| INVALID_INPUT |유효하지 않은 인자 (req , param, body에 잘못된 인자가 들어왔을 때)| +|42| CLIENT_AUTH_FAILED |Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.| + +--- + +## Auth Error Code (100번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|100| NO_AUTHORIZATION |권한이 없을때| +|101| NO_USER |해당 토큰의 유저가 DB에 없을때| +|102| NO_TOKEN |토큰이 발급되지 않았을때| +|103| NO_INPUT |로그인시 ID, PW 파라미터가 없을때| +|104| WRONG_PASSWORD |비밀번호가 일치하지 않을때(로그인 실패)| +|105| ALREADY_AUTHENTICATED |이미 인증된 회원의 경우(또 인증할 경우)| +|107| NO_ID |해당 ID가 존재하지 않을때(로그인 실패)| +|108| EXPIRATION_TOKEN |토큰이 만료되었을 경우| +|109| TOKEN_NOT_VALID |토큰이 유효하지 않을때| +|110| NON_AFFECTED |UPDATE 실패| +|111| ANOTHER_ACCOUNT_AUTHENTICATED |다른 계정에 이미 42 intra가 연동되어 있는 경우
(105번은 이미 인증된 회원인 경우이고 111번은 42 계정을 다른 계정에 또 연결하는 경우)| +|112| ACCESS_DENIED |42 API 사용에 대해 동의를 하지 않았을 경우| + +--- + +## User Error Code (200번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|203| EMAIL_OVERLAP |email 중복. (이미 있는 email 로 가입)| +|204| NICKNAME_OVERLAP |nickname 중복. (이미 있는 nickname 입력)| +|205| INVALIDATE_PASSWORD |잘못된 password 형식| +|206| INVALID_ROLE |유효하지 않은 role 값입니다.| +|207| SLACK_OVERLAP |슬랙 ID가 중복| +|208| INTRA_AUTHENTICATE_SUCCESS |42 인증 완료 ( 에러 메세지는 아닌데, 인증 완료시 Front한테 상태값을 전달해서 메세지를 띄우기 위한 코드 입니다 )| + +--- + +## Books Error Code (300번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|301| SLACKID_OVERLAP | 슬랙 ID가 중복됨 | +|302| NO_ISBN | 네이버 Open API에서 ISBN검색 결과가 없음 | +|303| ISBN_SEARCH_FAILED | 국립중앙 도서관 API에서 ISBN 검색이 실패 | +|304| NO_BOOK_INFO_ID | book_info table에 존재하지 않는 ID를 조회하려고 함 | +|305| CALL_SIGN_OVERLAP |등록하려는 callSign는 이미 있는 callSign임| +|306| INVALID_CALL_SIGN |유효하지 않는 callsign| +|307| NO_BOOK_ID |없는 BOOK_ID를 조회하려고 함| +|308| FAIL_CREATE_BOOK_BY_UNEXPECTED | 예상치 못한 에러로 책 정보 insert에 실패함 | +|309| INVALID_CATEGORY_ID | 보내준 카테고리 ID에 해당하는 callsign을 찾을 수 없음 | +|310| ISBN_SEARCH_FAILED_IN_NAVER | 네이버 Open API에서 ISBN검색 자체가 실패함 | +|311| INVALID_PUBDATE_FORNAT | 입력한 pubdate가 알맞은 형식이 아님. 기대하는 형식 "20220807" | +|312| FAIL_PATCH_BOOK_BY_UNEXPECTED | 예상치 못한 에러로 bookInfo patch 가 실패함 | +|313| NO_BOOK_INFO_DATA | 입력한 data가 없음(적어도 하나의 데이터는 필수) | + +--- + +## Lendings Error Code (400번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|401| NO_USER_ID | 유저 없음 | +|402| NO_PERMISSION | 권환 없음 | +|403| LENDING_OVERLOAD |2권 이상 대출| +|404| LENDING_OVERDUE |연체 중| +|405| ON_LENDING |대출 중| +|406| ON_RESERVATION |예약된 책| +|407| LOST_BOOK |분실된 책| +|408| DAMAGED_BOOK |파손된 책| +|410| NONEXISTENT_LENDING |존재하지 않는 대출| +|411| ALREADY_RETURNED |이미 반납 처리된 대출| + +--- + +## Reservation Error Code (500번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|501| INVALID_INFO_ID |book_info_id가 유효하지 않음| +|502| AT_PENALTY |대출 제한 중| +|503| NOT_LENDED |대출 가능| +|504| ALREADY_RESERVED |이미 예약 중| +|505| ALREADY_LENDED |이미 대출 중| +|506| MORE_THAN_TWO_RESERVATIONS |두 개 이상 예약 중| +|507| NO_MATCHING_USER |해당 유저 아님| +|508| RESERVATION_NOT_EXIST |예약 ID 존재하지 않음| +|509| NOT_RESERVED |예약 상태가 아님| + +--- + +## Likes (600번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|601| INVALID_INFO_ID_LIKES | bookInfoId가 유효하지 않음 | +|602| ALREADY_LIKES | 좋아요 데이터가 이미 존재함 | +|603| NONEXISTENT_LIKES | bookInfoId가 유효하지 않음 | + +--- + +## history (700번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|700| UNAUTHORIZED | 사서권한이 없는 사람이 모든 대출/반납 기록을 조회하려고함 | + + +--- + +### reviews (800번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|800| INVALID_INPUT_REVIEWS | 유효하지 않은 양식의 reviews | +|801| UNAUTHORIZED_REVIEWS | reviews를 수정/삭제할 권한이 없음 | +|804| NOT_FOUND_REVIEWS | 존재하지 않는 reviewsId | +|805| DISABLED_REVIEWS | Disabled 된 review | +|810| INVALID_INPUT_REVIEWS_ID | 유효하지 않은 양식의 reviewsId | +|811| INVALID_INPUT_REVIEWS_CONTENT | 유효하지 않은 양식의 reviews content | + +--- + +### tags (900번대) +|Error Code|Constant Name|Description| +|:----------:|:-------------|:-----------| +|900| INVALID_INPUT_TAGS | 유효하지 않은 양식의 tags | +|901| UNAUTHORIZED_TAGS | tags를 수정/삭제할 권한이 없음 | +|902| ALREADY_EXISTING_TAGS | 이미 존재하는 내용의 태그 | +|904| NOT_FOUND_TAGS | 존재하지 않는 tagId | +|910| INVALID_INPUT_TAG_ID | 유효하지 않은 양식의 tagId | + +--- \ No newline at end of file diff --git a/docs/docs/gitflow.md b/docs/docs/gitflow.md new file mode 100644 index 00000000..336d8f1d --- /dev/null +++ b/docs/docs/gitflow.md @@ -0,0 +1,18 @@ +# Git Flow Strategy + +## `main` 브랜치 +- 완성된 기능들이 들어있는 가장 최신의 브랜치입니다. develop 브랜치에서만 푸시를 받습니다. + +## `develop` 브랜치 +- 개발중인 기능들이 이슈 단위로 완료되어 들어오는 브랜치입니다. issue 브랜치에서 푸시를 받습니다. + +## issue 브랜치 (eg. `42-issue-추가`) +- 개별 이슈에 대한 개발이 진행되는 브랜치입니다. +- 이슈에서 create_branch 기능을 이용하여 자동으로 생성합시다. +- 여러 이슈로 이루어진 이슈는 여러 이슈를 가진 이슈로 묶어 Umbrella issue 로 관리합니다. [이슈 전략 페이지로 링크] +- 이슈를 해결한 후 pull request 를 생성합니다. +- 리뷰를 받은 후 **_squash merge_** 로 develop 브랜치에 merge 합니다. + + +## 개인 브랜치 +둘 이상의 인원이 하나의 issue 브랜치에서 작업할 경우에 `issue/23_jolim`같은 방식으로 이름지어서 푸시합니다. \ No newline at end of file diff --git a/docs/docs/index.md b/docs/docs/index.md new file mode 100644 index 00000000..7342a5e3 --- /dev/null +++ b/docs/docs/index.md @@ -0,0 +1,7 @@ +# Welcome to Jiphyeonjeon Dev + +## 문서 추가하는 방법 +- docs 폴더 아래에 파일을 추가한다. 파일명은 영어로 한다. +- 반드시 # 으로 제목을 추가한다. 목차의 이름이 된다. 한글로 해도 된다. +- 로컬에서 어떻게 보일지 테스트해보고 싶으면 mkdocs 를 설치해서 실행해보면 된다. +- 디렉토리 내부에 파일을 만들수도 있다. 단 디렉토리 이름은 영어로 해야 한다. diff --git a/docs/docs/issue_strategy.md b/docs/docs/issue_strategy.md new file mode 100644 index 00000000..6379292e --- /dev/null +++ b/docs/docs/issue_strategy.md @@ -0,0 +1,16 @@ +# 이슈 전략 + +## 여러 이슈를 관리하는 이슈 ☂️ +- 제목에 :open_unbrella: 라는 ☂️ 모양의 이모지를 붙이고 label 도 umbrella 이슈로 설정해주세요 +- 하나의 이슈는 하나의 풀 리퀘스트로 만들어지는데, 규모가 큰 이슈의 경우 umbrella 이슈로 묶어서 관리합니다. +- umbrella 이슈 내부에서 체크리스트에 이슈를 링킹할 수 있습니다. +- 링킹하는 방법은 `- [ ] #'이슈번호'` 를 입력하면 링크할 수 있습니다. +- 여러 이슈를 묶은 이슈는 issue 페이지 우측 하단의 pin 기능을 활용하여 쉽게 찾아가도록 합시다. + + +## 개별 이슈 +- 개별 이슈의 이름은 자유롭게 설정합니다. 그리고 어떤 이슈인지 자세히 명세하도록 합니다. +- 개별 이슈마다 브랜치 생성은 깃허브 우측의 브랜치 자동생성 기능을 이용하도록 합시다. +- **_개별 이슈들은 각각 브랜치 안에서 관리하고 squash merge 를 이용해서 develop 브랜치에 pull request 를 날리도록 합시다!_** + +[참고: 415 이슈](https://github.com/jiphyeonjeon-42/backend/issues/415) \ No newline at end of file diff --git a/docs/docs/usage.md b/docs/docs/usage.md new file mode 100644 index 00000000..f43304e9 --- /dev/null +++ b/docs/docs/usage.md @@ -0,0 +1,19 @@ +# How to use Mkdocs +### 로컬에서 정적 페이지 빌드 +1. working directory의 루트 디렉토리에 docs/ 생성 +2. mkdocs 설치 (mkdocs 공식문서 참조) +3. 프로젝트 생성 `mkdocs new [프로젝트 이름]` +4. 빌드 `mkdocs build` + - site 디렉토리에 정적 페이지 생성 +5. 실행 `mkdocs run` + +### github 에 정적 페이지 배포법 +... 로컬에서 정적 페이지 빌드하는 것까지는 똑같은데 +1. `mkdocs gh-pages` 명령을 내리면 소속된 레포지토리의 gh-pages 디렉토리에 정적 사이트를 배포해버림 +2. github -> setting -> github pages 에 branch 를 gh-pages + +### github 에 정적 페이지 자동 배포 +앞에서 알아본 배포법은 직접 빌드하고 배포까지 해야 한다. 매우 귀찮음. +github action 을 통해 특정 트리거가 발생하면 자동으로 빌드 - 배포를 하도록 만들 수 있음. +이를 위해서는 .github/workflows/ 디렉토리에 .yml 파일 작성 ( github action 을 작동시킬 파일 ) 해야한다. +yml 의 예시는.. 디렉토리 참조. \ No newline at end of file diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml new file mode 100644 index 00000000..e0716e5c --- /dev/null +++ b/docs/mkdocs.yml @@ -0,0 +1,8 @@ +site_name: 집현전 문서 +theme: + name: material + language: ko + +extra: + static_dirs: + - docs/image \ No newline at end of file