diff --git a/package-lock.json b/package-lock.json index 8129434..21a6454 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,8 @@ "redis": "^4.2.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", - "rxjs": "^7.2.0", + "rxjs": "^7.5.6", + "rxjs-compat": "^6.6.7", "swagger-ui-express": "^4.4.0", "typeorm": "^0.3.7", "uuid": "^8.3.2", @@ -62,7 +63,7 @@ "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "codecov": "^3.8.3", - "eslint": "^8.0.1", + "eslint": "^8.20.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^4.0.0", "husky": "^8.0.1", @@ -73,7 +74,7 @@ "supertest": "^6.1.3", "ts-jest": "^27.0.3", "ts-loader": "^9.2.3", - "ts-node": "^10.0.0", + "ts-node": "^10.9.1", "tsconfig-paths": "^3.10.1", "typescript": "^4.3.5" } @@ -814,7 +815,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -826,7 +827,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -917,6 +918,13 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "optional": true, + "peer": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1337,7 +1345,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -1379,7 +1387,7 @@ "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.14", @@ -2059,25 +2067,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "devOptional": true }, "node_modules/@types/babel__core": { "version": "7.1.19", @@ -2770,7 +2778,7 @@ "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, + "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -2978,7 +2986,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true }, "node_modules/argparse": { "version": "2.0.1", @@ -3405,6 +3413,47 @@ "node": ">=10.1" } }, + "node_modules/bull/node_modules/denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/bull/node_modules/ioredis": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", + "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "dependencies": { + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.isarguments": "^3.1.0", + "p-map": "^2.1.0", + "redis-commands": "1.7.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/bull/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "engines": { + "node": ">=6" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -4017,7 +4066,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "node_modules/cron-parser": { "version": "4.5.0", @@ -4192,9 +4241,11 @@ } }, "node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "optional": true, + "peer": true, "engines": { "node": ">=0.10" } @@ -4239,7 +4290,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.3.1" } @@ -4314,6 +4365,11 @@ "node": ">=12" } }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -4580,9 +4636,9 @@ } }, "node_modules/eslint": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.19.0.tgz", - "integrity": "sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", + "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", "dev": true, "dependencies": { "@eslint/eslintrc": "^1.3.0", @@ -4880,6 +4936,20 @@ "node": ">= 0.6" } }, + "node_modules/event-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", + "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", + "dependencies": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -5339,6 +5409,11 @@ "node": ">= 0.6" } }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -5851,38 +5926,30 @@ } }, "node_modules/ioredis": { - "version": "4.28.5", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", - "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.2.2.tgz", + "integrity": "sha512-wryKc1ur8PcCmNwfcGkw5evouzpbDXxxkMkzPK8wl4xQfQf7lHe11Jotell5ikMVAtikXJEu/OJVaoV51BggRQ==", + "optional": true, + "peer": true, "dependencies": { + "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", - "debug": "^4.3.1", - "denque": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.0.1", "lodash.defaults": "^4.2.0", - "lodash.flatten": "^4.4.0", "lodash.isarguments": "^3.1.0", - "p-map": "^2.1.0", - "redis-commands": "1.7.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" }, "engines": { - "node": ">=6" + "node": ">=12.22.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/ioredis" } }, - "node_modules/ioredis/node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "engines": { - "node": ">=6" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -7466,6 +7533,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -7689,7 +7761,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "node_modules/makeerror": { "version": "1.0.12", @@ -7700,6 +7772,11 @@ "tmpl": "1.0.5" } }, + "node_modules/map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==" + }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -7810,6 +7887,11 @@ "node": ">=6" } }, + "node_modules/mingo": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/mingo/-/mingo-1.3.3.tgz", + "integrity": "sha512-Y4wGTD/M7AMqF8QxKaBGps+axq/Z48hdtRAeiKtInkEXMLzUWUwT0OPDzrB26xrav9GF1AOYJfwVWPcLwnkgTA==" + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -8417,6 +8499,14 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dependencies": { + "through": "~2.3" + } + }, "node_modules/pg": { "version": "8.7.3", "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz", @@ -9020,13 +9110,18 @@ } }, "node_modules/rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", + "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", "dependencies": { "tslib": "^2.1.0" } }, + "node_modules/rxjs-compat": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz", + "integrity": "sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw==" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -9059,6 +9154,17 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/save": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/save/-/save-2.5.0.tgz", + "integrity": "sha512-xiVLpKVbx8EmW0HDkNRjYL271OnIRCo8VGWAEq6/K+E0dgNrwKV2xvKXdfPj6HGYA6l760800LyewSY3ooljCg==", + "dependencies": { + "async": "^3.2.2", + "event-stream": "^4.0.1", + "lodash.assign": "^4.2.0", + "mingo": "1" + } + }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -9411,6 +9517,17 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, "node_modules/split2": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", @@ -9467,6 +9584,15 @@ "node": ">= 0.8" } }, + "node_modules/stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, "node_modules/stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", @@ -9862,8 +9988,7 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/tmp": { "version": "0.0.33", @@ -10040,10 +10165,10 @@ } }, "node_modules/ts-node": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", - "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", - "dev": true, + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "devOptional": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -10086,7 +10211,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.4.0" } @@ -10421,7 +10546,7 @@ "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10522,7 +10647,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "node_modules/v8-to-istanbul": { "version": "8.1.1", @@ -10998,7 +11123,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -11565,7 +11690,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -11574,7 +11699,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -11659,6 +11784,13 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "optional": true, + "peer": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -11990,7 +12122,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true + "devOptional": true }, "@jridgewell/set-array": { "version": "1.1.2", @@ -12025,7 +12157,7 @@ "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "devOptional": true }, "@jridgewell/trace-mapping": { "version": "0.3.14", @@ -12176,12 +12308,14 @@ "@nestjs/mapped-types": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.0.1.tgz", - "integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==" + "integrity": "sha512-NFvofzSinp00j5rzUd4tf+xi9od6383iY0JP7o0Bnu1fuItAUkWBgc4EKuIQ3D+c2QI3i9pG1kDWAeY27EMGtg==", + "requires": {} }, "@nestjs/passport": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-8.2.2.tgz", - "integrity": "sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw==" + "integrity": "sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw==", + "requires": {} }, "@nestjs/platform-express": { "version": "8.4.7", @@ -12356,7 +12490,8 @@ "@redis/bloom": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.0.2.tgz", - "integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==" + "integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==", + "requires": {} }, "@redis/client": { "version": "1.2.0", @@ -12371,22 +12506,26 @@ "@redis/graph": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.0.1.tgz", - "integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==" + "integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==", + "requires": {} }, "@redis/json": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.3.tgz", - "integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==" + "integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==", + "requires": {} }, "@redis/search": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.0.6.tgz", - "integrity": "sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==" + "integrity": "sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==", + "requires": {} }, "@redis/time-series": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz", - "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==" + "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==", + "requires": {} }, "@sideway/address": { "version": "4.1.4", @@ -12439,25 +12578,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "devOptional": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "devOptional": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "devOptional": true }, "@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "devOptional": true }, "@types/babel__core": { "version": "7.1.19", @@ -13057,7 +13196,7 @@ "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true + "devOptional": true }, "acorn-globals": { "version": "6.0.0", @@ -13081,13 +13220,15 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true + "dev": true, + "requires": {} }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -13200,7 +13341,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "devOptional": true }, "argparse": { "version": "2.0.1", @@ -13525,6 +13666,36 @@ "p-timeout": "^3.2.0", "semver": "^7.3.2", "uuid": "^8.3.0" + }, + "dependencies": { + "denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + }, + "ioredis": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", + "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "requires": { + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.isarguments": "^3.1.0", + "p-map": "^2.1.0", + "redis-commands": "1.7.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + } } }, "busboy": { @@ -13997,7 +14168,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "devOptional": true }, "cron-parser": { "version": "4.5.0", @@ -14126,9 +14297,11 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "optional": true, + "peer": true }, "depd": { "version": "2.0.0", @@ -14160,7 +14333,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "devOptional": true }, "diff-sequences": { "version": "27.5.1", @@ -14213,6 +14386,11 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz", "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==" }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -14293,7 +14471,8 @@ "ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} } } }, @@ -14411,9 +14590,9 @@ } }, "eslint": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.19.0.tgz", - "integrity": "sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", + "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", "dev": true, "requires": { "@eslint/eslintrc": "^1.3.0", @@ -14512,7 +14691,8 @@ "version": "8.5.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-prettier": { "version": "4.2.1", @@ -14624,6 +14804,20 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, + "event-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", + "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", + "requires": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -14995,6 +15189,11 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + }, "fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -15353,28 +15552,21 @@ "dev": true }, "ioredis": { - "version": "4.28.5", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", - "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.2.2.tgz", + "integrity": "sha512-wryKc1ur8PcCmNwfcGkw5evouzpbDXxxkMkzPK8wl4xQfQf7lHe11Jotell5ikMVAtikXJEu/OJVaoV51BggRQ==", + "optional": true, + "peer": true, "requires": { + "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", - "debug": "^4.3.1", - "denque": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.0.1", "lodash.defaults": "^4.2.0", - "lodash.flatten": "^4.4.0", "lodash.isarguments": "^3.1.0", - "p-map": "^2.1.0", - "redis-commands": "1.7.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" - }, - "dependencies": { - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" - } } }, "ipaddr.js": { @@ -15919,7 +16111,8 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "27.5.1", @@ -16576,6 +16769,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" + }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -16757,7 +16955,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "devOptional": true }, "makeerror": { "version": "1.0.12", @@ -16768,6 +16966,11 @@ "tmpl": "1.0.5" } }, + "map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==" + }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -16848,6 +17051,11 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "mingo": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/mingo/-/mingo-1.3.3.tgz", + "integrity": "sha512-Y4wGTD/M7AMqF8QxKaBGps+axq/Z48hdtRAeiKtInkEXMLzUWUwT0OPDzrB26xrav9GF1AOYJfwVWPcLwnkgTA==" + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -17306,6 +17514,14 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "requires": { + "through": "~2.3" + } + }, "pg": { "version": "8.7.3", "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz", @@ -17333,7 +17549,8 @@ "pg-pool": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz", - "integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==" + "integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==", + "requires": {} }, "pg-protocol": { "version": "1.5.0", @@ -17731,13 +17948,18 @@ } }, "rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", + "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", "requires": { "tslib": "^2.1.0" } }, + "rxjs-compat": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz", + "integrity": "sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw==" + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -17753,6 +17975,17 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "save": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/save/-/save-2.5.0.tgz", + "integrity": "sha512-xiVLpKVbx8EmW0HDkNRjYL271OnIRCo8VGWAEq6/K+E0dgNrwKV2xvKXdfPj6HGYA6l760800LyewSY3ooljCg==", + "requires": { + "async": "^3.2.2", + "event-stream": "^4.0.1", + "lodash.assign": "^4.2.0", + "mingo": "1" + } + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -17794,7 +18027,8 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "json-schema-traverse": { "version": "0.4.1", @@ -18037,6 +18271,14 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, "split2": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", @@ -18080,6 +18322,15 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "requires": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, "stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", @@ -18373,8 +18624,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "tmp": { "version": "0.0.33", @@ -18491,10 +18741,10 @@ } }, "ts-node": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", - "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", - "dev": true, + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "devOptional": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -18515,7 +18765,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true + "devOptional": true } } }, @@ -18709,7 +18959,7 @@ "version": "4.7.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true + "devOptional": true }, "universalify": { "version": "2.0.0", @@ -18775,7 +19025,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "devOptional": true }, "v8-to-istanbul": { "version": "8.1.1", @@ -19059,7 +19309,8 @@ "version": "7.5.8", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", - "dev": true + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", @@ -19131,7 +19382,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "devOptional": true } } } diff --git a/package.json b/package.json index e35defd..9894771 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,12 @@ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", "prepare": "husky install", - "lint-staged": "lint-staged" + "lint-staged": "lint-staged", + "typeorm": "ts-node ./node_modules/typeorm/cli", + "typeorm:run-migrations": "npm run typeorm migration:run -- -d ./src/database/migrations/typeOrm.config.ts", + "typeorm:generate-migration": "npm run typeorm -- -d ./src/database/migrations/typeOrm.config.ts migration:generate ./src/database/migrations/$npm_config_name", + "typeorm:create-migration": "npm run typeorm -- migration:create ./src/database/migrations/$npm_config_name", + "typeorm:revert-migration": "npm run typeorm -- -d ./src/database/migrations/typeOrm.config.ts migration:revert" }, "dependencies": { "@nestjs/axios": "^0.1.0", @@ -57,6 +62,7 @@ "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0", + "save": "^2.5.0", "swagger-ui-express": "^4.4.0", "typeorm": "^0.3.7", "uuid": "^8.3.2", @@ -82,7 +88,7 @@ "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "codecov": "^3.8.3", - "eslint": "^8.0.1", + "eslint": "^8.20.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^4.0.0", "husky": "^8.0.1", @@ -93,7 +99,7 @@ "supertest": "^6.1.3", "ts-jest": "^27.0.3", "ts-loader": "^9.2.3", - "ts-node": "^10.0.0", + "ts-node": "^10.9.1", "tsconfig-paths": "^3.10.1", "typescript": "^4.3.5" }, diff --git a/src/common/consts/enum.ts b/src/common/consts/enum.ts index f345b6a..bafcd8a 100644 --- a/src/common/consts/enum.ts +++ b/src/common/consts/enum.ts @@ -27,7 +27,10 @@ enum OrderStatus { enum TicketStatus { DONE = '입장완료', - WAIT = '입장대기' + // 원래 WAIT = "입장대기" 였음 ENTERWAIT이라고 생각하면될듯 + ENTERWAIT = '입금확인', + ORDERWAIT = '확인대기', + EXPIRE = '기한만료' } enum JWTType { diff --git a/src/common/pipes/orderId-validation.pipe.ts b/src/common/pipes/orderId-validation.pipe.ts new file mode 100644 index 0000000..2def576 --- /dev/null +++ b/src/common/pipes/orderId-validation.pipe.ts @@ -0,0 +1,10 @@ +import { PipeTransform } from '@nestjs/common'; + +export class OrderIdValidationPipe implements PipeTransform { + + transform(value: any) { + value = value - 10000; + return value; + } + +} \ No newline at end of file diff --git a/src/common/pipes/ticket-status-validation.pipe.ts b/src/common/pipes/ticket-status-validation.pipe.ts index 8881c2f..7822fd9 100644 --- a/src/common/pipes/ticket-status-validation.pipe.ts +++ b/src/common/pipes/ticket-status-validation.pipe.ts @@ -3,7 +3,7 @@ import e from 'express'; import { TicketStatus } from '../consts/enum'; export class TicketStatusValidationPipe implements PipeTransform { - readonly StatusOptions = [TicketStatus.DONE, TicketStatus.WAIT]; + readonly StatusOptions = [TicketStatus.DONE, TicketStatus.ENTERWAIT]; transform(value: any) { if (typeof value === 'object') { diff --git a/src/database/entities/comment.entity.ts b/src/database/entities/comment.entity.ts index cdeb12a..c1999ed 100644 --- a/src/database/entities/comment.entity.ts +++ b/src/database/entities/comment.entity.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Exclude, Expose, Transform } from 'class-transformer'; -import { Role } from 'src/common/consts/enum'; +import { Role } from '../../common/consts/enum'; import { Column, diff --git a/src/database/entities/order.entity.ts b/src/database/entities/order.entity.ts index 5a72af0..d02d823 100644 --- a/src/database/entities/order.entity.ts +++ b/src/database/entities/order.entity.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger'; import { Expose, Transform, Type } from 'class-transformer'; import { MaxLength } from 'class-validator'; -import { OrderStatus, OrderDate } from 'src/common/consts/enum'; -import { UserProfileDto } from 'src/common/dtos/user-profile.dto'; +import { OrderStatus, OrderDate } from '../../common/consts/enum'; +import { UserProfileDto } from '../../common/dtos/user-profile.dto'; import { Column, CreateDateColumn, diff --git a/src/database/entities/ticket.entity.ts b/src/database/entities/ticket.entity.ts index 5109d99..54f27fa 100644 --- a/src/database/entities/ticket.entity.ts +++ b/src/database/entities/ticket.entity.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Exclude, Expose, Type } from 'class-transformer'; -import { PerformanceDate, TicketStatus } from 'src/common/consts/enum'; +import { PerformanceDate, TicketStatus } from '../../common/consts/enum'; import { AfterLoad, BeforeInsert, @@ -16,7 +16,7 @@ import { import { Order } from './order.entity'; import { User } from './user.entity'; import { nanoid } from 'nanoid'; -import { UserProfileDto } from 'src/common/dtos/user-profile.dto'; +import { UserProfileDto } from '../../common/dtos/user-profile.dto'; @Entity() export class Ticket { @@ -55,7 +55,7 @@ export class Ticket { @Column({ type: 'enum', enum: TicketStatus, - default: TicketStatus.WAIT + default: TicketStatus.ORDERWAIT }) public status: TicketStatus; diff --git a/src/database/entities/user.entity.ts b/src/database/entities/user.entity.ts index 774f157..5884b72 100644 --- a/src/database/entities/user.entity.ts +++ b/src/database/entities/user.entity.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Exclude, Expose } from 'class-transformer'; -import { Role } from 'src/common/consts/enum'; +import { Role } from '../../common/consts/enum'; import { Column, CreateDateColumn, diff --git a/src/database/migrations/1658837628780-TicketStatusAddEnum.ts b/src/database/migrations/1658837628780-TicketStatusAddEnum.ts new file mode 100644 index 0000000..e98139b --- /dev/null +++ b/src/database/migrations/1658837628780-TicketStatusAddEnum.ts @@ -0,0 +1,78 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class TicketStatusAddEnum1658837628780 implements MigrationInterface { + name = 'TicketStatusAddEnum1658837628780'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TYPE "public"."ticket_status_enum" RENAME TO "ticket_status_enum_old"` + ); + + await queryRunner.query( + `CREATE TYPE "public"."ticket_status_enum_migration" AS ENUM('입장완료', '입금확인', '확인대기', '기한만료' ,'입장대기')` + ); + await queryRunner.query( + `CREATE TYPE "public"."ticket_status_enum" AS ENUM('입장완료', '입금확인', '확인대기', '기한만료' )` + ); + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" DROP DEFAULT` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" TYPE "public"."ticket_status_enum_migration" USING "status"::"text"::"public"."ticket_status_enum_migration"` + ); + await queryRunner.query( + `UPDATE "ticket" + SET status = '확인대기' + WHERE status = '입장대기' ;` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" TYPE "public"."ticket_status_enum" USING "status"::"text"::"public"."ticket_status_enum"` + ); + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" SET DEFAULT '확인대기'` + ); + + await queryRunner.query(`DROP TYPE "public"."ticket_status_enum_old"`); + await queryRunner.query( + `DROP TYPE "public"."ticket_status_enum_migration"` + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."ticket_status_enum_old" AS ENUM('입장완료', '입장대기')` + ); + await queryRunner.query( + `CREATE TYPE "public"."ticket_status_enum_migration" AS ENUM('입장완료', '입금확인', '확인대기', '기한만료' ,'입장대기')` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" DROP DEFAULT` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" TYPE "public"."ticket_status_enum_migration" USING "status"::"text"::"public"."ticket_status_enum_migration"` + ); + await queryRunner.query( + `UPDATE "ticket" + SET status = '입장대기' + WHERE status IN('확인대기', '기한만료' ,'입장대기') ;` + ); + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" TYPE "public"."ticket_status_enum_old" USING "status"::"text"::"public"."ticket_status_enum_old"` + ); + + await queryRunner.query( + `ALTER TABLE "ticket" ALTER COLUMN "status" SET DEFAULT '입장대기'` + ); + await queryRunner.query(`DROP TYPE "public"."ticket_status_enum"`); + await queryRunner.query( + `DROP TYPE "public"."ticket_status_enum_migration"` + ); + await queryRunner.query( + `ALTER TYPE "public"."ticket_status_enum_old" RENAME TO "ticket_status_enum"` + ); + } +} diff --git a/src/database/migrations/1658841312873-TicketUuidToVARCHAR.ts b/src/database/migrations/1658841312873-TicketUuidToVARCHAR.ts new file mode 100644 index 0000000..eef017c --- /dev/null +++ b/src/database/migrations/1658841312873-TicketUuidToVARCHAR.ts @@ -0,0 +1,19 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class TicketUuidToVARCHAR1658841312873 implements MigrationInterface { + name = 'migrations1658841312873'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "ticket" DROP COLUMN "uuid"`); + await queryRunner.query( + `ALTER TABLE "ticket" ADD "uuid" character varying(14) NOT NULL` + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "ticket" DROP COLUMN "uuid"`); + await queryRunner.query( + `ALTER TABLE "ticket" ADD "uuid" uuid NOT NULL DEFAULT uuid_generate_v4()` + ); + } +} diff --git a/src/database/migrations/typeOrm.config.ts b/src/database/migrations/typeOrm.config.ts new file mode 100644 index 0000000..b22613a --- /dev/null +++ b/src/database/migrations/typeOrm.config.ts @@ -0,0 +1,23 @@ +import 'reflect-metadata'; +import { DataSource } from 'typeorm'; +import { ConfigService } from '@nestjs/config'; +import { config } from 'dotenv'; +import { Ticket } from '../entities/ticket.entity'; +import { Order } from '../entities/order.entity'; +import { User } from '../entities/user.entity'; +import { Comment } from '../entities/comment.entity'; +import { TicketStatusAddEnum1658837628780 } from './1658837628780-TicketStatusAddEnum'; + +config(); + +const configService = new ConfigService(); +console.log(configService.get('POSTGRES_HOST')); +export default new DataSource({ + type: 'postgres', + host: configService.get('POSTGRES_HOST'), + port: configService.get('POSTGRES_PORT'), + username: configService.get('POSTGRES_USER'), + password: configService.get('POSTGRES_PASSWORD'), + entities: [Ticket, Order, User, Comment], + migrations: [TicketStatusAddEnum1658837628780] +}); diff --git a/src/database/repositories/order.repository.ts b/src/database/repositories/order.repository.ts new file mode 100644 index 0000000..e4440ba --- /dev/null +++ b/src/database/repositories/order.repository.ts @@ -0,0 +1,50 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; +import { Repository } from 'typeorm'; +import { Order } from '../entities/order.entity'; +import { User } from '../entities/user.entity'; + +@Injectable() +export class OrderRepository { + constructor( + @InjectRepository(Order) + private orderRepository: Repository + ) {} + + /** + * 주문을 생성한다 + * @param requestOrderDto {selection, ticketCount} + * @param user Request User + * @param totalPrice 총 입금할 금액 + * @returns 생성된 주문 + */ + async createOrder( + requestOrderDto: RequestOrderDto, + user: User, + totalPrice: number + ): Promise { + const { selection, ticketCount } = requestOrderDto; + const order = this.orderRepository.create({ + selection, + ticketCount, + price: totalPrice, + user: user, + isFree: false + }); + await this.orderRepository.save(order); + return order; + } + + /** + * + * @param userId 해당 유저의 주문 목록을 가져온다 + * @returns Order배열 + */ + async findAllByUserId(userId: number): Promise { + return await this.orderRepository + .createQueryBuilder('order') + .where({ user: userId }) + .getMany(); + } +} diff --git a/src/database/repositories/ticket.repository.ts b/src/database/repositories/ticket.repository.ts index 7f806fc..24c26c3 100644 --- a/src/database/repositories/ticket.repository.ts +++ b/src/database/repositories/ticket.repository.ts @@ -31,7 +31,8 @@ export class TicketRepository { const ticket = await this.ticketRepository.findOne({ where: { id: ticketId - } + }, + relations: ['user'] }); if (!ticket) { @@ -132,6 +133,18 @@ export class TicketRepository { .getMany(); } + /** + * + * @param orderId 조회할 주문id + * @returns 해당 주문에 속한 Ticket 배열 + */ + async findAllByOrderId(orderId: number): Promise { + return await this.ticketRepository + .createQueryBuilder('ticket') + .where({ order: orderId }) + .getMany(); + } + /** * 해당 티켓을 저장한다 * @param ticket 저장할 티켓 @@ -150,8 +163,6 @@ export class TicketRepository { async createTicket(createTicketDto: CreateTicketDto): Promise { const { user, order, date } = createTicketDto; - //order = orderRepository.findOne(order) - const ticket = this.ticketRepository.create({ date: date, user: user, diff --git a/src/orders/dtos/request-order.dto.ts b/src/orders/dtos/request-order.dto.ts new file mode 100644 index 0000000..b86a2c0 --- /dev/null +++ b/src/orders/dtos/request-order.dto.ts @@ -0,0 +1,18 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { Expose } from "class-transformer"; +import { IsEnum, IsIn, IsNotEmpty, isNotEmpty, IsNumber } from "class-validator"; +import { Order } from "src/database/entities/order.entity"; +import { OrderDate } from "../../common/consts/enum"; + +export class RequestOrderDto { + @ApiProperty({ description: '공연일자', enum: OrderDate }) + @IsEnum(OrderDate) + @Expose() + selection: OrderDate; + + @ApiProperty({ description: '티켓수량', type: Number }) + @IsNumber() + @IsIn([1,2,3]) + @Expose() + ticketCount: number; +} \ No newline at end of file diff --git a/src/orders/orders.controller.ts b/src/orders/orders.controller.ts new file mode 100644 index 0000000..f18d72f --- /dev/null +++ b/src/orders/orders.controller.ts @@ -0,0 +1,95 @@ +import { + Body, + Controller, + Get, + Param, + Post, + UseGuards, + UsePipes, + ValidationPipe +} from '@nestjs/common'; +import { + ApiBearerAuth, + ApiOperation, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse +} from '@nestjs/swagger'; +import { AccessTokenGuard } from 'src/auth/guards/AccessToken.guard'; +import { ReqUser } from 'src/common/decorators/user.decorator'; +import { Order } from 'src/database/entities/order.entity'; +import { User } from 'src/database/entities/user.entity'; +import { OrdersService } from './orders.service'; +import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; +import { Ticket } from 'src/database/entities/ticket.entity'; +import { TicketsService } from 'src/tickets/tickets.service'; +import { OrderIdValidationPipe } from 'src/common/pipes/orderId-validation.pipe'; + +@ApiTags('orders') +@ApiBearerAuth('accessToken') +@Controller('orders') +@UseGuards(AccessTokenGuard) +export class OrdersController { + constructor( + private orderService: OrdersService, + private ticketService: TicketsService + ) {} + + @ApiOperation({ + summary: '주문을 생성하고, 해당 주문의 티켓을 생성한다.' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Order + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken 권한이 없을 경우' + }) + @Post('') + createOrder( + @Body() requestOrderDto: RequestOrderDto, + @ReqUser() user: User + ): Promise { + return this.orderService.createOrder(requestOrderDto, user); + } + + @ApiOperation({ + summary: '접근한 유저의 주문 목록을 불러온다' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Order, + isArray: true + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken이 없을 경우' + }) + @Get('') + getUserOrderList(@ReqUser() user: User): Promise { + return this.orderService.findAllByUserId(user.id); + } + + @ApiOperation({ + summary: '해당 주문에 속한 티켓 목록을 불러온다' + }) + @ApiResponse({ + status: 200, + description: '요청 성공시', + type: Ticket, + isArray: true + }) + @ApiUnauthorizedResponse({ + status: 401, + description: 'AccessToken이 없을 경우' + }) + @Get('/:orderId') + getTicketListByOrderId( + @Param('orderId', OrderIdValidationPipe) orderId: number + ): Promise { + return this.ticketService.findAllByOrderId(orderId); + } +} diff --git a/src/orders/orders.module.ts b/src/orders/orders.module.ts index 90c2cca..28221b1 100644 --- a/src/orders/orders.module.ts +++ b/src/orders/orders.module.ts @@ -1,4 +1,19 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Order } from 'src/database/entities/order.entity'; +import { OrderRepository } from 'src/database/repositories/order.repository'; +import { QueueModule } from 'src/queue/queue.module'; +import { TicketsModule } from 'src/tickets/tickets.module'; +import { OrdersController } from './orders.controller'; +import { OrdersService } from './orders.service'; -@Module({}) +@Module({ + imports: [ + TypeOrmModule.forFeature([Order]), + TicketsModule, + QueueModule, + ], + controllers: [OrdersController], + providers: [OrdersService, OrderRepository] +}) export class OrdersModule {} diff --git a/src/orders/orders.service.ts b/src/orders/orders.service.ts new file mode 100644 index 0000000..0e74b76 --- /dev/null +++ b/src/orders/orders.service.ts @@ -0,0 +1,127 @@ +import { + BadRequestException, + Injectable, + InternalServerErrorException +} from '@nestjs/common'; +import { RequestOrderDto } from 'src/orders/dtos/request-order.dto'; +import { Order } from 'src/database/entities/order.entity'; +import { User } from 'src/database/entities/user.entity'; +import { OrderRepository } from 'src/database/repositories/order.repository'; +import { OrderDate, PerformanceDate } from 'src/common/consts/enum'; +import { TicketsService } from 'src/tickets/tickets.service'; +import { DataSource } from 'typeorm'; +import { getConnectedRepository } from 'src/common/funcs/getConnectedRepository'; +import { TicketRepository } from 'src/database/repositories/ticket.repository'; +import { Ticket } from 'src/database/entities/ticket.entity'; +import e from 'express'; +import { QueueService } from 'src/queue/queue.service'; + +@Injectable() +export class OrdersService { + constructor( + private orderRepository: OrderRepository, + private ticketService: TicketsService, + private dataSource: DataSource, + private queueService: QueueService + ) {} + + // 가격 책정 함수 : 단지 가독성을 위해 함수로 뺌 + getTotalPrice(requestOrderDto: RequestOrderDto): number { + const { selection, ticketCount } = requestOrderDto; + const pricePerTicket = 3000; // 티켓 한 장 가격 + const discountForBoth = 1000; // 양일권에 대한 할인 가격 + + let totalPrice = pricePerTicket * ticketCount; + + if (selection === OrderDate.BOTH) { + // ticketCount = 양일권 개수 + totalPrice = totalPrice * 2 - discountForBoth * ticketCount; + } + return totalPrice; + } + + /** + * selection과 ticketCount를 요청받아서 가격 책정 후 주문을 생성하고, + * 해당 주문에 포함되는 모든 티켓을 각각 생성한다. + * @param requestOrderDto {selection, ticketCount} + * @param user Request User + * @returns Order + */ + async createOrder( + requestOrderDto: RequestOrderDto, + user: User + ): Promise { + const { selection, ticketCount } = requestOrderDto; + const totalPrice = this.getTotalPrice(requestOrderDto); // 가격 책정 + + // 양일권일 경우 요청수량 * 2 해서 저장 + if (selection === OrderDate.BOTH) { + requestOrderDto.ticketCount *= 2; + } + + const queryRunner = this.dataSource.createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); + + const connectedOrder = getConnectedRepository( + OrderRepository, + queryRunner, + Order + ); + const connectedTicket = getConnectedRepository( + TicketRepository, + queryRunner, + Ticket + ); + + try { + // 주문 생성 + const order = await connectedOrder.createOrder( + requestOrderDto, + user, + totalPrice + ); + + // ticketList에 생성할 티켓을 모두 담은 후 한번에 비동기요청 + const ticketList: any[] = []; + + for (let i = 0; i < ticketCount; i++) { + if (selection === OrderDate.BOTH || selection === OrderDate.YB) { + const createTicketDto = { + date: PerformanceDate.YB, + order, + user + }; + ticketList.push(createTicketDto); + } + if (selection === OrderDate.BOTH || selection === OrderDate.OB) { + const createTicketDto = { + date: PerformanceDate.OB, + order, + user + }; + ticketList.push(createTicketDto); + } + } + const ticketListForQ = await Promise.all( + ticketList.map(dto => { + return connectedTicket.createTicket(dto); + }) + ); + await this.queueService.createNewOrderJob(order); + await this.queueService.sendNaverSmsForOrderJob(order, ticketListForQ); + await queryRunner.commitTransaction(); + return order; + } catch (e) { + // 주문 생성 실패시 Error + await queryRunner.rollbackTransaction(); + throw e; + } finally { + await queryRunner.release(); + } + } + + async findAllByUserId(userId: number): Promise { + return await this.orderRepository.findAllByUserId(userId); + } +} diff --git a/src/queue/queue.consumer.sms.ts b/src/queue/queue.consumer.sms.ts new file mode 100644 index 0000000..ba4d5cb --- /dev/null +++ b/src/queue/queue.consumer.sms.ts @@ -0,0 +1,24 @@ +import { OnQueueFailed, Process, Processor } from '@nestjs/bull'; +import { Job } from 'bull'; +import { plainToInstance } from 'class-transformer'; +import { Err } from 'joi'; +import { MessageDto } from 'src/sms/dtos/message.dto'; +import { SmsService } from 'src/sms/sms.service'; + +@Processor('naverSmsQ') +export class QueueConsumerSms { + constructor(private smsService: SmsService) {} + + @OnQueueFailed() + errHandler(job: Job, err: Err) { + console.log(`error: ` + err); + throw err; + } + + @Process('sendNaverSmsForOrder') + async handleSmsForOrder(job: Job) { + const data = job.data; + const messageDtoList = plainToInstance(MessageDto, data as MessageDto[]); + await this.smsService.sendMessages(messageDtoList); + } +} diff --git a/src/queue/queue.consumer.ts b/src/queue/queue.consumer.ts new file mode 100644 index 0000000..dc0ba4c --- /dev/null +++ b/src/queue/queue.consumer.ts @@ -0,0 +1,27 @@ +import { OnQueueFailed, Process, Processor } from '@nestjs/bull'; +import { Job } from 'bull'; +import { Err } from 'joi'; +import { SlackService } from 'src/slack/slack.service'; + +@Processor('slackAlarmQ') +export class QueueConsumer { + constructor(private slackService: SlackService) {} + + @OnQueueFailed() + errHandler(job: Job, err: Err) { + console.log('error: ' + err); + throw err; + } + + @Process('updateTicketStatus') + async handleUpdateTicketStatus(job: Job) { + const ticketStatusChangeDto = job.data; + await this.slackService.ticketQREnterEvent(ticketStatusChangeDto); + } + + @Process('createNewOrder') + async handleCreateNewOrder(job: Job) { + const newOrderDto = job.data; + await this.slackService.newOrderAlarm(newOrderDto); + } +} diff --git a/src/queue/queue.module.ts b/src/queue/queue.module.ts index ef5d4e2..170086b 100644 --- a/src/queue/queue.module.ts +++ b/src/queue/queue.module.ts @@ -1,18 +1,33 @@ import { BullModule } from '@nestjs/bull'; import { Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { SlackModule } from 'src/slack/slack.module'; +import { SmsModule } from 'src/sms/sms.module'; + +import { QueueConsumer } from './queue.consumer'; +import { QueueConsumerSms } from './queue.consumer.sms'; import { QueueService } from './queue.service'; @Module({ imports: [ BullModule.registerQueue( { - name: 'test' + name: 'slackAlarmQ' }, { - name: 'test2' + name: 'naverSmsQ' } - ) + ), + SmsModule.forRootAsync({ + imports: [ConfigModule], + useFactory: async (configService: ConfigService) => ({ + isProd: configService.get('NODE_ENV') === 'prod' ? true : false + }), + inject: [ConfigService] + }), + SlackModule ], - providers: [QueueService] + providers: [QueueService, QueueConsumer, QueueConsumerSms], + exports: [QueueService] }) export class QueueModule {} diff --git a/src/queue/queue.service.ts b/src/queue/queue.service.ts index dc8efe7..356a23d 100644 --- a/src/queue/queue.service.ts +++ b/src/queue/queue.service.ts @@ -1,4 +1,59 @@ +import { InjectQueue } from '@nestjs/bull'; import { Injectable } from '@nestjs/common'; +import { Queue } from 'bull'; +import { OrderDate, PerformanceDate } from 'src/common/consts/enum'; +import { Order } from 'src/database/entities/order.entity'; +import { Ticket } from 'src/database/entities/ticket.entity'; +import { User } from 'src/database/entities/user.entity'; @Injectable() -export class QueueService {} +export class QueueService { + constructor( + @InjectQueue('slackAlarmQ') private slackAlarmQ: Queue, + @InjectQueue('naverSmsQ') private naverSmsQ: Queue + ) {} + + async updateTicketStatusJob(ticket: Ticket, admin: User) { + console.log('admin: ' + admin.name); + console.log(ticket); + const job = await this.slackAlarmQ.add('updateTicketStatus', { + adminName: admin.name, + ticketId: ticket.id, + userName: ticket.user.name + }); + return job; + } + + async createNewOrderJob(order: Order) { + console.log('order: ' + order.id); + const job = await this.slackAlarmQ.add('createNewOrder', { + orderId: order.id, + userName: order.user.name, + orderTicketCount: order.ticketCount, + orderPrice: order.price + }); + return job; + } + + async sendNaverSmsForOrderJob(order: Order, ticketList: Ticket[]) { + const url = 'https://gosrock.band/tickets/'; + let obIdx = 1; + let ybIdx = 1; + const totalTicketCnt = order.selection == OrderDate.BOTH ? order.ticketCount/2 : order.ticketCount + const messageDtoList = ticketList.map(ticket => { + switch (ticket.date) { + case PerformanceDate.OB: + return { + to: order.user.phoneNumber, + content: `[${ticket.date}] 고티켓 (${obIdx++}/${totalTicketCnt}) \n\n ${url}${ticket.uuid}` + }; + case PerformanceDate.YB: + return { + to: order.user.phoneNumber, + content: `[${ticket.date}] 고티켓 (${ybIdx++}/${totalTicketCnt}) \n\n ${url}${ticket.uuid}` + }; + } + }); + await this.naverSmsQ.add('sendNaverSmsForOrder', messageDtoList); + } +} diff --git a/src/slack/slack.module.ts b/src/slack/slack.module.ts index d5cd69f..6b879d3 100644 --- a/src/slack/slack.module.ts +++ b/src/slack/slack.module.ts @@ -27,8 +27,7 @@ import { SlackFakeService } from './slackFake.service'; providers: [ { provide: SlackService, - useClass: - process.env.NODE_ENV === 'prod' ? SlackService : SlackFakeService + useClass: process.env.NODE_ENV === 'prod' ? SlackService : SlackFakeService }, { provide: ADMIN_CHANNELID, diff --git a/src/slack/slack.service.spec.ts b/src/slack/slack.service.spec.ts index 598b661..b53055a 100644 --- a/src/slack/slack.service.spec.ts +++ b/src/slack/slack.service.spec.ts @@ -76,7 +76,12 @@ describe('SlackService', () => { it('관리자가 티켓의 상태를 변경하면 알림이 가야합니다.', async () => { const value = await service.ticketStateChangedByAdminEvent( - new SlackTicketStateChangeDto(1, '테스트', TicketStatus.WAIT, '테스트2') + new SlackTicketStateChangeDto( + 1, + '테스트', + TicketStatus.ENTERWAIT, + '테스트2' + ) ); console.log(value); expect(value).toBeDefined(); diff --git a/src/slack/slack.service.ts b/src/slack/slack.service.ts index 8c191c3..8a2c431 100644 --- a/src/slack/slack.service.ts +++ b/src/slack/slack.service.ts @@ -161,6 +161,8 @@ export class SlackService { async newOrderAlarm(slackNewOrderDto: SlackNewOrderDto) { const { orderId, userName, orderTicketCount, orderPrice } = slackNewOrderDto; + console.log('통과:' + orderId); + console.log('') try { const value = await lastValueFrom( this.httpService diff --git a/src/slack/slackFake.service.ts b/src/slack/slackFake.service.ts index 0f93325..3bae8b5 100644 --- a/src/slack/slackFake.service.ts +++ b/src/slack/slackFake.service.ts @@ -17,29 +17,69 @@ import { export class SlackFakeService { constructor() {} - async findSlackUserIdByEmail(email: string) {} + async findSlackUserIdByEmail(email: string) { + Logger.log( + 'findSlackUserIdByEmail' + JSON.stringify(email), + 'SlackFakeService' + ); + } async sendDMwithValidationNumber( slackValidationNumberDMDto: SlackValidationNumberDMDto - ) {} + ) { + Logger.log( + 'sendDMwithValidationNumber' + JSON.stringify(slackValidationNumberDMDto), + 'SlackFakeService' + ); + } async orderStateChangedByAdminEvent( slackOrderStateChangeDto: SlackOrderStateChangeDto - ) {} + ) { + Logger.log( + 'orderStateChangedByAdminEvent' + + JSON.stringify(slackOrderStateChangeDto), + 'SlackFakeService' + ); + } - async newOrderAlarm(slackNewOrderDto: SlackNewOrderDto) {} + async newOrderAlarm(slackNewOrderDto: SlackNewOrderDto) { + Logger.log( + 'newOrderAlarm' + JSON.stringify(slackNewOrderDto), + 'SlackFakeService' + ); + } async ticketStateChangedByAdminEvent( slackTicketStateChangeDto: SlackTicketStateChangeDto - ) {} + ) { + Logger.log( + 'ticketStateChangedByAdminEvent' + + JSON.stringify(slackTicketStateChangeDto), + 'SlackFakeService' + ); + } async ticketQREnterEvent( slackTicketQREnterEventDto: SlackTicketQREnterEventDto - ) {} + ) { + Logger.log( + 'ticketQREnterEvent' + JSON.stringify(slackTicketQREnterEventDto), + 'SlackFakeService' + ); + } async backendInternelServerError( path: string, body: string, errorStack: string | undefined - ) {} + ) { + Logger.log( + 'backendInternelServerError' + + JSON.stringify(path) + + JSON.stringify(body) + + JSON.stringify(errorStack), + 'SlackFakeService' + ); + } } diff --git a/src/sms/sms.service.ts b/src/sms/sms.service.ts index 3cda910..a926c2a 100644 --- a/src/sms/sms.service.ts +++ b/src/sms/sms.service.ts @@ -26,7 +26,6 @@ export class SmsService { const signature = this.makeSignature(serviceId, 'POST', date); Logger.log('실제 문자메시지 전송' + JSON.stringify(messages), 'SmsService'); - try { const data = await lastValueFrom( this.httpService diff --git a/src/socket/socket-admin.gateway.ts b/src/socket/socket-admin.gateway.ts index 343d938..6a40cc2 100644 --- a/src/socket/socket-admin.gateway.ts +++ b/src/socket/socket-admin.gateway.ts @@ -1,4 +1,4 @@ -import { Logger, UnauthorizedException, UseGuards } from '@nestjs/common'; +import { Logger, UnauthorizedException } from '@nestjs/common'; import { ConnectedSocket, OnGatewayConnection, @@ -10,8 +10,6 @@ import { import { Namespace, Server, Socket } from 'socket.io'; import { AuthService } from 'src/auth/auth.service'; import { Role } from 'src/common/consts/enum'; -import { Roles } from 'src/common/decorators/roles.decorator'; -import { SocketGuard } from './socket.guard'; // @UseGuards(SocketGuard) // @Roles(Role.Admin) diff --git a/src/socket/socket.service.ts b/src/socket/socket.service.ts index 88f4d89..9cc63bd 100644 --- a/src/socket/socket.service.ts +++ b/src/socket/socket.service.ts @@ -35,4 +35,10 @@ export class SocketService { throw new GatewayTimeoutException('소켓 서버에 연결할 수 없습니다'); } } + + //양쪽 + async emitToAll(ticketEntryResponseDto: TicketEntryResponseDto) { + await this.emitToUser(ticketEntryResponseDto); + await this.emitToAdmin(ticketEntryResponseDto); + } } diff --git a/src/tickets/dtos/create-ticket.dto.ts b/src/tickets/dtos/create-ticket.dto.ts index 9ecfcbb..0df8fbb 100644 --- a/src/tickets/dtos/create-ticket.dto.ts +++ b/src/tickets/dtos/create-ticket.dto.ts @@ -5,9 +5,7 @@ import { Ticket } from 'src/database/entities/ticket.entity'; export class CreateTicketDto extends PickType(PartialType(Ticket), [ 'date', 'order', - 'user', - 'createdAt', - 'updatedAt' + 'user' ] as const) { // @ApiProperty({ // description: '주문한 유저에 대한 정보입니다.', diff --git a/src/tickets/dtos/update-ticket-status.dto.ts b/src/tickets/dtos/update-ticket-status.dto.ts index 0cbff18..4295976 100644 --- a/src/tickets/dtos/update-ticket-status.dto.ts +++ b/src/tickets/dtos/update-ticket-status.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Expose } from 'class-transformer'; -import { IsEnum, IsNumber, IsString } from 'class-validator'; +import { IsEnum, IsNumber } from 'class-validator'; import { TicketStatus } from 'src/common/consts/enum'; export class UpdateTicketStatusDto { diff --git a/src/tickets/tickets.module.ts b/src/tickets/tickets.module.ts index 1a496d8..28d47f8 100644 --- a/src/tickets/tickets.module.ts +++ b/src/tickets/tickets.module.ts @@ -3,6 +3,9 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { Ticket } from 'src/database/entities/ticket.entity'; import { TicketRepository } from 'src/database/repositories/ticket.repository'; import { SocketModule } from 'src/socket/socket.module'; +import { UserRepository } from 'src/database/repositories/user.repository'; +import { QueueModule } from 'src/queue/queue.module'; +import { QueueService } from 'src/queue/queue.service'; import { UsersModule } from 'src/users/users.module'; import { TicketsController } from './tickets.controller'; import { TicketsService } from './tickets.service'; @@ -11,7 +14,8 @@ import { TicketsService } from './tickets.service'; imports: [ TypeOrmModule.forFeature([Ticket]), SocketModule, - UsersModule //삭제예정 + UsersModule, //삭제예정, + QueueModule ], providers: [ TicketsService, diff --git a/src/tickets/tickets.service.ts b/src/tickets/tickets.service.ts index 6afaea5..af22bab 100644 --- a/src/tickets/tickets.service.ts +++ b/src/tickets/tickets.service.ts @@ -16,6 +16,8 @@ import { Ticket } from 'src/database/entities/ticket.entity'; import { User } from 'src/database/entities/user.entity'; import { TicketRepository } from 'src/database/repositories/ticket.repository'; import { SocketService } from 'src/socket/socket.service'; +import { UserRepository } from 'src/database/repositories/user.repository'; +import { QueueService } from 'src/queue/queue.service'; import { DataSource } from 'typeorm'; import { CreateTicketDto } from './dtos/create-ticket.dto'; import { TicketEntryResponseDto } from './dtos/ticket-entry-response.dto'; @@ -28,7 +30,8 @@ export class TicketsService { constructor( private ticketRepository: TicketRepository, private socketService: SocketService, - private dataSource: DataSource + private dataSource: DataSource, + private queueService: QueueService ) {} async findById(ticketId: number): Promise { @@ -71,6 +74,10 @@ export class TicketsService { return await this.ticketRepository.findAllByUserId(userId); } + async findAllByOrderId(orderId: number): Promise { + return await this.ticketRepository.findAllByOrderId(orderId); + } + async findAllWith( ticketFindDto: TicketFindDto, pageOptionsDto: PageOptionsDto @@ -114,25 +121,21 @@ export class TicketsService { ticket, admin.name, false, - '[입장실패] - 공연 날짜가 일치하지 않습니다' + '[입장실패] 공연 날짜가 일치하지 않습니다' ); - this.logger.error('티켓 날짜 오류 - 공연 날짜가 일치하지 않습니다'); - this.socketService.emitToUser(failureResponse); - this.socketService.emitToAdmin(failureResponse); + this.socketService.emitToAll(failureResponse); throw new BadRequestException('공연 날짜가 일치하지 않습니다'); } // 티켓 상태 오류('입장대기'가 아님) - if (ticket.status !== TicketStatus.WAIT) { + if (ticket.status !== TicketStatus.ENTERWAIT) { const failureResponse = new TicketEntryResponseDto( ticket, admin.name, false, - '[입장실패] - 이미 입장 완료된 티켓입니다' + '[입장실패] 이미 입장 완료된 티켓입니다' ); - this.logger.error('티켓 상태 오류 - 이미 입장 완료된 티켓입니다'); - this.socketService.emitToUser(failureResponse); - this.socketService.emitToAdmin(failureResponse); + this.socketService.emitToAll(failureResponse); throw new BadRequestException('이미 입장 완료된 티켓입니다'); } @@ -150,18 +153,14 @@ export class TicketsService { true, `[입장성공] ${ticket.user?.name}님이 입장하셨습니다` ); - - this.socketService.emitToUser(successResponse); - this.socketService.emitToAdmin(successResponse); + this.logger.log(`${ticket.user?.name}님이 입장하셨습니다`); + this.socketService.emitToAll(successResponse); return successResponse; } catch (e) { await queryRunner.rollbackTransaction(); - + this.logger.error(`티켓 상태 오류 - ${e.message}`); // 내부 예외 그대로 던짐 - if (e) { - throw e; - } - throw new InternalServerErrorException('Ticket db 에러'); + throw e; } finally { await queryRunner.release(); } @@ -196,12 +195,11 @@ export class TicketsService { ticket.admin = admin; await connectedRepository.saveTicket(ticket); - + await this.queueService.updateTicketStatusJob(ticket, admin); await queryRunner.commitTransaction(); return ticket; } catch (e) { await queryRunner.rollbackTransaction(); - //티켓 찾을때 Not Found Error 캐치 if (e) { throw e; @@ -217,7 +215,8 @@ export class TicketsService { * @param createTicketDto 티켓 생성 dto */ async createTicket(createTicketDto: CreateTicketDto): Promise { - return await this.ticketRepository.createTicket(createTicketDto); + const result = await this.ticketRepository.createTicket(createTicketDto); + return result; } async deleteTicketByUuid(ticketUuid: string): Promise {