refactor: made the sms to use queue

This commit is contained in:
2026-07-31 18:46:21 +03:30
parent ac4e34436a
commit a4c50496c5
18 changed files with 306 additions and 73 deletions
+3
View File
@@ -22,6 +22,7 @@
"dependencies": {
"@keyv/redis": "^5.1.6",
"@nestjs/axios": "^4.0.1",
"@nestjs/bullmq": "^11.0.4",
"@nestjs/cache-manager": "^3.1.3",
"@nestjs/common": "^11.1.28",
"@nestjs/config": "^4.0.4",
@@ -33,9 +34,11 @@
"@nestjs/typeorm": "^11.0.3",
"axios": "^1.18.1",
"bcrypt": "^6.0.0",
"bullmq": "^5.81.3",
"cache-manager": "^7.2.9",
"class-transformer": "^0.5.1",
"class-validator": "^0.15.1",
"ioredis": "^5.11.1",
"joi": "^18.2.3",
"keyv": "^5.6.0",
"ms": "^2.1.3",
+215 -5
View File
@@ -14,6 +14,9 @@ importers:
'@nestjs/axios':
specifier: ^4.0.1
version: 4.0.1(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.18.1)(rxjs@7.8.2)
'@nestjs/bullmq':
specifier: ^11.0.4
version: 11.0.4(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(bullmq@5.81.3)
'@nestjs/cache-manager':
specifier: ^3.1.3
version: 3.1.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(cache-manager@7.2.9)(keyv@5.6.0)(rxjs@7.8.2)
@@ -40,13 +43,16 @@ importers:
version: 11.4.6(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)
'@nestjs/typeorm':
specifier: ^11.0.3
version: 11.0.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@1.1.0(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)))
version: 11.0.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@1.1.0(ioredis@5.11.1)(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)))
axios:
specifier: ^1.18.1
version: 1.18.1
bcrypt:
specifier: ^6.0.0
version: 6.0.0
bullmq:
specifier: ^5.81.3
version: 5.81.3
cache-manager:
specifier: ^7.2.9
version: 7.2.9
@@ -56,6 +62,9 @@ importers:
class-validator:
specifier: ^0.15.1
version: 0.15.1
ioredis:
specifier: ^5.11.1
version: 5.11.1
joi:
specifier: ^18.2.3
version: 18.2.3
@@ -82,7 +91,7 @@ importers:
version: 7.8.2
typeorm:
specifier: ^1.1.0
version: 1.1.0(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3))
version: 1.1.0(ioredis@5.11.1)(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3))
devDependencies:
'@eslint/eslintrc':
specifier: ^3.2.0
@@ -605,6 +614,9 @@ packages:
'@types/node':
optional: true
'@ioredis/commands@1.10.0':
resolution: {integrity: sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==}
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
@@ -737,6 +749,36 @@ packages:
'@microsoft/tsdoc@0.16.0':
resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==}
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4':
resolution: {integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==}
cpu: [arm64]
os: [darwin]
'@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4':
resolution: {integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==}
cpu: [x64]
os: [darwin]
'@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4':
resolution: {integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==}
cpu: [arm64]
os: [linux]
'@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4':
resolution: {integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==}
cpu: [arm]
os: [linux]
'@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4':
resolution: {integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==}
cpu: [x64]
os: [linux]
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4':
resolution: {integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==}
cpu: [x64]
os: [win32]
'@napi-rs/wasm-runtime@1.1.6':
resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==}
peerDependencies:
@@ -750,6 +792,19 @@ packages:
axios: ^1.3.1
rxjs: ^7.0.0
'@nestjs/bull-shared@11.0.4':
resolution: {integrity: sha512-VBJcDHSAzxQnpcDfA0kt9MTGUD1XZzfByV70su0W0eDCQ9aqIEBlzWRW21tv9FG9dIut22ysgDidshdjlnczLw==}
peerDependencies:
'@nestjs/common': ^10.0.0 || ^11.0.0
'@nestjs/core': ^10.0.0 || ^11.0.0
'@nestjs/bullmq@11.0.4':
resolution: {integrity: sha512-wBzK9raAVG0/6NTMdvLGM4/FQ1lsB35/pYS8L6a0SDgkTiLpd7mAjQ8R692oMx5s7IjvgntaZOuTUrKYLNfIkA==}
peerDependencies:
'@nestjs/common': ^10.0.0 || ^11.0.0
'@nestjs/core': ^10.0.0 || ^11.0.0
bullmq: ^3.0.0 || ^4.0.0 || ^5.0.0
'@nestjs/cache-manager@3.1.3':
resolution: {integrity: sha512-HMtiOfHz75NZX7mJn1VnZGLSachVI04TnUc5wvEogIaKwk5BDQHgtP5htxreizjv7oxKalJbuTyxtiF6bE+bgQ==}
peerDependencies:
@@ -1504,6 +1559,15 @@ packages:
buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
bullmq@5.81.3:
resolution: {integrity: sha512-Q7uEH2G92rVjX3Yl2qw3+6VEO15uxehC6DfeTHQBQTehddcRDSDuquD9zuvDjxiCffXsPUaBwrRlvlbVcgKs7g==}
engines: {node: '>=12.22.0'}
peerDependencies:
redis: '>=5.0.0'
peerDependenciesMeta:
redis:
optional: true
busboy@1.6.0:
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
engines: {node: '>=10.16.0'}
@@ -1598,6 +1662,10 @@ packages:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'}
cluster-key-slot@1.1.1:
resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==}
engines: {node: '>=0.10.0'}
cluster-key-slot@1.1.2:
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
engines: {node: '>=0.10.0'}
@@ -1683,6 +1751,10 @@ packages:
create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
cron-parser@4.9.0:
resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==}
engines: {node: '>=12.0.0'}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@@ -1721,10 +1793,18 @@ packages:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
denque@2.1.0:
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
engines: {node: '>=0.10'}
depd@2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
detect-libc@2.1.2:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
detect-newline@3.1.0:
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
engines: {node: '>=8'}
@@ -2177,6 +2257,10 @@ packages:
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
ioredis@5.11.1:
resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==}
engines: {node: '>=12.22.0'}
ipaddr.js@1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
@@ -2517,6 +2601,10 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
luxon@3.7.2:
resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==}
engines: {node: '>=12'}
magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
@@ -2603,6 +2691,13 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
msgpackr-extract@3.0.4:
resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==}
hasBin: true
msgpackr@2.0.5:
resolution: {integrity: sha512-cef05H/dSYpLpqp3sj/qyZh5vhUYCalnaLO7j1yOmpsR0y/XwLVtK7r5gn+U/F7CTEfMowcGhlUQJDLcLf7jcA==}
multer@2.2.0:
resolution: {integrity: sha512-6rdyFg2kLrMh9Jee7/BMPuV9lEAd7lLW2YUpF9/YxR7njyoUwwQ0ZPh3TaIY50Sw6vlyD2HW3wGOkTS4P79xrQ==}
engines: {node: '>= 10.16.0'}
@@ -2636,6 +2731,10 @@ packages:
node-emoji@1.11.0:
resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==}
node-gyp-build-optional-packages@5.2.2:
resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==}
hasBin: true
node-gyp-build@4.8.4:
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
hasBin: true
@@ -2893,6 +2992,14 @@ packages:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
redis-errors@1.2.0:
resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==}
engines: {node: '>=4'}
redis-parser@3.0.0:
resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==}
engines: {node: '>=4'}
reflect-metadata@0.2.2:
resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
@@ -3032,6 +3139,9 @@ packages:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}
standard-as-callback@2.1.0:
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
statuses@2.0.2:
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
engines: {node: '>= 0.8'}
@@ -3998,6 +4108,8 @@ snapshots:
optionalDependencies:
'@types/node': 22.20.1
'@ioredis/commands@1.10.0': {}
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
@@ -4240,6 +4352,24 @@ snapshots:
'@microsoft/tsdoc@0.16.0': {}
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4':
optional: true
'@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
dependencies:
'@emnapi/core': 1.10.0
@@ -4253,6 +4383,20 @@ snapshots:
axios: 1.18.1
rxjs: 7.8.2
'@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)':
dependencies:
'@nestjs/common': 11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)
tslib: 2.8.1
'@nestjs/bullmq@11.0.4(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(bullmq@5.81.3)':
dependencies:
'@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)
'@nestjs/common': 11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)
bullmq: 5.81.3
tslib: 2.8.1
'@nestjs/cache-manager@3.1.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(cache-manager@7.2.9)(keyv@5.6.0)(rxjs@7.8.2)':
dependencies:
'@nestjs/common': 11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
@@ -4400,13 +4544,13 @@ snapshots:
optionalDependencies:
'@nestjs/platform-express': 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)
'@nestjs/typeorm@11.0.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@1.1.0(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)))':
'@nestjs/typeorm@11.0.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@1.1.0(ioredis@5.11.1)(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)))':
dependencies:
'@nestjs/common': 11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)
reflect-metadata: 0.2.2
rxjs: 7.8.2
typeorm: 1.1.0(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3))
typeorm: 1.1.0(ioredis@5.11.1)(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3))
'@noble/hashes@1.8.0': {}
@@ -5085,6 +5229,17 @@ snapshots:
base64-js: 1.5.1
ieee754: 1.2.1
bullmq@5.81.3:
dependencies:
cron-parser: 4.9.0
ioredis: 5.11.1
msgpackr: 2.0.5
node-abort-controller: 3.1.1
semver: 7.8.5
tslib: 2.8.1
transitivePeerDependencies:
- supports-color
busboy@1.6.0:
dependencies:
streamsearch: 1.1.0
@@ -5169,6 +5324,8 @@ snapshots:
clone@1.0.4: {}
cluster-key-slot@1.1.1: {}
cluster-key-slot@1.1.2: {}
co@4.6.0: {}
@@ -5235,6 +5392,10 @@ snapshots:
create-require@1.1.1: {}
cron-parser@4.9.0:
dependencies:
luxon: 3.7.2
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
@@ -5259,8 +5420,13 @@ snapshots:
delayed-stream@1.0.0: {}
denque@2.1.0: {}
depd@2.0.0: {}
detect-libc@2.1.2:
optional: true
detect-newline@3.1.0: {}
dezalgo@1.0.4:
@@ -5748,6 +5914,18 @@ snapshots:
inherits@2.0.4: {}
ioredis@5.11.1:
dependencies:
'@ioredis/commands': 1.10.0
cluster-key-slot: 1.1.1
debug: 4.4.3
denque: 2.1.0
redis-errors: 1.2.0
redis-parser: 3.0.0
standard-as-callback: 2.1.0
transitivePeerDependencies:
- supports-color
ipaddr.js@1.9.1: {}
is-arrayish@0.2.1: {}
@@ -6264,6 +6442,8 @@ snapshots:
dependencies:
yallist: 3.1.1
luxon@3.7.2: {}
magic-string@0.30.17:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -6328,6 +6508,22 @@ snapshots:
ms@2.1.3: {}
msgpackr-extract@3.0.4:
dependencies:
node-gyp-build-optional-packages: 5.2.2
optionalDependencies:
'@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.4
'@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.4
'@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.4
'@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.4
'@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.4
'@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4
optional: true
msgpackr@2.0.5:
optionalDependencies:
msgpackr-extract: 3.0.4
multer@2.2.0:
dependencies:
append-field: 1.0.0
@@ -6353,6 +6549,11 @@ snapshots:
dependencies:
lodash: 4.18.1
node-gyp-build-optional-packages@5.2.2:
dependencies:
detect-libc: 2.1.2
optional: true
node-gyp-build@4.8.4: {}
node-int64@0.4.0: {}
@@ -6583,6 +6784,12 @@ snapshots:
readdirp@4.1.2: {}
redis-errors@1.2.0: {}
redis-parser@3.0.0:
dependencies:
redis-errors: 1.2.0
reflect-metadata@0.2.2: {}
require-directory@2.1.1: {}
@@ -6734,6 +6941,8 @@ snapshots:
dependencies:
escape-string-regexp: 2.0.0
standard-as-callback@2.1.0: {}
statuses@2.0.2: {}
streamsearch@1.1.0: {}
@@ -6951,7 +7160,7 @@ snapshots:
typedarray@0.0.6: {}
typeorm@1.1.0(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)):
typeorm@1.1.0(ioredis@5.11.1)(pg@8.22.0)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)):
dependencies:
'@sqltools/formatter': 1.2.5
ansis: 4.3.1
@@ -6964,6 +7173,7 @@ snapshots:
tslib: 2.8.1
yargs: 18.0.0
optionalDependencies:
ioredis: 5.11.1
pg: 8.22.0
ts-node: 10.9.2(@types/node@22.20.1)(typescript@5.9.3)
transitivePeerDependencies:
+1
View File
@@ -1,4 +1,5 @@
allowBuilds:
'@scarf/scarf': false
bcrypt: false
msgpackr-extract: false
unrs-resolver: false
+11
View File
@@ -12,6 +12,7 @@ import { AttachmentModule } from './modules/attachment/attachment.module';
import { ReplyModule } from './modules/reply/reply.module';
import { CacheModule } from '@nestjs/cache-manager';
import KeyvRedis from '@keyv/redis';
import { BullModule } from '@nestjs/bullmq';
@Module({
imports: [
@@ -26,6 +27,16 @@ import KeyvRedis from '@keyv/redis';
stores: [new KeyvRedis(config.getOrThrow('REDIS_URL'))],
}),
}),
BullModule.forRootAsync({
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
connection: {
host: configService.getOrThrow<string>('REDIS_HOST'),
port: configService.getOrThrow<number>('REDIS_PORT'),
// password: configService.get<string>('REDIS_PASSWORD'),
},
}),
}),
TypeOrmModule.forRootAsync(databaseConfig()),
HttpModule.register({
global: true,
+1 -1
View File
@@ -1,7 +1,7 @@
import { FactoryProvider } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { SMS_CONFIG } from "src/modules/utils/constants";
import { SMS_CONFIG } from "src/modules/notifications/constants";
export const smsConfigsProvider: FactoryProvider<ISmsConfigs> = {
provide: SMS_CONFIG,
+3 -7
View File
@@ -2,25 +2,21 @@ import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UtilsModule } from '../utils/utils.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { OTP } from './entities/otp.entity';
import { OtpRepository } from './repositories/otp.repository';
import { UsersModule } from 'src/modules/users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './strategies/jwt.strategy';
import { OtpService } from './otp.service';
import { NotificationModule } from '../notifications/notification.module';
@Module({
imports: [
TypeOrmModule.forFeature([OTP]),
PassportModule,
JwtModule.register({}),
UtilsModule,
UsersModule,
NotificationModule,
],
controllers: [AuthController],
providers: [AuthService, OtpService, OtpRepository, JwtStrategy],
providers: [AuthService, OtpService, JwtStrategy],
exports: [JwtModule, PassportModule],
})
export class AuthModule {}
+5 -10
View File
@@ -1,27 +1,23 @@
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import type { ISmsConfigs } from 'src/config/sms.config';
import { SMS_CONFIG } from '../utils/constants';
import { SmsService } from '../utils/providers/sms.service';
import { OtpRepository } from './repositories/otp.repository';
import { OtpStatus } from './enums/otp-status.enum';
import { SMS_CONFIG } from '../notifications/constants';
import { VerifyOtpDto } from './DTO/verify-otp.dto';
import { OTPMessages, UserMessages } from 'src/common/enums/messages.enum';
import { UserMessages } from 'src/common/enums/messages.enum';
import { LoginCredentialDto } from './DTO/login-credential.dto';
import { UsersService } from 'src/modules/users/users.service';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';
import ms from 'ms';
import { OtpService } from './otp.service';
import { RoleType } from '../users/enums/user-role.enum';
import { SendOtpDto } from './DTO/send-otp.dto';
import { string } from 'joi';
import { SmsProducer } from '../notifications/producers/sms.producer';
@Injectable()
export class AuthService {
constructor(
@Inject(SMS_CONFIG) private smsConfig: ISmsConfigs,
private readonly smsService: SmsService,
private readonly smsProducer: SmsProducer,
private readonly configService: ConfigService,
private readonly userService: UsersService,
private readonly jwtService: JwtService,
@@ -35,7 +31,7 @@ export class AuthService {
});
try {
await this.smsService.sendSms({
await this.smsProducer.sendSms({
Mobile: dto.phoneNumber,
TemplateId: this.smsConfig.SMS_PATTERN_OTP,
Parameters: [
@@ -61,7 +57,6 @@ export class AuthService {
{ phoneNumber: dto.phoneNumber, role: dto.role },
dto.code,
);
if (dto.role) console.log('VERIFIED OTP FOR ROLE: ', dto.role);
}
async checkLoginCredentials(credential: LoginCredentialDto): Promise<void> {
-23
View File
@@ -1,23 +0,0 @@
import { Column, Entity } from 'typeorm';
import { BaseEntity } from 'src/common/entities/base.entity';
import { OtpStatus } from '../enums/otp-status.enum';
@Entity('otps')
export class OTP extends BaseEntity {
@Column({ type: 'varchar', length: 6 })
code: string;
@Column({ type: 'timestamptz' })
expirationDate: Date;
@Column({type: 'enum', enum: OtpStatus, default: OtpStatus.PENDING})
status: OtpStatus;
@Column({ type: 'smallint', default: 0 })
numberOfTries: number;
@Column({
length: 11,
})
phoneNumber: string;
}
@@ -1,13 +0,0 @@
import { Repository } from 'typeorm';
import { OTP } from '../entities/otp.entity';
import { InjectRepository } from '@nestjs/typeorm';
export class OtpRepository extends Repository<OTP> {
constructor(@InjectRepository(OTP) otpRepository: Repository<OTP>) {
super(
otpRepository.target,
otpRepository.manager,
otpRepository.queryRunner,
);
}
}
+2
View File
@@ -0,0 +1,2 @@
export const SMS_CONFIG = "SMS_CONFIG";
export const SMS_QUEUE = 'sms';
@@ -0,0 +1,23 @@
import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { SmsService } from './providers/sms.service';
import { SmsProducer } from './producers/sms.producer';
import { SmsProcessor } from './processors/sms.processor';
import { SMS_CONFIG, SMS_QUEUE } from './constants';
import { smsConfigsProvider } from 'src/config/sms.config';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [
HttpModule,
BullModule.registerQueue({
name: SMS_QUEUE,
}),
],
providers: [SmsService, smsConfigsProvider, SmsProducer, SmsProcessor],
exports: [SmsProducer, SMS_CONFIG],
})
export class NotificationModule {}
export { SMS_QUEUE };
@@ -0,0 +1,22 @@
import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';
import { Logger } from '@nestjs/common';
import { SMS_QUEUE } from '../constants';
import { SmsService } from '../providers/sms.service';
import { SmsRequest } from '../interfaces/ISms';
@Processor(SMS_QUEUE)
export class SmsProcessor extends WorkerHost {
private readonly logger = new Logger(SmsProcessor.name);
constructor(private readonly smsService: SmsService) {
super();
}
async process(job: Job<SmsRequest>): Promise<void> {
this.logger.log(
`Processing SMS job ${job.id} (attempt ${job.attemptsMade + 1})`,
);
await this.smsService.sendSms(job.data);
}
}
@@ -0,0 +1,19 @@
import { Injectable } from '@nestjs/common';
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
import { SMS_QUEUE } from '../constants';
import { SmsRequest } from '../interfaces/ISms';
@Injectable()
export class SmsProducer {
constructor(@InjectQueue(SMS_QUEUE) private readonly smsQueue: Queue) {}
async sendSms(body: SmsRequest) {
return this.smsQueue.add('send-sms', body, {
attempts: 3,
backoff: { type: 'exponential', delay: 2000 },
removeOnComplete: true,
removeOnFail: false,
});
}
}
@@ -1,5 +1,4 @@
import {
BadGatewayException,
Inject,
Injectable,
InternalServerErrorException,
-1
View File
@@ -1,5 +1,4 @@
import { ApiProperty } from '@nestjs/swagger';
import { Exclude } from 'class-transformer';
import {
IsEmail,
IsNotEmpty,
-1
View File
@@ -1 +0,0 @@
export const SMS_CONFIG = "SMS_CONFIG";
-10
View File
@@ -1,10 +0,0 @@
import { Module } from '@nestjs/common';
import { SmsService } from './providers/sms.service';
import { smsConfigsProvider } from 'src/config/sms.config';
import { SMS_CONFIG } from './constants';
@Module({
providers: [SmsService, smsConfigsProvider],
exports: [SMS_CONFIG, SmsService],
})
export class UtilsModule {}