From 55383c879d2068bbdc0bb4bfab23f14c2da10ddf Mon Sep 17 00:00:00 2001 From: Gsk54 Date: Thu, 22 Dec 2022 14:24:51 +0100 Subject: [PATCH] send messages on CUD --- .env | 5 + .env.dist | 5 + package-lock.json | 495 +++++++++++++++++- package.json | 1 + .../secondaries/prisma-repository.abstract.ts | 2 +- .../src/interfaces/repository.interface.ts | 2 +- .../adapters/primaries/users.controller.ts | 5 +- .../adapters/secondaries/user.messager.ts | 18 + .../users/domain/interfaces/user-messager.ts | 12 + .../domain/usecases/create-user.usecase.ts | 10 +- .../domain/usecases/delete-user.usecase.ts | 20 +- .../domain/usecases/update-user.usecase.ts | 15 +- .../tests/unit/create-user.usecase.spec.ts | 9 + .../tests/unit/delete-user.usecase.spec.ts | 9 + .../tests/unit/update-user.usecase.spec.ts | 11 +- src/modules/users/users.module.ts | 22 +- 16 files changed, 624 insertions(+), 17 deletions(-) create mode 100644 src/modules/users/adapters/secondaries/user.messager.ts create mode 100644 src/modules/users/domain/interfaces/user-messager.ts diff --git a/.env b/.env index 15ae154..562a4ba 100644 --- a/.env +++ b/.env @@ -6,6 +6,11 @@ SERVICE_PORT=5001 # PRISMA DATABASE_URL="postgresql://user:user@v3-user-db:5432/user?schema=public" +# RABBIT MQ +RMQ_EXCHANGE_NAME=user +RMQ_EXCHANGE_TYPE=topic +RMQ_URI=amqp://v3-gateway-broker:5672 + # POSTGRES POSTGRES_CONTAINER=v3-user-db POSTGRES_IMAGE=postgres:15.0 diff --git a/.env.dist b/.env.dist index 15ae154..7ca933f 100644 --- a/.env.dist +++ b/.env.dist @@ -6,6 +6,11 @@ SERVICE_PORT=5001 # PRISMA DATABASE_URL="postgresql://user:user@v3-user-db:5432/user?schema=public" +# RABBIT MQ +RMQ_EXCHANGES=user +RMQ_EXCHANGE_TYPE=topic +RMQ_URI=amqp://localhost:5672 + # POSTGRES POSTGRES_CONTAINER=v3-user-db POSTGRES_IMAGE=postgres:15.0 diff --git a/package-lock.json b/package-lock.json index fdb502c..4ae0c38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@automapper/classes": "^8.7.7", "@automapper/core": "^8.7.7", "@automapper/nestjs": "^8.7.7", + "@golevelup/nestjs-rabbitmq": "^3.4.0", "@grpc/grpc-js": "^1.8.0", "@grpc/proto-loader": "^0.7.4", "@nestjs/common": "^9.0.0", @@ -52,6 +53,28 @@ "typescript": "^4.7.4" } }, + "node_modules/@acuminous/bitsyntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", + "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", + "optional": true, + "peer": true, + "dependencies": { + "buffer-more-ints": "~1.0.0", + "debug": "^4.3.4", + "safe-buffer": "~5.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/@acuminous/bitsyntax/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true, + "peer": true + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -896,6 +919,103 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/@golevelup/nestjs-common": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.4.tgz", + "integrity": "sha512-NTjtOhHTMuGwiR3lmBQKKaRr++mHQEsh8AxtaH+/EWOYKMK2Cv/8duaH9MQ0hI3TwnouyaA5IRxYR1ZCUyNXOQ==", + "dependencies": { + "nanoid": "^3.2.0" + } + }, + "node_modules/@golevelup/nestjs-discovery": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.0.tgz", + "integrity": "sha512-ZvkXtobTKxXB1LJanP/l6Z/Fing88IMBr3uabQpU2IWjfsstjh02qYDSU2cfD6CSmNldX5ewW5Pd+SdK2lU8Sw==", + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/@golevelup/nestjs-modules": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.6.1.tgz", + "integrity": "sha512-E0STg8In8fhIivnGDJAA70+XLPHzK5bMTkCnif9FbZ8waTYDQ3T/QQL0h73k+CUFeznn1hmuEW14sNaE+8cd7w==", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@nestjs/common": "^9.x", + "rxjs": "^7.x" + } + }, + "node_modules/@golevelup/nestjs-rabbitmq": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-3.4.0.tgz", + "integrity": "sha512-Ca6JtboZL11qTWl8mFYT3phs+JAhZDhct6/gKbcNEhaaEd3IU6+hEBnjs7LDbYSAIdlpZNODy/rRGSPCFmUYsQ==", + "dependencies": { + "@golevelup/nestjs-common": "^1.4.4", + "@golevelup/nestjs-discovery": "^3.0.0", + "@golevelup/nestjs-modules": "^0.6.1", + "amqp-connection-manager": "^3.0.0", + "amqplib": "^0.8.0" + } + }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/amqp-connection-manager": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-3.9.0.tgz", + "integrity": "sha512-ZKw9ckJKz40Lc2pC7DY0NVocpzPalMaCgv0sBn+N4er2QFAJul9pIiMOm/FsPHeCzB+FulV7PckOpmZvWvewGQ==", + "dependencies": { + "promise-breaker": "^5.0.0" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">5.0.0" + }, + "peerDependencies": { + "amqplib": "*" + } + }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "dependencies": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/promise-breaker": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", + "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" + }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "node_modules/@grpc/grpc-js": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.0.tgz", @@ -2884,6 +3004,66 @@ } } }, + "node_modules/amqp-connection-manager": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-4.1.9.tgz", + "integrity": "sha512-FvV6xfdytmGZdOEAwOWPXgxDBGXytJorN5s8OmS9MlmDrF829bGeo3DphgZZNtY6c1xLccLCKiRjMKt9xfDnFA==", + "optional": true, + "peer": true, + "dependencies": { + "promise-breaker": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">5.0.0" + }, + "peerDependencies": { + "amqplib": "*" + } + }, + "node_modules/amqplib": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", + "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", + "optional": true, + "peer": true, + "dependencies": { + "@acuminous/bitsyntax": "^0.1.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "url-parse": "~1.5.10" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/amqplib/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "optional": true, + "peer": true + }, + "node_modules/amqplib/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "optional": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/amqplib/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "optional": true, + "peer": true + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -3139,6 +3319,37 @@ "node": ">=8" } }, + "node_modules/bitsyntax": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", + "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "dependencies": { + "buffer-more-ints": "~1.0.0", + "debug": "~2.6.9", + "safe-buffer": "~5.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/bitsyntax/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/bitsyntax/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bitsyntax/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3164,6 +3375,11 @@ "node": ">= 6" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -3299,6 +3515,11 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -3713,7 +3934,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, + "devOptional": true, "dependencies": { "ms": "2.1.2" }, @@ -6516,7 +6737,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "devOptional": true }, "node_modules/multer": { "version": "1.4.4-lts.1", @@ -6541,6 +6762,17 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7081,6 +7313,13 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/promise-breaker": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-6.0.0.tgz", + "integrity": "sha512-BthzO9yTPswGf7etOBiHCVuugs2N01/Q/94dIPls48z2zCmrnDptUUZzfIb+41xq0MnYZ/BzmOd6ikDR4ibNZA==", + "optional": true, + "peer": true + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -7167,6 +7406,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -7301,6 +7545,11 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -8426,6 +8675,15 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -8795,6 +9053,27 @@ } }, "dependencies": { + "@acuminous/bitsyntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", + "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", + "optional": true, + "peer": true, + "requires": { + "buffer-more-ints": "~1.0.0", + "debug": "^4.3.4", + "safe-buffer": "~5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true, + "peer": true + } + } + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -9435,6 +9714,91 @@ } } }, + "@golevelup/nestjs-common": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.4.tgz", + "integrity": "sha512-NTjtOhHTMuGwiR3lmBQKKaRr++mHQEsh8AxtaH+/EWOYKMK2Cv/8duaH9MQ0hI3TwnouyaA5IRxYR1ZCUyNXOQ==", + "requires": { + "nanoid": "^3.2.0" + } + }, + "@golevelup/nestjs-discovery": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.0.tgz", + "integrity": "sha512-ZvkXtobTKxXB1LJanP/l6Z/Fing88IMBr3uabQpU2IWjfsstjh02qYDSU2cfD6CSmNldX5ewW5Pd+SdK2lU8Sw==", + "requires": { + "lodash": "^4.17.15" + } + }, + "@golevelup/nestjs-modules": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.6.1.tgz", + "integrity": "sha512-E0STg8In8fhIivnGDJAA70+XLPHzK5bMTkCnif9FbZ8waTYDQ3T/QQL0h73k+CUFeznn1hmuEW14sNaE+8cd7w==", + "requires": { + "lodash": "^4.17.21" + } + }, + "@golevelup/nestjs-rabbitmq": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-3.4.0.tgz", + "integrity": "sha512-Ca6JtboZL11qTWl8mFYT3phs+JAhZDhct6/gKbcNEhaaEd3IU6+hEBnjs7LDbYSAIdlpZNODy/rRGSPCFmUYsQ==", + "requires": { + "@golevelup/nestjs-common": "^1.4.4", + "@golevelup/nestjs-discovery": "^3.0.0", + "@golevelup/nestjs-modules": "^0.6.1", + "amqp-connection-manager": "^3.0.0", + "amqplib": "^0.8.0" + }, + "dependencies": { + "amqp-connection-manager": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-3.9.0.tgz", + "integrity": "sha512-ZKw9ckJKz40Lc2pC7DY0NVocpzPalMaCgv0sBn+N4er2QFAJul9pIiMOm/FsPHeCzB+FulV7PckOpmZvWvewGQ==", + "requires": { + "promise-breaker": "^5.0.0" + } + }, + "amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "requires": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "promise-breaker": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", + "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + } + } + }, "@grpc/grpc-js": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.0.tgz", @@ -10945,6 +11309,58 @@ "ajv": "^8.0.0" } }, + "amqp-connection-manager": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-4.1.9.tgz", + "integrity": "sha512-FvV6xfdytmGZdOEAwOWPXgxDBGXytJorN5s8OmS9MlmDrF829bGeo3DphgZZNtY6c1xLccLCKiRjMKt9xfDnFA==", + "optional": true, + "peer": true, + "requires": { + "promise-breaker": "^6.0.0" + } + }, + "amqplib": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", + "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", + "optional": true, + "peer": true, + "requires": { + "@acuminous/bitsyntax": "^0.1.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "url-parse": "~1.5.10" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "optional": true, + "peer": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "optional": true, + "peer": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "optional": true, + "peer": true + } + } + }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -11130,6 +11546,36 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bitsyntax": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", + "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "requires": { + "buffer-more-ints": "~1.0.0", + "debug": "~2.6.9", + "safe-buffer": "~5.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -11154,6 +11600,11 @@ } } }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -11251,6 +11702,11 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -11560,7 +12016,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, + "devOptional": true, "requires": { "ms": "2.1.2" } @@ -13657,7 +14113,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "devOptional": true }, "multer": { "version": "1.4.4-lts.1", @@ -13679,6 +14135,11 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -14062,6 +14523,13 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "promise-breaker": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-6.0.0.tgz", + "integrity": "sha512-BthzO9yTPswGf7etOBiHCVuugs2N01/Q/94dIPls48z2zCmrnDptUUZzfIb+41xq0MnYZ/BzmOd6ikDR4ibNZA==", + "optional": true, + "peer": true + }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -14131,6 +14599,11 @@ "side-channel": "^1.0.4" } }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -14229,6 +14702,11 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -15020,6 +15498,15 @@ "punycode": "^2.1.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 15bcd6a..9e2bcc6 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@automapper/classes": "^8.7.7", "@automapper/core": "^8.7.7", "@automapper/nestjs": "^8.7.7", + "@golevelup/nestjs-rabbitmq": "^3.4.0", "@grpc/grpc-js": "^1.8.0", "@grpc/proto-loader": "^0.7.4", "@nestjs/common": "^9.0.0", diff --git a/src/modules/database/src/adapters/secondaries/prisma-repository.abstract.ts b/src/modules/database/src/adapters/secondaries/prisma-repository.abstract.ts index 0f655c1..4b9cd4e 100644 --- a/src/modules/database/src/adapters/secondaries/prisma-repository.abstract.ts +++ b/src/modules/database/src/adapters/secondaries/prisma-repository.abstract.ts @@ -144,7 +144,7 @@ export abstract class PrismaRepository implements IRepository { } } - async delete(uuid: string): Promise { + async delete(uuid: string): Promise { try { const entity = await this._prisma[this._model].delete({ where: { uuid }, diff --git a/src/modules/database/src/interfaces/repository.interface.ts b/src/modules/database/src/interfaces/repository.interface.ts index 1755f33..9228712 100644 --- a/src/modules/database/src/interfaces/repository.interface.ts +++ b/src/modules/database/src/interfaces/repository.interface.ts @@ -12,5 +12,5 @@ export interface IRepository { create(entity: Partial | any, include?: any): Promise; update(uuid: string, entity: Partial, include?: any): Promise; updateWhere(where: any, entity: Partial | any, include?: any): Promise; - delete(uuid: string): Promise; + delete(uuid: string): Promise; } diff --git a/src/modules/users/adapters/primaries/users.controller.ts b/src/modules/users/adapters/primaries/users.controller.ts index 1500b84..75d4e1c 100644 --- a/src/modules/users/adapters/primaries/users.controller.ts +++ b/src/modules/users/adapters/primaries/users.controller.ts @@ -92,10 +92,7 @@ export class UsersController { @GrpcMethod('UsersService', 'Delete') async deleteUser(data: FindUserByUuidRequest): Promise { try { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const user = await this._commandBus.execute( - new DeleteUserCommand(data.uuid), - ); + await this._commandBus.execute(new DeleteUserCommand(data.uuid)); return Promise.resolve(); } catch (e) { diff --git a/src/modules/users/adapters/secondaries/user.messager.ts b/src/modules/users/adapters/secondaries/user.messager.ts new file mode 100644 index 0000000..2ce98c5 --- /dev/null +++ b/src/modules/users/adapters/secondaries/user.messager.ts @@ -0,0 +1,18 @@ +import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; +import { Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { IMessageUser } from '../../domain/interfaces/user-messager'; + +@Injectable() +export class UserMessager extends IMessageUser { + constructor( + private readonly _configService: ConfigService, + private readonly _amqpConnection: AmqpConnection, + ) { + super(_configService.get('RMQ_EXCHANGE_NAME')); + } + + publish(routingKey: string, message: string): void { + this._amqpConnection.publish(this.exchange, routingKey, message); + } +} diff --git a/src/modules/users/domain/interfaces/user-messager.ts b/src/modules/users/domain/interfaces/user-messager.ts new file mode 100644 index 0000000..98ad7c2 --- /dev/null +++ b/src/modules/users/domain/interfaces/user-messager.ts @@ -0,0 +1,12 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export abstract class IMessageUser { + exchange: string; + + constructor(exchange: string) { + this.exchange = exchange; + } + + abstract publish(routingKey: string, message: string): void; +} diff --git a/src/modules/users/domain/usecases/create-user.usecase.ts b/src/modules/users/domain/usecases/create-user.usecase.ts index 3f25c57..e2b5ded 100644 --- a/src/modules/users/domain/usecases/create-user.usecase.ts +++ b/src/modules/users/domain/usecases/create-user.usecase.ts @@ -1,6 +1,7 @@ import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; import { CommandHandler } from '@nestjs/cqrs'; +import { UserMessager } from '../../adapters/secondaries/user.messager'; import { UsersRepository } from '../../adapters/secondaries/users.repository'; import { CreateUserCommand } from '../../commands/create-user.command'; import { CreateUserRequest } from '../dtos/create-user.request'; @@ -10,6 +11,7 @@ import { User } from '../entities/user'; export class CreateUserUseCase { constructor( private readonly _repository: UsersRepository, + private readonly _messager: UserMessager, @InjectMapper() private readonly _mapper: Mapper, ) {} @@ -20,6 +22,12 @@ export class CreateUserUseCase { User, ); - return this._repository.create(entity); + const user = await this._repository.create(entity); + + if (user) { + this._messager.publish('user.create', JSON.stringify(user)); + } + + return user; } } diff --git a/src/modules/users/domain/usecases/delete-user.usecase.ts b/src/modules/users/domain/usecases/delete-user.usecase.ts index 4378b61..1d27849 100644 --- a/src/modules/users/domain/usecases/delete-user.usecase.ts +++ b/src/modules/users/domain/usecases/delete-user.usecase.ts @@ -1,12 +1,26 @@ import { CommandHandler } from '@nestjs/cqrs'; +import { UserMessager } from '../../adapters/secondaries/user.messager'; import { UsersRepository } from '../../adapters/secondaries/users.repository'; import { DeleteUserCommand } from '../../commands/delete-user.command'; +import { User } from '../entities/user'; @CommandHandler(DeleteUserCommand) export class DeleteUserUseCase { - constructor(private readonly _repository: UsersRepository) {} + constructor( + private readonly _repository: UsersRepository, + private readonly _messager: UserMessager, + ) {} - async execute(command: DeleteUserCommand): Promise { - return this._repository.delete(command.uuid); + async execute(command: DeleteUserCommand): Promise { + const user = await this._repository.delete(command.uuid); + + if (user) { + this._messager.publish( + 'user.delete', + JSON.stringify({ uuid: user.uuid }), + ); + } + + return user; } } diff --git a/src/modules/users/domain/usecases/update-user.usecase.ts b/src/modules/users/domain/usecases/update-user.usecase.ts index 10637da..bd3aab8 100644 --- a/src/modules/users/domain/usecases/update-user.usecase.ts +++ b/src/modules/users/domain/usecases/update-user.usecase.ts @@ -1,6 +1,7 @@ import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; import { CommandHandler } from '@nestjs/cqrs'; +import { UserMessager } from '../../adapters/secondaries/user.messager'; import { UsersRepository } from '../../adapters/secondaries/users.repository'; import { UpdateUserCommand } from '../../commands/update-user.command'; import { UpdateUserRequest } from '../dtos/update-user.request'; @@ -10,6 +11,7 @@ import { User } from '../entities/user'; export class UpdateUserUseCase { constructor( private readonly _repository: UsersRepository, + private readonly _messager: UserMessager, @InjectMapper() private readonly _mapper: Mapper, ) {} @@ -20,6 +22,17 @@ export class UpdateUserUseCase { User, ); - return this._repository.update(command.updateUserRequest.uuid, entity); + const user = await this._repository.update( + command.updateUserRequest.uuid, + entity, + ); + + if (user) { + this._messager.publish( + 'user.update', + JSON.stringify(command.updateUserRequest), + ); + } + return user; } } diff --git a/src/modules/users/tests/unit/create-user.usecase.spec.ts b/src/modules/users/tests/unit/create-user.usecase.spec.ts index 2d3a8f5..cf85f13 100644 --- a/src/modules/users/tests/unit/create-user.usecase.spec.ts +++ b/src/modules/users/tests/unit/create-user.usecase.spec.ts @@ -1,6 +1,7 @@ import { classes } from '@automapper/classes'; import { AutomapperModule } from '@automapper/nestjs'; import { Test, TestingModule } from '@nestjs/testing'; +import { UserMessager } from '../../adapters/secondaries/user.messager'; import { UsersRepository } from '../../adapters/secondaries/users.repository'; import { CreateUserCommand } from '../../commands/create-user.command'; import { CreateUserRequest } from '../../domain/dtos/create-user.request'; @@ -23,6 +24,10 @@ const mockUsersRepository = { }), }; +const mockUserMessager = { + publish: jest.fn().mockImplementation(), +}; + describe('CreateUserUseCase', () => { let createUserUseCase: CreateUserUseCase; @@ -36,6 +41,10 @@ describe('CreateUserUseCase', () => { }, CreateUserUseCase, UserProfile, + { + provide: UserMessager, + useValue: mockUserMessager, + }, ], }).compile(); diff --git a/src/modules/users/tests/unit/delete-user.usecase.spec.ts b/src/modules/users/tests/unit/delete-user.usecase.spec.ts index 40e5c19..02cb5be 100644 --- a/src/modules/users/tests/unit/delete-user.usecase.spec.ts +++ b/src/modules/users/tests/unit/delete-user.usecase.spec.ts @@ -1,4 +1,5 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { UserMessager } from '../../adapters/secondaries/user.messager'; import { UsersRepository } from '../../adapters/secondaries/users.repository'; import { DeleteUserCommand } from '../../commands/delete-user.command'; import { DeleteUserUseCase } from '../../domain/usecases/delete-user.usecase'; @@ -38,6 +39,10 @@ const mockUsersRepository = { }), }; +const mockUserMessager = { + publish: jest.fn().mockImplementation(), +}; + describe('DeleteUserUseCase', () => { let deleteUserUseCase: DeleteUserUseCase; @@ -49,6 +54,10 @@ describe('DeleteUserUseCase', () => { useValue: mockUsersRepository, }, DeleteUserUseCase, + { + provide: UserMessager, + useValue: mockUserMessager, + }, ], }).compile(); diff --git a/src/modules/users/tests/unit/update-user.usecase.spec.ts b/src/modules/users/tests/unit/update-user.usecase.spec.ts index 0c631db..ed68fda 100644 --- a/src/modules/users/tests/unit/update-user.usecase.spec.ts +++ b/src/modules/users/tests/unit/update-user.usecase.spec.ts @@ -1,6 +1,7 @@ import { classes } from '@automapper/classes'; import { AutomapperModule } from '@automapper/nestjs'; import { Test, TestingModule } from '@nestjs/testing'; +import { UserMessager } from '../../adapters/secondaries/user.messager'; import { UsersRepository } from '../../adapters/secondaries/users.repository'; import { UpdateUserCommand } from '../../commands/update-user.command'; import { UpdateUserRequest } from '../../domain/dtos/update-user.request'; @@ -29,6 +30,10 @@ const mockUsersRepository = { }), }; +const mockUserMessager = { + publish: jest.fn().mockImplementation(), +}; + describe('UpdateUserUseCase', () => { let updateUserUseCase: UpdateUserUseCase; @@ -43,6 +48,10 @@ describe('UpdateUserUseCase', () => { }, UpdateUserUseCase, UserProfile, + { + provide: UserMessager, + useValue: mockUserMessager, + }, ], }).compile(); @@ -54,7 +63,7 @@ describe('UpdateUserUseCase', () => { }); describe('execute', () => { - it('should update an User', async () => { + it('should update a user', async () => { const updatedUser: User = await updateUserUseCase.execute( updateUserCommand, ); diff --git a/src/modules/users/users.module.ts b/src/modules/users/users.module.ts index 10a82a9..47fec5c 100644 --- a/src/modules/users/users.module.ts +++ b/src/modules/users/users.module.ts @@ -1,7 +1,10 @@ +import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'; import { Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import { CqrsModule } from '@nestjs/cqrs'; import { DatabaseModule } from '../database/database.module'; import { UsersController } from './adapters/primaries/users.controller'; +import { UserMessager } from './adapters/secondaries/user.messager'; import { UsersRepository } from './adapters/secondaries/users.repository'; import { CreateUserUseCase } from './domain/usecases/create-user.usecase'; import { DeleteUserUseCase } from './domain/usecases/delete-user.usecase'; @@ -11,11 +14,28 @@ import { UpdateUserUseCase } from './domain/usecases/update-user.usecase'; import { UserProfile } from './mappers/user.profile'; @Module({ - imports: [DatabaseModule, CqrsModule], + imports: [ + DatabaseModule, + CqrsModule, + RabbitMQModule.forRootAsync(RabbitMQModule, { + imports: [ConfigModule], + useFactory: async (configService: ConfigService) => ({ + exchanges: [ + { + name: configService.get('RMQ_EXCHANGE_NAME'), + type: configService.get('RMQ_EXCHANGE_TYPE'), + }, + ], + uri: configService.get('RMQ_URI'), + }), + inject: [ConfigService], + }), + ], controllers: [UsersController], providers: [ UserProfile, UsersRepository, + UserMessager, FindAllUsersUseCase, FindUserByUuidUseCase, CreateUserUseCase,