From b575277f114f629c298b1e960c89de2b7b130c52 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Sat, 26 Aug 2023 12:03:44 +0700 Subject: [PATCH 01/19] feat: initialize elastic module --- docker-compose.yaml | 18 ++++++ package.json | 2 + .../core/interfaces/article.interface.ts | 10 +++ src/elastic-search/elastic-search.module.ts | 18 ++++++ src/elastic-search/elastic-search.service.ts | 41 +++++++++++++ yarn.lock | 61 ++++++++++++++++++- 6 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 src/elastic-search/elastic-search.module.ts create mode 100644 src/elastic-search/elastic-search.service.ts diff --git a/docker-compose.yaml b/docker-compose.yaml index ed1bfa7..d4722f7 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -65,3 +65,21 @@ services: depends_on: - social-api-1 - social-api-2 + elasticsearch: + container_name: social-es + image: docker.elastic.co/elasticsearch/elasticsearch:7.11.0 + environment: + - node.name=elasticsearch + - cluster.name=es-docker-cluster + - discovery.seed_hosts=elasticsearch + - cluster.initial_master_nodes=elasticsearch + - bootstrap.memory_lock=true + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ulimits: + memlock: + soft: -1 + hard: -1 + ports: + - 9200:9200 + volumes: + - /data/elasticsearch/ diff --git a/package.json b/package.json index a754dbf..7000c0a 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,12 @@ "author": "trananh22112001@gmail.com", "license": "ISC", "dependencies": { + "@elastic/elasticsearch": "^8.9.0", "@nestjs/common": "^7.0.5", "@nestjs/config": "^2.2.0", "@nestjs/core": "^7.0.5", "@nestjs/cqrs": "^9.0.1", + "@nestjs/elasticsearch": "^10.0.1", "@nestjs/platform-express": "^7.0.5", "@nestjs/swagger": "^4.4.0", "@nestjs/testing": "^7.0.5", diff --git a/src/article/core/interfaces/article.interface.ts b/src/article/core/interfaces/article.interface.ts index 0d0cac3..a9c2100 100644 --- a/src/article/core/interfaces/article.interface.ts +++ b/src/article/core/interfaces/article.interface.ts @@ -2,6 +2,7 @@ import { BlockEntity } from "../entities/block.entity"; import { IBlock } from "./block.interface"; import { ProfileData } from "../../../profile/core/interfaces/profile.interface"; import { IUser } from "../../../user/core/interfaces/user.interface"; +import { ArticleFilters } from "../../dto"; // export interface Comment { // id: number; @@ -63,3 +64,12 @@ export interface IComment { article?: IArticle; author?: IUser | ProfileData; } + +export interface IArticleSearchResult { + hits: { + total: number; + hits: Array<{ + _source: ArticleFilters; + }>; + }; +} diff --git a/src/elastic-search/elastic-search.module.ts b/src/elastic-search/elastic-search.module.ts new file mode 100644 index 0000000..a397a4e --- /dev/null +++ b/src/elastic-search/elastic-search.module.ts @@ -0,0 +1,18 @@ +import { Module } from "@nestjs/common"; +import { ElasticsearchModule as EsModule } from "@nestjs/elasticsearch"; +import { SearchService } from "./elastic-search.service"; + +@Module({ + imports: [ + EsModule.register({ + node: process.env.ELASTICSEARCH_NODE, + auth: { + username: process.env.ELASTICSEARCH_USERNAME, + password: process.env.ELASTICSEARCH_PASSWORD, + }, + }), + ], + providers: [SearchService], + exports: [EsModule], +}) +export class ElasticSearchModule {} diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts new file mode 100644 index 0000000..935422b --- /dev/null +++ b/src/elastic-search/elastic-search.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from "@nestjs/common"; +import { ElasticsearchService } from "@nestjs/elasticsearch"; +import { ArticleEntity, IArticleSearchResult } from "../article/core"; + +@Injectable() +export class SearchService { + private readonly articleIndexes = "articles"; + + constructor(private readonly elasticsearchService: ElasticsearchService) {} + + async indexArticle(article: ArticleEntity) { + return this.elasticsearchService.index({ + index: this.articleIndexes, + body: { + id: article.id, + title: article.title, + slug: article.slug, + description: article.description, + author: article.author.username, + blockText: article.blocks.map((block) => block.data.text), + }, + }); + } + + async searchArticles(search: string) { + const response = + await this.elasticsearchService.search({ + index: this.articleIndexes, + body: { + query: { + multi_match: { + query: search, + fields: ["title", "description"], + }, + }, + }, + }); + const hits = response.hits.hits; + return hits.map((item) => item._source); + } +} diff --git a/yarn.lock b/yarn.lock index 7bd1875..f977cb0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -293,6 +293,26 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@elastic/elasticsearch@^8.9.0": + version "8.9.0" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-8.9.0.tgz#d132021c6c12e4171fe14371609a5c69b535edd4" + integrity sha512-UyolnzjOYTRL2966TYS3IoJP4tQbvak/pmYmbP3JdphD53RjkyVDdxMpTBv+2LcNBRrvYPTzxQbpRW/nGSXA9g== + dependencies: + "@elastic/transport" "^8.3.2" + tslib "^2.4.0" + +"@elastic/transport@^8.3.2": + version "8.3.3" + resolved "https://registry.yarnpkg.com/@elastic/transport/-/transport-8.3.3.tgz#06c5b1b9566796775ac96d17959dafc269da5ec1" + integrity sha512-g5nc//dq/RQUTMkJUB8Ui8KJa/WflWmUa7yLl4SRZd67PPxIp3cn+OvGMNIhpiLRcfz1upanzgZHb/7Po2eEdQ== + dependencies: + debug "^4.3.4" + hpagent "^1.0.0" + ms "^2.1.3" + secure-json-parse "^2.4.0" + tslib "^2.4.0" + undici "^5.22.1" + "@ioredis/commands@^1.1.1": version "1.2.0" resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" @@ -562,6 +582,11 @@ dependencies: uuid "8.3.2" +"@nestjs/elasticsearch@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@nestjs/elasticsearch/-/elasticsearch-10.0.1.tgz#5aed1b699e5b3622c6522cbb7f78a16db549d652" + integrity sha512-rYkcuStF7oDbyt5X3h0BAYS3thZQm8vsHUkGot6dkB8dOTsSIsQJ8UYY9j66LhghzsBiewIwUrKkhY5WM2DVqA== + "@nestjs/mapped-types@0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-0.4.1.tgz#e7fe038f0bdda7b8f858fa79ca8516b8f9069b1a" @@ -1364,6 +1389,13 @@ busboy@^0.2.11: dicer "0.2.5" readable-stream "1.1.x" +busboy@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" @@ -2685,6 +2717,11 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== +hpagent@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-1.2.0.tgz#0ae417895430eb3770c03443456b8d90ca464903" + integrity sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA== + html-encoding-sniffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" @@ -4020,7 +4057,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: +ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -5048,6 +5085,11 @@ saxes@^3.1.9: dependencies: xmlchars "^2.1.1" +secure-json-parse@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" + integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -5358,6 +5400,11 @@ streamsearch@0.1.2: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" integrity sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA== +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + string-length@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" @@ -5706,6 +5753,11 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== +tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -5808,6 +5860,13 @@ undefsafe@^2.0.2: resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== +undici@^5.22.1: + version "5.23.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.23.0.tgz#e7bdb0ed42cebe7b7aca87ced53e6eaafb8f8ca0" + integrity sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg== + dependencies: + busboy "^1.6.0" + uni-global@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/uni-global/-/uni-global-1.0.0.tgz#3583c449e87a2d9dc270ea221410a649bcdad040" From 4dc3317c0e3b87fc275b23b8af18fbb5906846f0 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Sat, 26 Aug 2023 12:19:33 +0700 Subject: [PATCH 02/19] feat: imple searching --wip --- src/article/dto/index.ts | 1 + src/article/dto/search-article.ts | 12 +++++++ .../handlers/search-article.handler.ts | 31 +++++++++++++++++++ src/article/queries/impl/index.ts | 2 ++ .../queries/impl/search-article.query.ts | 5 +++ src/article/queries/query.module.ts | 2 ++ 6 files changed, 53 insertions(+) create mode 100644 src/article/dto/search-article.ts create mode 100644 src/article/queries/handlers/search-article.handler.ts create mode 100644 src/article/queries/impl/search-article.query.ts diff --git a/src/article/dto/index.ts b/src/article/dto/index.ts index 23b3038..eb22ce7 100644 --- a/src/article/dto/index.ts +++ b/src/article/dto/index.ts @@ -2,3 +2,4 @@ export { CreateArticleDto } from "./create-article.dto"; export { CreateCommentDto } from "./create-comment"; export * from "./article-query"; export * from "./block.dto"; +export * from "./search-article"; diff --git a/src/article/dto/search-article.ts b/src/article/dto/search-article.ts new file mode 100644 index 0000000..ddf9164 --- /dev/null +++ b/src/article/dto/search-article.ts @@ -0,0 +1,12 @@ +import { ApiProperty } from "@nestjs/swagger"; + +export class SearchArticleDto { + @ApiProperty({ required: false }) + limit?: number; + + @ApiProperty({ required: false }) + offset?: number; + + @ApiProperty({ required: true }) + search?: string; +} diff --git a/src/article/queries/handlers/search-article.handler.ts b/src/article/queries/handlers/search-article.handler.ts new file mode 100644 index 0000000..132d525 --- /dev/null +++ b/src/article/queries/handlers/search-article.handler.ts @@ -0,0 +1,31 @@ +import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; + +import { READ_CONNECTION } from "../../../config"; +import { UserEntity } from "../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../core/entities/article.entity"; +import { ArticlesRO } from "../../core/interfaces/article.interface"; +import { ArticleService } from "../../services/article.service"; +import { SearchArticleQuery } from "../impl"; +import { SearchService } from "../../../elastic-search/elastic-search.service"; + +@QueryHandler(SearchArticleQuery) +export class SearchArticleQueryHandler + implements IQueryHandler +{ + constructor( + @InjectRepository(UserEntity, READ_CONNECTION) + private readonly userRepository: Repository, + @InjectRepository(ArticleEntity, READ_CONNECTION) + private readonly articleRepository: Repository, + + private readonly articleService: ArticleService, + + private readonly elasticSearch: SearchService + ) {} + + async execute({ query }: SearchArticleQuery): Promise { + return this.elasticSearch.searchArticles(query.search); + } +} diff --git a/src/article/queries/impl/index.ts b/src/article/queries/impl/index.ts index a261536..5856675 100644 --- a/src/article/queries/impl/index.ts +++ b/src/article/queries/impl/index.ts @@ -2,4 +2,6 @@ export * from "./find-all.article.query"; export * from "./find-feed-article.query"; export * from "./find-one-article.query"; +export * from "./search-article.query"; + export * from "./find-comments.query"; diff --git a/src/article/queries/impl/search-article.query.ts b/src/article/queries/impl/search-article.query.ts new file mode 100644 index 0000000..5b11602 --- /dev/null +++ b/src/article/queries/impl/search-article.query.ts @@ -0,0 +1,5 @@ +import { SearchArticleDto } from "../../dto"; + +export class SearchArticleQuery { + constructor(public readonly query: SearchArticleDto) {} +} diff --git a/src/article/queries/query.module.ts b/src/article/queries/query.module.ts index 3785a4b..99e4db9 100644 --- a/src/article/queries/query.module.ts +++ b/src/article/queries/query.module.ts @@ -9,6 +9,7 @@ import { UserModule } from "../../user/user.module"; import { ArticleEntity } from "../core"; import { CommentEntity } from "../core/entities/comment.entity"; import { ArticleService } from "../services/article.service"; +import { ElasticSearchModule } from "../../elastic-search/elastic-search.module"; @Module({ imports: [ @@ -18,6 +19,7 @@ import { ArticleService } from "../services/article.service"; ), UserModule, CqrsModule, + ElasticSearchModule, ], providers: [ArticleService, ...QueryHandlers], controllers: [], From be77d23ef0df6e716f78e16b8c1c121b00402b01 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Sat, 26 Aug 2023 14:43:43 +0700 Subject: [PATCH 03/19] feat: impl bulk indexing for data availble --- package.json | 4 +- src/article/article.module.ts | 7 ++- src/article/core/enums/article.enum.ts | 2 + .../core/interfaces/projection.interface.ts | 1 + .../elastic-search-article.projection.ts | 31 ++++++++++ src/article/events/event.module.ts | 2 + src/article/events/handlers/index.ts | 2 + .../handlers/indexing-article.handler.ts | 19 ++++++ src/article/events/index.ts | 3 + src/article/queries/handlers/index.ts | 3 + .../handlers/indexing-article.handler.ts | 51 +++++++++++++++ src/article/queries/impl/index.ts | 2 + src/article/queries/index.ts | 5 ++ src/article/queries/query.module.ts | 2 + src/elastic-search/elastic-search.module.ts | 2 +- src/elastic-search/elastic-search.service.ts | 48 +++++++++++++- src/rabbitmq/publisher.service.ts | 21 +++++++ src/rabbitmq/rabbitmq.constants.ts | 4 ++ yarn.lock | 62 +++++-------------- 19 files changed, 217 insertions(+), 54 deletions(-) create mode 100644 src/article/elastic-search-article.projection.ts create mode 100644 src/article/events/handlers/indexing-article.handler.ts create mode 100644 src/article/queries/handlers/indexing-article.handler.ts diff --git a/package.json b/package.json index 7000c0a..63f979d 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,12 @@ "author": "trananh22112001@gmail.com", "license": "ISC", "dependencies": { - "@elastic/elasticsearch": "^8.9.0", + "@elastic/elasticsearch": "^7.11.0", "@nestjs/common": "^7.0.5", "@nestjs/config": "^2.2.0", "@nestjs/core": "^7.0.5", "@nestjs/cqrs": "^9.0.1", - "@nestjs/elasticsearch": "^10.0.1", + "@nestjs/elasticsearch": "^7.1", "@nestjs/platform-express": "^7.0.5", "@nestjs/swagger": "^4.4.0", "@nestjs/testing": "^7.0.5", diff --git a/src/article/article.module.ts b/src/article/article.module.ts index 0b16e8b..aaeb3e3 100644 --- a/src/article/article.module.ts +++ b/src/article/article.module.ts @@ -15,6 +15,7 @@ import { CommandModule } from "./commands/command.module"; import { EventModule } from "./events/event.module"; import { QueryModule } from "./queries/query.module"; import { RedisModule } from "../redis/redis.module"; +import { ElasticSearchArticleProjection } from "./elastic-search-article.projection"; @Module({ imports: [ @@ -26,7 +27,11 @@ import { RedisModule } from "../redis/redis.module"; RabbitMqModule, RedisModule, ], - providers: [ArticleService, ArticleProjection], + providers: [ + ArticleService, + ArticleProjection, + ElasticSearchArticleProjection, + ], controllers: [ArticleController], }) export class ArticleModule implements NestModule { diff --git a/src/article/core/enums/article.enum.ts b/src/article/core/enums/article.enum.ts index 82e977e..e394ee1 100644 --- a/src/article/core/enums/article.enum.ts +++ b/src/article/core/enums/article.enum.ts @@ -6,4 +6,6 @@ export enum MessageType { ARTICLE_UNFAVORITED = "ARTICLE_UNFAVORITED", COMMENT_CREATED = "COMMENT_CREATED", COMMENT_DELETED = "COMMENT_DELETED", + + INDEXING_ARTICLE = "INDEXING_ARTICLE", } diff --git a/src/article/core/interfaces/projection.interface.ts b/src/article/core/interfaces/projection.interface.ts index d9468d4..400f062 100644 --- a/src/article/core/interfaces/projection.interface.ts +++ b/src/article/core/interfaces/projection.interface.ts @@ -7,6 +7,7 @@ export interface IMessage { type: MessageType; payload: { article?: ArticleEntity; + articles?: ArticleEntity[]; user?: UserEntity; slug?: string; userId?: number; diff --git a/src/article/elastic-search-article.projection.ts b/src/article/elastic-search-article.projection.ts new file mode 100644 index 0000000..90fdd5d --- /dev/null +++ b/src/article/elastic-search-article.projection.ts @@ -0,0 +1,31 @@ +import { Injectable } from "@nestjs/common"; +import { EventBus } from "@nestjs/cqrs"; +import { ConsumerService } from "../rabbitmq/consumer.service"; +import { ES_ARTICLE_QUEUE } from "../rabbitmq/rabbitmq.constants"; +import { IMessage, IProjection } from "./core"; +import { MessageType } from "./core/enums/article.enum"; +import { IndexingArticleEvent } from "./events"; + +@Injectable() +export class ElasticSearchArticleProjection implements IProjection { + constructor( + private readonly consumer: ConsumerService, + private readonly eventBus: EventBus + ) {} + + async handle() { + await this.consumer.consume(ES_ARTICLE_QUEUE, (msg: IMessage) => { + this.handleMessage(msg); + }); + } + + private async handleMessage({ type, payload }: IMessage) { + switch (type) { + case MessageType.INDEXING_ARTICLE: + this.eventBus.publish(new IndexingArticleEvent(payload.articles)); + break; + default: + break; + } + } +} diff --git a/src/article/events/event.module.ts b/src/article/events/event.module.ts index 6a2b041..c32eedc 100644 --- a/src/article/events/event.module.ts +++ b/src/article/events/event.module.ts @@ -6,6 +6,7 @@ import { UserEntity } from "../../user/core/entities/user.entity"; import { ArticleEntity, BlockEntity } from "../core"; import { CommentEntity } from "../core/entities/comment.entity"; import { EventHandlers } from "../events"; +import { ElasticSearchModule } from "../../elastic-search/elastic-search.module"; @Module({ imports: [ @@ -14,6 +15,7 @@ import { EventHandlers } from "../events"; READ_CONNECTION ), CqrsModule, + ElasticSearchModule ], providers: [...EventHandlers], controllers: [], diff --git a/src/article/events/handlers/index.ts b/src/article/events/handlers/index.ts index e1a19dd..cee276a 100644 --- a/src/article/events/handlers/index.ts +++ b/src/article/events/handlers/index.ts @@ -4,5 +4,7 @@ export * from "./article-deleted.handler"; export * from "./article-favorited.handler"; export * from "./article-unfavorited.handler"; +export * from "./indexing-article.handler"; + export * from "./comment-created.handler"; export * from "./comment-deleted.handler"; diff --git a/src/article/events/handlers/indexing-article.handler.ts b/src/article/events/handlers/indexing-article.handler.ts new file mode 100644 index 0000000..fac1bf0 --- /dev/null +++ b/src/article/events/handlers/indexing-article.handler.ts @@ -0,0 +1,19 @@ +import { IEventHandler } from "@nestjs/cqrs"; +import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; + +import { SearchService } from "../../../elastic-search/elastic-search.service"; +import { ArticleEntity } from "../../core/entities/article.entity"; + +export class IndexingArticleEvent { + constructor(public readonly articles: ArticleEntity[]) {} +} + +@EventsHandler(IndexingArticleEvent) +export class IndexingArticleEventHandler + implements IEventHandler +{ + constructor(private readonly elasticSearch: SearchService) {} + async handle({ articles }: IndexingArticleEvent) { + await this.elasticSearch.bulkIndexArticles(articles); + } +} diff --git a/src/article/events/index.ts b/src/article/events/index.ts index b22e778..4e55602 100644 --- a/src/article/events/index.ts +++ b/src/article/events/index.ts @@ -6,6 +6,7 @@ import { ArticleUpdatedEventHandler, CommentCreatedEventHandler, CommentDeletedEventHandler, + IndexingArticleEventHandler, } from "./handlers"; export * from "./handlers"; @@ -19,4 +20,6 @@ export const EventHandlers = [ ArticleUnFavoritedEventHandler, CommentCreatedEventHandler, CommentDeletedEventHandler, + + IndexingArticleEventHandler, ]; diff --git a/src/article/queries/handlers/index.ts b/src/article/queries/handlers/index.ts index fd47847..832e298 100644 --- a/src/article/queries/handlers/index.ts +++ b/src/article/queries/handlers/index.ts @@ -3,3 +3,6 @@ export * from "./find-feed-article.handler"; export * from "./find-one-article.handler"; export * from "./find-comments.handler"; + +export * from "./indexing-article.handler"; +export * from "./search-article.handler"; diff --git a/src/article/queries/handlers/indexing-article.handler.ts b/src/article/queries/handlers/indexing-article.handler.ts new file mode 100644 index 0000000..806bcbd --- /dev/null +++ b/src/article/queries/handlers/indexing-article.handler.ts @@ -0,0 +1,51 @@ +import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; + +import { READ_CONNECTION } from "../../../config"; +import { PublisherService } from "../../../rabbitmq/publisher.service"; +import { ArticleEntity } from "../../core/entities/article.entity"; +import { ES_ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; +import { MessageType } from "../../core"; + +export class IndexingArticleQuery { + constructor() {} +} + +@QueryHandler(IndexingArticleQuery) +export class IndexingArticleQueryHandler + implements IQueryHandler +{ + constructor( + @InjectRepository(ArticleEntity, READ_CONNECTION) + private readonly articleRepository: Repository, + + private readonly publisher: PublisherService + ) {} + + async execute(_: IndexingArticleQuery): Promise { + const articles = await this.articleRepository.find({ + relations: ["author", "blocks"], + }); + + const chunkArticles = this.chunkArray(articles, 100); + + chunkArticles.forEach((articles: ArticleEntity[]) => { + this.publisher.publish(ES_ARTICLE_QUEUE, { + type: MessageType.INDEXING_ARTICLE, + payload: { articles }, + }); + }); + } + + private chunkArray(array: T[], chunkSize: number): T[][] { + const chunks: T[][] = []; + + for (let i = 0; i < array.length; i += chunkSize) { + const chunk = array.slice(i, i + chunkSize); + chunks.push(chunk); + } + + return chunks; + } +} diff --git a/src/article/queries/impl/index.ts b/src/article/queries/impl/index.ts index 5856675..c9576d2 100644 --- a/src/article/queries/impl/index.ts +++ b/src/article/queries/impl/index.ts @@ -5,3 +5,5 @@ export * from "./find-one-article.query"; export * from "./search-article.query"; export * from "./find-comments.query"; + +export * from "./search-article.query"; diff --git a/src/article/queries/index.ts b/src/article/queries/index.ts index 64680be..e7aa7d7 100644 --- a/src/article/queries/index.ts +++ b/src/article/queries/index.ts @@ -3,6 +3,8 @@ import { FindCommentQueryHandler, FindFeedArticleQueryHandler, FindOneArticleQueryHandler, + IndexingArticleQueryHandler, + SearchArticleQueryHandler, } from "./handlers"; export * from "./handlers"; @@ -13,4 +15,7 @@ export const QueryHandlers = [ FindFeedArticleQueryHandler, FindOneArticleQueryHandler, FindCommentQueryHandler, + + SearchArticleQueryHandler, + IndexingArticleQueryHandler, ]; diff --git a/src/article/queries/query.module.ts b/src/article/queries/query.module.ts index 99e4db9..62cc854 100644 --- a/src/article/queries/query.module.ts +++ b/src/article/queries/query.module.ts @@ -10,6 +10,7 @@ import { ArticleEntity } from "../core"; import { CommentEntity } from "../core/entities/comment.entity"; import { ArticleService } from "../services/article.service"; import { ElasticSearchModule } from "../../elastic-search/elastic-search.module"; +import { RabbitMqModule } from "../../rabbitmq/rabbitmq.module"; @Module({ imports: [ @@ -20,6 +21,7 @@ import { ElasticSearchModule } from "../../elastic-search/elastic-search.module" UserModule, CqrsModule, ElasticSearchModule, + RabbitMqModule, ], providers: [ArticleService, ...QueryHandlers], controllers: [], diff --git a/src/elastic-search/elastic-search.module.ts b/src/elastic-search/elastic-search.module.ts index a397a4e..099d2b5 100644 --- a/src/elastic-search/elastic-search.module.ts +++ b/src/elastic-search/elastic-search.module.ts @@ -13,6 +13,6 @@ import { SearchService } from "./elastic-search.service"; }), ], providers: [SearchService], - exports: [EsModule], + exports: [EsModule, SearchService], }) export class ElasticSearchModule {} diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index 935422b..8d5274b 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from "@nestjs/common"; +import { Injectable, Logger } from "@nestjs/common"; import { ElasticsearchService } from "@nestjs/elasticsearch"; import { ArticleEntity, IArticleSearchResult } from "../article/core"; @@ -8,6 +8,50 @@ export class SearchService { constructor(private readonly elasticsearchService: ElasticsearchService) {} + async bulkIndexArticles(articles: ArticleEntity[]) { + const body = articles.reduce((acc, article) => { + acc.push({ index: { _index: this.articleIndexes, _id: article.id } }); + acc.push({ + id: article.id, + title: article.title, + slug: article.slug, + description: article.description, + author: article.author.username, + blockText: article.blocks.map((block) => block.data.text), + }); + return acc; + }, []); + + try { + const bulkResponse = await this.elasticsearchService.bulk({ + refresh: true, // Refresh the index after the bulk operation (for testing purposes) + body, + }); + + if (bulkResponse.body.errors) { + // Handle errors in bulk indexing, if any + const erroredDocuments = []; + // Iterate through the items and collect errors, if any + bulkResponse.body.items.forEach((action, i) => { + const operation = Object.keys(action)[0]; + if (action[operation].error) { + erroredDocuments.push({ + index: i, + id: action[operation]._id, + error: action[operation].error, + }); + } + }); + Logger.error(`Bulk indexing errors: ${erroredDocuments}`); + } else { + Logger.log("Bulk indexing successful"); + } + } catch (error) { + Logger.error("Error during bulk indexing:", error); + throw error; + } + } + async indexArticle(article: ArticleEntity) { return this.elasticsearchService.index({ index: this.articleIndexes, @@ -35,7 +79,7 @@ export class SearchService { }, }, }); - const hits = response.hits.hits; + const hits = response.body.hits.hits; return hits.map((item) => item._source); } } diff --git a/src/rabbitmq/publisher.service.ts b/src/rabbitmq/publisher.service.ts index 08fb2ac..8eb6a22 100644 --- a/src/rabbitmq/publisher.service.ts +++ b/src/rabbitmq/publisher.service.ts @@ -5,6 +5,8 @@ import { ARTICLE_DL_ROUTE_KEY, ARTICLE_QUEUE, ARTICLE_ROUTE_KEY, + ES_ARTICLE_QUEUE, + ES_ARTICLE_ROUTE_KEY, PROFILE_DL_ROUTE_KEY, PROFILE_QUEUE, PROFILE_ROUTE_KEY, @@ -95,6 +97,25 @@ export class PublisherService { `Message type: ${message.type} sent to exchange ${RABBIT_EXCHANGE} with route key ${PROFILE_ROUTE_KEY}` ); break; + case ES_ARTICLE_QUEUE: + await this.channel.bindQueue( + ES_ARTICLE_QUEUE, + RABBIT_EXCHANGE, + ES_ARTICLE_ROUTE_KEY + ); + this.channel.publish( + RABBIT_EXCHANGE, + ES_ARTICLE_ROUTE_KEY, + Buffer.from(JSON.stringify(message)), + { + persistent: true, + } + ); + + Logger.log( + `Message type: ${message.type} sent to exchange ${RABBIT_EXCHANGE} with route key ${ES_ARTICLE_ROUTE_KEY}` + ); + break; default: break; } diff --git a/src/rabbitmq/rabbitmq.constants.ts b/src/rabbitmq/rabbitmq.constants.ts index 63cf24c..664dcd9 100644 --- a/src/rabbitmq/rabbitmq.constants.ts +++ b/src/rabbitmq/rabbitmq.constants.ts @@ -4,6 +4,7 @@ export const RABBIT_MQ_CONNECTION = "amqp://localhost:15672/"; export const RABBIT_EXCHANGE = "SOCIAL"; export const ARTICLE_ROUTE_KEY = "ARTICLE_ROUTE_KEY"; +export const ES_ARTICLE_ROUTE_KEY = "ARTICLE_ROUTE_KEY"; export const USER_ROUTE_KEY = "USER_ROUTE_KEY"; export const PROFILE_ROUTE_KEY = "PROFILECLE_ROUTE_KEY"; @@ -11,6 +12,9 @@ export const ARTICLE_QUEUE = "ARTICLE_QUEUE"; export const USER_QUEUE = "USER_QUEUE"; export const PROFILE_QUEUE = "PROFILE_QUEUE"; +// elastic +export const ES_ARTICLE_QUEUE = "ES_ARTICLE_QUEUE"; + // dead letter export const RABBIT_DL_EXCHANGE = "SOCIAL_DL"; diff --git a/yarn.lock b/yarn.lock index f977cb0..dd58cba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -293,25 +293,15 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@elastic/elasticsearch@^8.9.0": - version "8.9.0" - resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-8.9.0.tgz#d132021c6c12e4171fe14371609a5c69b535edd4" - integrity sha512-UyolnzjOYTRL2966TYS3IoJP4tQbvak/pmYmbP3JdphD53RjkyVDdxMpTBv+2LcNBRrvYPTzxQbpRW/nGSXA9g== +"@elastic/elasticsearch@^7.11.0": + version "7.17.12" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.17.12.tgz#b37f15c8e6a1952ad899e5a9ac3ad0824bf1d0a4" + integrity sha512-iypJDSzlnA1dXcw6H77qy0pH1Et8Nrw/TA6UHA7ECjKwZ9iBxZKS3WgOX0KgtL6GWdmTQWhGEha7k+ELVHygjQ== dependencies: - "@elastic/transport" "^8.3.2" - tslib "^2.4.0" - -"@elastic/transport@^8.3.2": - version "8.3.3" - resolved "https://registry.yarnpkg.com/@elastic/transport/-/transport-8.3.3.tgz#06c5b1b9566796775ac96d17959dafc269da5ec1" - integrity sha512-g5nc//dq/RQUTMkJUB8Ui8KJa/WflWmUa7yLl4SRZd67PPxIp3cn+OvGMNIhpiLRcfz1upanzgZHb/7Po2eEdQ== - dependencies: - debug "^4.3.4" - hpagent "^1.0.0" + debug "^4.3.1" + hpagent "^0.1.1" ms "^2.1.3" secure-json-parse "^2.4.0" - tslib "^2.4.0" - undici "^5.22.1" "@ioredis/commands@^1.1.1": version "1.2.0" @@ -582,10 +572,10 @@ dependencies: uuid "8.3.2" -"@nestjs/elasticsearch@^10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@nestjs/elasticsearch/-/elasticsearch-10.0.1.tgz#5aed1b699e5b3622c6522cbb7f78a16db549d652" - integrity sha512-rYkcuStF7oDbyt5X3h0BAYS3thZQm8vsHUkGot6dkB8dOTsSIsQJ8UYY9j66LhghzsBiewIwUrKkhY5WM2DVqA== +"@nestjs/elasticsearch@^7.1": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@nestjs/elasticsearch/-/elasticsearch-7.1.0.tgz#ba77a11d419b9aa542252a83b6490ef8c458fed4" + integrity sha512-3ixmu9MkTh0DS+LKAKcWHLyf/1DPQTXoy+aVClVI14DJQU208oHR3V0e9klApC+GXCYW+BDhNReh4HRyekjTrw== "@nestjs/mapped-types@0.4.1": version "0.4.1" @@ -1389,13 +1379,6 @@ busboy@^0.2.11: dicer "0.2.5" readable-stream "1.1.x" -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" @@ -2717,10 +2700,10 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== -hpagent@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-1.2.0.tgz#0ae417895430eb3770c03443456b8d90ca464903" - integrity sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA== +hpagent@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-0.1.2.tgz#cab39c66d4df2d4377dbd212295d878deb9bdaa9" + integrity sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ== html-encoding-sniffer@^1.0.2: version "1.0.2" @@ -5400,11 +5383,6 @@ streamsearch@0.1.2: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" integrity sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA== -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - string-length@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" @@ -5753,11 +5731,6 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== -tslib@^2.4.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -5860,13 +5833,6 @@ undefsafe@^2.0.2: resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== -undici@^5.22.1: - version "5.23.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.23.0.tgz#e7bdb0ed42cebe7b7aca87ced53e6eaafb8f8ca0" - integrity sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg== - dependencies: - busboy "^1.6.0" - uni-global@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/uni-global/-/uni-global-1.0.0.tgz#3583c449e87a2d9dc270ea221410a649bcdad040" From 8339f20af8a8beccb772dc1733aa273e2ec1dabd Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Sat, 26 Aug 2023 15:47:26 +0700 Subject: [PATCH 04/19] wip --- src/elastic-search/elastic-search.service.ts | 37 ++++++++++---------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index 8d5274b..074e77d 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -5,34 +5,35 @@ import { ArticleEntity, IArticleSearchResult } from "../article/core"; @Injectable() export class SearchService { private readonly articleIndexes = "articles"; + private readonly articleType = "article"; constructor(private readonly elasticsearchService: ElasticsearchService) {} async bulkIndexArticles(articles: ArticleEntity[]) { - const body = articles.reduce((acc, article) => { - acc.push({ index: { _index: this.articleIndexes, _id: article.id } }); - acc.push({ - id: article.id, - title: article.title, - slug: article.slug, - description: article.description, - author: article.author.username, - blockText: article.blocks.map((block) => block.data.text), - }); - return acc; - }, []); + const body = articles + .map((article) => [ + { index: { _index: this.articleIndexes, _id: article.id } }, + { + id: article.id, + title: article.title, + description: article.description, + author: article.author.username, + blockText: article.blocks.map((block) => block.data.text).join(" "), + }, + ]) + .reduce((acc, val) => acc.concat(val), []); try { - const bulkResponse = await this.elasticsearchService.bulk({ + const { body: bulkResponse } = await this.elasticsearchService.bulk({ refresh: true, // Refresh the index after the bulk operation (for testing purposes) body, }); - if (bulkResponse.body.errors) { + if (bulkResponse.errors) { // Handle errors in bulk indexing, if any const erroredDocuments = []; // Iterate through the items and collect errors, if any - bulkResponse.body.items.forEach((action, i) => { + bulkResponse.items.forEach((action, i) => { const operation = Object.keys(action)[0]; if (action[operation].error) { erroredDocuments.push({ @@ -42,7 +43,7 @@ export class SearchService { }); } }); - Logger.error(`Bulk indexing errors: ${erroredDocuments}`); + Logger.error("Bulk indexing errors:", erroredDocuments.toString()); } else { Logger.log("Bulk indexing successful"); } @@ -58,11 +59,11 @@ export class SearchService { body: { id: article.id, title: article.title, - slug: article.slug, description: article.description, author: article.author.username, blockText: article.blocks.map((block) => block.data.text), }, + type: this.articleType, }); } @@ -74,7 +75,7 @@ export class SearchService { query: { multi_match: { query: search, - fields: ["title", "description"], + fields: ["title", "description", "author", "blockText"], }, }, }, From e6e33f197ee3af5903647c0e135c314b56413639 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Sat, 26 Aug 2023 15:48:31 +0700 Subject: [PATCH 05/19] chore: remove TODO file --- src/article/article.controller.ts | 18 ++++++- src/article/queries/handlers/index.ts | 1 - .../handlers/indexing-article.handler.ts | 51 ------------------- src/article/queries/index.ts | 2 - 4 files changed, 17 insertions(+), 55 deletions(-) delete mode 100644 src/article/queries/handlers/indexing-article.handler.ts diff --git a/src/article/article.controller.ts b/src/article/article.controller.ts index 0499bef..099d132 100644 --- a/src/article/article.controller.ts +++ b/src/article/article.controller.ts @@ -28,12 +28,18 @@ import { UpdateArticleCommand, } from "./commands"; import { ArticleRO, ArticlesRO, CommentsRO } from "./core"; -import { ArticleFilters, CreateArticleDto, CreateCommentDto } from "./dto"; +import { + ArticleFilters, + CreateArticleDto, + CreateCommentDto, + SearchArticleDto, +} from "./dto"; import { FindAllArticleQuery, FindCommentQuery, FindFeedArticleQuery, FindOneArticleQuery, + SearchArticleQuery, } from "./queries"; @ApiBearerAuth() @@ -44,6 +50,16 @@ export class ArticleController { private readonly commandBus: CommandBus, private readonly queryBus: QueryBus ) {} + @ApiOperation({ summary: "Unfavorite article" }) + @ApiResponse({ + status: 201, + description: "The article has been successfully unfavorited.", + }) + @ApiResponse({ status: 403, description: "Forbidden." }) + @Get("search") + async search(@Query() query: SearchArticleDto) { + return this.queryBus.execute(new SearchArticleQuery(query)); + } @ApiOperation({ summary: "Get all articles" }) @ApiResponse({ status: 200, description: "Return all articles." }) diff --git a/src/article/queries/handlers/index.ts b/src/article/queries/handlers/index.ts index 832e298..a63665f 100644 --- a/src/article/queries/handlers/index.ts +++ b/src/article/queries/handlers/index.ts @@ -4,5 +4,4 @@ export * from "./find-one-article.handler"; export * from "./find-comments.handler"; -export * from "./indexing-article.handler"; export * from "./search-article.handler"; diff --git a/src/article/queries/handlers/indexing-article.handler.ts b/src/article/queries/handlers/indexing-article.handler.ts deleted file mode 100644 index 806bcbd..0000000 --- a/src/article/queries/handlers/indexing-article.handler.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; -import { InjectRepository } from "@nestjs/typeorm"; -import { Repository } from "typeorm"; - -import { READ_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { ES_ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { MessageType } from "../../core"; - -export class IndexingArticleQuery { - constructor() {} -} - -@QueryHandler(IndexingArticleQuery) -export class IndexingArticleQueryHandler - implements IQueryHandler -{ - constructor( - @InjectRepository(ArticleEntity, READ_CONNECTION) - private readonly articleRepository: Repository, - - private readonly publisher: PublisherService - ) {} - - async execute(_: IndexingArticleQuery): Promise { - const articles = await this.articleRepository.find({ - relations: ["author", "blocks"], - }); - - const chunkArticles = this.chunkArray(articles, 100); - - chunkArticles.forEach((articles: ArticleEntity[]) => { - this.publisher.publish(ES_ARTICLE_QUEUE, { - type: MessageType.INDEXING_ARTICLE, - payload: { articles }, - }); - }); - } - - private chunkArray(array: T[], chunkSize: number): T[][] { - const chunks: T[][] = []; - - for (let i = 0; i < array.length; i += chunkSize) { - const chunk = array.slice(i, i + chunkSize); - chunks.push(chunk); - } - - return chunks; - } -} diff --git a/src/article/queries/index.ts b/src/article/queries/index.ts index e7aa7d7..0f046a0 100644 --- a/src/article/queries/index.ts +++ b/src/article/queries/index.ts @@ -3,7 +3,6 @@ import { FindCommentQueryHandler, FindFeedArticleQueryHandler, FindOneArticleQueryHandler, - IndexingArticleQueryHandler, SearchArticleQueryHandler, } from "./handlers"; @@ -17,5 +16,4 @@ export const QueryHandlers = [ FindCommentQueryHandler, SearchArticleQueryHandler, - IndexingArticleQueryHandler, ]; From d89948c813feb32ba2bb4b1b0c9a8ad3b7af0e22 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Wed, 30 Aug 2023 22:10:20 +0700 Subject: [PATCH 06/19] feat: impl search engine --- src/article/article.controller.ts | 13 +++++ src/article/article.module.ts | 6 +-- .../core/interfaces/article.interface.ts | 15 ++++-- src/article/dto/search-article.ts | 2 +- src/article/events/event.module.ts | 2 +- .../handlers/indexing-article.handler.ts | 3 +- .../handlers/indexing-article.handler.ts | 51 +++++++++++++++++++ .../handlers/search-article.handler.ts | 39 +++++++------- src/article/queries/index.ts | 3 +- src/elastic-search/elastic-search.module.ts | 4 +- src/elastic-search/elastic-search.service.ts | 30 ++++++++--- src/main.ts | 7 ++- src/rabbitmq/rabbitmq.constants.ts | 2 +- 13 files changed, 137 insertions(+), 40 deletions(-) create mode 100644 src/article/queries/handlers/indexing-article.handler.ts diff --git a/src/article/article.controller.ts b/src/article/article.controller.ts index 099d132..91b6ff2 100644 --- a/src/article/article.controller.ts +++ b/src/article/article.controller.ts @@ -41,6 +41,7 @@ import { FindOneArticleQuery, SearchArticleQuery, } from "./queries"; +import { IndexingArticleQuery } from "./queries/handlers/indexing-article.handler"; @ApiBearerAuth() @ApiTags("articles") @@ -50,6 +51,18 @@ export class ArticleController { private readonly commandBus: CommandBus, private readonly queryBus: QueryBus ) {} + + @ApiOperation({ summary: "Unfavorite article" }) + @ApiResponse({ + status: 201, + description: "The article has been successfully unfavorited.", + }) + @ApiResponse({ status: 403, description: "Forbidden." }) + @Get("index") + async index() { + return this.queryBus.execute(new IndexingArticleQuery()); + } + @ApiOperation({ summary: "Unfavorite article" }) @ApiResponse({ status: 201, diff --git a/src/article/article.module.ts b/src/article/article.module.ts index aaeb3e3..21ab0bf 100644 --- a/src/article/article.module.ts +++ b/src/article/article.module.ts @@ -6,16 +6,16 @@ import { } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { RabbitMqModule } from "../rabbitmq/rabbitmq.module"; +import { RedisModule } from "../redis/redis.module"; import { AuthMiddleware } from "../user/auth.middleware"; import { UserModule } from "../user/user.module"; import { ArticleController } from "./article.controller"; import { ArticleProjection } from "./article.projection"; -import { ArticleService } from "./services/article.service"; import { CommandModule } from "./commands/command.module"; +import { ElasticSearchArticleProjection } from "./elastic-search-article.projection"; import { EventModule } from "./events/event.module"; import { QueryModule } from "./queries/query.module"; -import { RedisModule } from "../redis/redis.module"; -import { ElasticSearchArticleProjection } from "./elastic-search-article.projection"; +import { ArticleService } from "./services/article.service"; @Module({ imports: [ diff --git a/src/article/core/interfaces/article.interface.ts b/src/article/core/interfaces/article.interface.ts index a9c2100..09ec4e6 100644 --- a/src/article/core/interfaces/article.interface.ts +++ b/src/article/core/interfaces/article.interface.ts @@ -1,8 +1,7 @@ -import { BlockEntity } from "../entities/block.entity"; -import { IBlock } from "./block.interface"; import { ProfileData } from "../../../profile/core/interfaces/profile.interface"; import { IUser } from "../../../user/core/interfaces/user.interface"; -import { ArticleFilters } from "../../dto"; +import { BlockEntity } from "../entities/block.entity"; +import { IBlock } from "./block.interface"; // export interface Comment { // id: number; @@ -65,11 +64,19 @@ export interface IComment { author?: IUser | ProfileData; } +interface IArticleElasticSearch { + id: string; + title: string; + description: string; + author: string; + blockText: string; +} + export interface IArticleSearchResult { hits: { total: number; hits: Array<{ - _source: ArticleFilters; + _source: ArticleData; }>; }; } diff --git a/src/article/dto/search-article.ts b/src/article/dto/search-article.ts index ddf9164..948f107 100644 --- a/src/article/dto/search-article.ts +++ b/src/article/dto/search-article.ts @@ -8,5 +8,5 @@ export class SearchArticleDto { offset?: number; @ApiProperty({ required: true }) - search?: string; + search: string; } diff --git a/src/article/events/event.module.ts b/src/article/events/event.module.ts index c32eedc..7c7703b 100644 --- a/src/article/events/event.module.ts +++ b/src/article/events/event.module.ts @@ -15,7 +15,7 @@ import { ElasticSearchModule } from "../../elastic-search/elastic-search.module" READ_CONNECTION ), CqrsModule, - ElasticSearchModule + ElasticSearchModule, ], providers: [...EventHandlers], controllers: [], diff --git a/src/article/events/handlers/indexing-article.handler.ts b/src/article/events/handlers/indexing-article.handler.ts index fac1bf0..c36a92c 100644 --- a/src/article/events/handlers/indexing-article.handler.ts +++ b/src/article/events/handlers/indexing-article.handler.ts @@ -1,8 +1,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; -import { SearchService } from "../../../elastic-search/elastic-search.service"; import { ArticleEntity } from "../../core/entities/article.entity"; +import { SearchService } from "../../../elastic-search/elastic-search.service"; export class IndexingArticleEvent { constructor(public readonly articles: ArticleEntity[]) {} @@ -13,6 +13,7 @@ export class IndexingArticleEventHandler implements IEventHandler { constructor(private readonly elasticSearch: SearchService) {} + async handle({ articles }: IndexingArticleEvent) { await this.elasticSearch.bulkIndexArticles(articles); } diff --git a/src/article/queries/handlers/indexing-article.handler.ts b/src/article/queries/handlers/indexing-article.handler.ts new file mode 100644 index 0000000..806bcbd --- /dev/null +++ b/src/article/queries/handlers/indexing-article.handler.ts @@ -0,0 +1,51 @@ +import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; + +import { READ_CONNECTION } from "../../../config"; +import { PublisherService } from "../../../rabbitmq/publisher.service"; +import { ArticleEntity } from "../../core/entities/article.entity"; +import { ES_ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; +import { MessageType } from "../../core"; + +export class IndexingArticleQuery { + constructor() {} +} + +@QueryHandler(IndexingArticleQuery) +export class IndexingArticleQueryHandler + implements IQueryHandler +{ + constructor( + @InjectRepository(ArticleEntity, READ_CONNECTION) + private readonly articleRepository: Repository, + + private readonly publisher: PublisherService + ) {} + + async execute(_: IndexingArticleQuery): Promise { + const articles = await this.articleRepository.find({ + relations: ["author", "blocks"], + }); + + const chunkArticles = this.chunkArray(articles, 100); + + chunkArticles.forEach((articles: ArticleEntity[]) => { + this.publisher.publish(ES_ARTICLE_QUEUE, { + type: MessageType.INDEXING_ARTICLE, + payload: { articles }, + }); + }); + } + + private chunkArray(array: T[], chunkSize: number): T[][] { + const chunks: T[][] = []; + + for (let i = 0; i < array.length; i += chunkSize) { + const chunk = array.slice(i, i + chunkSize); + chunks.push(chunk); + } + + return chunks; + } +} diff --git a/src/article/queries/handlers/search-article.handler.ts b/src/article/queries/handlers/search-article.handler.ts index 132d525..ef72266 100644 --- a/src/article/queries/handlers/search-article.handler.ts +++ b/src/article/queries/handlers/search-article.handler.ts @@ -1,31 +1,32 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; -import { InjectRepository } from "@nestjs/typeorm"; -import { Repository } from "typeorm"; +import { ElasticsearchService } from "@nestjs/elasticsearch"; -import { READ_CONNECTION } from "../../../config"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { ArticlesRO } from "../../core/interfaces/article.interface"; -import { ArticleService } from "../../services/article.service"; +import { IArticleSearchResult } from "../../core/interfaces/article.interface"; import { SearchArticleQuery } from "../impl"; -import { SearchService } from "../../../elastic-search/elastic-search.service"; @QueryHandler(SearchArticleQuery) export class SearchArticleQueryHandler implements IQueryHandler { - constructor( - @InjectRepository(UserEntity, READ_CONNECTION) - private readonly userRepository: Repository, - @InjectRepository(ArticleEntity, READ_CONNECTION) - private readonly articleRepository: Repository, - - private readonly articleService: ArticleService, - - private readonly elasticSearch: SearchService - ) {} + constructor(private readonly elasticsearchService: ElasticsearchService) {} async execute({ query }: SearchArticleQuery): Promise { - return this.elasticSearch.searchArticles(query.search); + const response = + await this.elasticsearchService.search({ + index: "articles", // TODO: replace by constant + body: { + from: query.limit || 0, + size: query.offset || 10, + query: { + multi_match: { + query: query.search, + fields: ["title", "description", "author", "blocks"], + }, + }, + }, + }); + const hits = response.body.hits.hits; + const articleEs = hits.map((item) => item._source); + return articleEs; } } diff --git a/src/article/queries/index.ts b/src/article/queries/index.ts index 0f046a0..f5b6ba7 100644 --- a/src/article/queries/index.ts +++ b/src/article/queries/index.ts @@ -1,3 +1,4 @@ +import { IndexingArticleQueryHandler } from "./handlers/indexing-article.handler"; import { FindAllArticleQueryHandler, FindCommentQueryHandler, @@ -14,6 +15,6 @@ export const QueryHandlers = [ FindFeedArticleQueryHandler, FindOneArticleQueryHandler, FindCommentQueryHandler, - + IndexingArticleQueryHandler, SearchArticleQueryHandler, ]; diff --git a/src/elastic-search/elastic-search.module.ts b/src/elastic-search/elastic-search.module.ts index 099d2b5..6438c2c 100644 --- a/src/elastic-search/elastic-search.module.ts +++ b/src/elastic-search/elastic-search.module.ts @@ -5,7 +5,9 @@ import { SearchService } from "./elastic-search.service"; @Module({ imports: [ EsModule.register({ - node: process.env.ELASTICSEARCH_NODE, + cloud: { + id: process.env.ELASTICSEARCH_CLOUD_ID, + }, auth: { username: process.env.ELASTICSEARCH_USERNAME, password: process.env.ELASTICSEARCH_PASSWORD, diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index 074e77d..56841cf 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -15,10 +15,18 @@ export class SearchService { { index: { _index: this.articleIndexes, _id: article.id } }, { id: article.id, - title: article.title, + slug: article.slug, description: article.description, - author: article.author.username, - blockText: article.blocks.map((block) => block.data.text).join(" "), + blocks: article.blocks.map((block) => block.data.text), + tagList: article.tagList, + createdAt: article.created, + updatedAt: article.updated, + favoritesCount: article.favoriteCount, + author: { + username: article.author?.username, + bio: article.author?.bio, + image: article.author?.image, + }, }, ]) .reduce((acc, val) => acc.concat(val), []); @@ -58,10 +66,18 @@ export class SearchService { index: this.articleIndexes, body: { id: article.id, - title: article.title, + slug: article.slug, description: article.description, - author: article.author.username, - blockText: article.blocks.map((block) => block.data.text), + blocks: article.blocks.map((block) => block.data.text), + tagList: article.tagList, + createdAt: article.created, + updatedAt: article.updated, + favoritesCount: article.favoriteCount, + author: { + username: article.author?.username, + bio: article.author?.bio, + image: article.author?.image, + }, }, type: this.articleType, }); @@ -75,7 +91,7 @@ export class SearchService { query: { multi_match: { query: search, - fields: ["title", "description", "author", "blockText"], + fields: ["title", "description", "author", "blocks.data.text"], }, }, }, diff --git a/src/main.ts b/src/main.ts index 38de3e9..db769d6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,13 +9,18 @@ import { ApplicationModule } from "./app.module"; import { ArticleProjection } from "./article/article.projection"; import { UserProjection } from "./user/user.projection"; import { ProfileProjection } from "./profile/profile.projection"; +import { ElasticSearchArticleProjection } from "./article/elastic-search-article.projection"; async function executeProjection(app: INestApplication) { const articleProjection = app.get(ArticleProjection); + const elasticSearchArticleProjection = app.get( + ElasticSearchArticleProjection + ); const userProjection = app.get(UserProjection); const profileProjection = app.get(ProfileProjection); await articleProjection.handle(); + await elasticSearchArticleProjection.handle(); await userProjection.handle(); await profileProjection.handle(); } @@ -25,7 +30,7 @@ async function bootstrap() { const numWorkers = os.cpus().length; console.log(`Master cluster setting up ${numWorkers} workers...`); - for (let i = 0; i < numWorkers; i++) { + for (let i = 0; i < 1; i++) { cluster.fork(); } diff --git a/src/rabbitmq/rabbitmq.constants.ts b/src/rabbitmq/rabbitmq.constants.ts index 664dcd9..a9f958e 100644 --- a/src/rabbitmq/rabbitmq.constants.ts +++ b/src/rabbitmq/rabbitmq.constants.ts @@ -4,7 +4,7 @@ export const RABBIT_MQ_CONNECTION = "amqp://localhost:15672/"; export const RABBIT_EXCHANGE = "SOCIAL"; export const ARTICLE_ROUTE_KEY = "ARTICLE_ROUTE_KEY"; -export const ES_ARTICLE_ROUTE_KEY = "ARTICLE_ROUTE_KEY"; +export const ES_ARTICLE_ROUTE_KEY = "ES_ARTICLE_ROUTE_KEY"; export const USER_ROUTE_KEY = "USER_ROUTE_KEY"; export const PROFILE_ROUTE_KEY = "PROFILECLE_ROUTE_KEY"; From ff006fbf47f7f0fb887f42aee5c739f673d14784 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Wed, 30 Aug 2023 22:36:14 +0700 Subject: [PATCH 07/19] chore: update .env --- src/rabbitmq/rabbitmq.module.ts | 9 +-------- src/redis/redis.module.ts | 16 +--------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/rabbitmq/rabbitmq.module.ts b/src/rabbitmq/rabbitmq.module.ts index fd028af..40f07e2 100644 --- a/src/rabbitmq/rabbitmq.module.ts +++ b/src/rabbitmq/rabbitmq.module.ts @@ -9,14 +9,7 @@ import { PublisherService } from "./publisher.service"; { provide: "RABBIT_MQ_CONNECTION", useFactory: async (): Promise => { - if (process.env.NODE_ENV === "development") { - return ( - connect("amqp://localhost") || connect(process.env.RABBIT_URL_DEV) - ); - } - if (process.env.NODE_ENV === "staging") { - return connect(process.env.RABBIT_URL); - } + return connect(process.env.RABBIT_URL); }, }, PublisherService, diff --git a/src/redis/redis.module.ts b/src/redis/redis.module.ts index f2430dc..e00a096 100644 --- a/src/redis/redis.module.ts +++ b/src/redis/redis.module.ts @@ -7,21 +7,7 @@ import { RedisService } from "./redis.service"; { provide: "REDIS_CLIENT", useFactory: () => { - if (process.env.NODE_ENV === "development") { - return new Redis({ - host: "localhost", - port: 6379, - }); - } - if (process.env.NODE_ENV === "staging") { - return new Redis({ - host: process.env.REDIS_HOST, - port: parseInt(process.env.REDIS_PORT), - }); - } - if (process.env.NODE_ENV === "RENDER") { - return new Redis(process.env.REDIS_URL); - } + return new Redis(process.env.REDIS_URL); }, }, RedisService, From 4763ef61e345246809234e8745c4e09235793326 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Fri, 1 Sep 2023 10:37:14 +0700 Subject: [PATCH 08/19] update: config CORS --- src/main.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index db769d6..9388261 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,7 @@ import { NestFactory } from "@nestjs/core"; import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger"; import { json, urlencoded } from "express"; -import { INestApplication } from "@nestjs/common"; +import { INestApplication, NestApplicationOptions } from "@nestjs/common"; import * as cluster from "cluster"; import * as os from "os"; @@ -46,7 +46,11 @@ async function bootstrap() { cluster.fork(); }); } else { - const appOptions = { cors: true }; + const appOptions: NestApplicationOptions = { + cors: { + origin: [process.env.CORS_ORIGIN], + }, + }; const app = await NestFactory.create(ApplicationModule, appOptions); app.use(json({ limit: "50mb" })); app.use(urlencoded({ extended: true, limit: "50mb" })); From 84fc28e1f047f09e6f3cb3b83a5c0102d43c3799 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Fri, 13 Oct 2023 14:43:22 +0700 Subject: [PATCH 09/19] feat: apply CLEAN Architect for user-module --- .gitignore | 1 + src/article/article.controller.ts | 2 +- src/article/article.module.ts | 2 +- src/main.ts | 2 +- src/media/media.module.ts | 2 +- src/profile/profile.controller.ts | 2 +- src/profile/profile.module.ts | 2 +- src/rabbitmq/rabbitmq.module.ts | 1 + .../middleware}/auth.middleware.ts | 8 ++++---- src/{user => shared/middleware}/user.decorator.ts | 4 ++-- .../{ => application}/commands/command.module.ts | 10 +++++----- .../commands/handlers/create-user.handler.ts | 12 ++++++------ .../{ => application}/commands/handlers/index.ts | 0 .../commands/handlers/update-user.handler.ts | 12 ++++++------ .../commands/impl/create-user.command.ts | 2 +- src/user/{ => application}/commands/impl/index.ts | 0 .../commands/impl/update-user.command.ts | 2 +- src/user/{ => application}/commands/index.ts | 0 src/user/{ => application}/events/event.module.ts | 6 +++--- .../{ => application}/events/handlers/index.ts | 0 .../events/handlers/user-created.handler.ts | 4 ++-- .../events/handlers/user-updated.handler.ts | 4 ++-- src/user/{ => application}/events/impl/index.ts | 0 .../events/impl/user-created.event.ts | 2 +- .../events/impl/user-updated.event.ts | 2 +- src/user/{ => application}/events/index.ts | 0 .../handlers/find-user-by-email.handler.ts | 8 ++++---- .../queries/handlers/find-user-by-id.handler.ts | 12 ++++++------ .../{ => application}/queries/handlers/index.ts | 0 .../queries/handlers/login.handler.ts | 12 ++++++------ .../queries/impl/find-user-by-email.query.ts | 0 .../queries/impl/find-user-by-id.query.ts | 0 src/user/{ => application}/queries/impl/index.ts | 0 .../{ => application}/queries/impl/login.query.ts | 2 +- src/user/{ => application}/queries/index.ts | 0 .../{ => application}/queries/query.module.ts | 10 +++++----- .../{ => application}/services/auth.service.ts | 0 .../{ => application}/services/user.service.ts | 4 ++-- src/user/{ => application}/user.projection.ts | 8 ++++---- src/user/{ => core}/dto/create-user.dto.ts | 0 src/user/{ => core}/dto/index.ts | 0 src/user/{ => core}/dto/login-user.dto.ts | 0 src/user/{ => core}/dto/update-user.dto.ts | 0 src/user/{ => presentation}/user.controller.ts | 13 +++++++------ src/user/user.module.ts | 15 ++++++++------- 45 files changed, 85 insertions(+), 81 deletions(-) rename src/{user => shared/middleware}/auth.middleware.ts (85%) rename src/{user => shared/middleware}/user.decorator.ts (86%) rename src/user/{ => application}/commands/command.module.ts (65%) rename src/user/{ => application}/commands/handlers/create-user.handler.ts (85%) rename src/user/{ => application}/commands/handlers/index.ts (100%) rename src/user/{ => application}/commands/handlers/update-user.handler.ts (77%) rename src/user/{ => application}/commands/impl/create-user.command.ts (63%) rename src/user/{ => application}/commands/impl/index.ts (100%) rename src/user/{ => application}/commands/impl/update-user.command.ts (69%) rename src/user/{ => application}/commands/index.ts (100%) rename src/user/{ => application}/events/event.module.ts (71%) rename src/user/{ => application}/events/handlers/index.ts (100%) rename src/user/{ => application}/events/handlers/user-created.handler.ts (86%) rename src/user/{ => application}/events/handlers/user-updated.handler.ts (86%) rename src/user/{ => application}/events/impl/index.ts (100%) rename src/user/{ => application}/events/impl/user-created.event.ts (56%) rename src/user/{ => application}/events/impl/user-updated.event.ts (56%) rename src/user/{ => application}/events/index.ts (100%) rename src/user/{ => application}/queries/handlers/find-user-by-email.handler.ts (76%) rename src/user/{ => application}/queries/handlers/find-user-by-id.handler.ts (75%) rename src/user/{ => application}/queries/handlers/index.ts (100%) rename src/user/{ => application}/queries/handlers/login.handler.ts (80%) rename src/user/{ => application}/queries/impl/find-user-by-email.query.ts (100%) rename src/user/{ => application}/queries/impl/find-user-by-id.query.ts (100%) rename src/user/{ => application}/queries/impl/index.ts (100%) rename src/user/{ => application}/queries/impl/login.query.ts (64%) rename src/user/{ => application}/queries/index.ts (100%) rename src/user/{ => application}/queries/query.module.ts (66%) rename src/user/{ => application}/services/auth.service.ts (100%) rename src/user/{ => application}/services/user.service.ts (87%) rename src/user/{ => application}/user.projection.ts (77%) rename src/user/{ => core}/dto/create-user.dto.ts (100%) rename src/user/{ => core}/dto/index.ts (100%) rename src/user/{ => core}/dto/login-user.dto.ts (100%) rename src/user/{ => core}/dto/update-user.dto.ts (100%) rename src/user/{ => presentation}/user.controller.ts (78%) diff --git a/.gitignore b/.gitignore index 6d3c07c..8d83aa9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,5 +22,6 @@ dist/* .env .env.development +.env.docker app.yaml \ No newline at end of file diff --git a/src/article/article.controller.ts b/src/article/article.controller.ts index 91b6ff2..fef294d 100644 --- a/src/article/article.controller.ts +++ b/src/article/article.controller.ts @@ -17,7 +17,7 @@ import { ApiResponse, ApiTags, } from "@nestjs/swagger"; -import { User } from "../user/user.decorator"; +import { User } from "../shared/middleware/user.decorator"; import { CreateArticleCommand, CreateCommentCommand, diff --git a/src/article/article.module.ts b/src/article/article.module.ts index 21ab0bf..2b9c0db 100644 --- a/src/article/article.module.ts +++ b/src/article/article.module.ts @@ -7,7 +7,7 @@ import { import { CqrsModule } from "@nestjs/cqrs"; import { RabbitMqModule } from "../rabbitmq/rabbitmq.module"; import { RedisModule } from "../redis/redis.module"; -import { AuthMiddleware } from "../user/auth.middleware"; +import { AuthMiddleware } from "../shared/middleware/auth.middleware"; import { UserModule } from "../user/user.module"; import { ArticleController } from "./article.controller"; import { ArticleProjection } from "./article.projection"; diff --git a/src/main.ts b/src/main.ts index 9388261..dadbea3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,7 +7,7 @@ import * as os from "os"; import { ApplicationModule } from "./app.module"; import { ArticleProjection } from "./article/article.projection"; -import { UserProjection } from "./user/user.projection"; +import { UserProjection } from "./user/application/user.projection"; import { ProfileProjection } from "./profile/profile.projection"; import { ElasticSearchArticleProjection } from "./article/elastic-search-article.projection"; diff --git a/src/media/media.module.ts b/src/media/media.module.ts index d872f55..6d70335 100644 --- a/src/media/media.module.ts +++ b/src/media/media.module.ts @@ -5,7 +5,7 @@ import { RequestMethod, } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; -import { AuthMiddleware } from "../user/auth.middleware"; +import { AuthMiddleware } from "../shared/middleware/auth.middleware"; import { UserModule } from "../user/user.module"; import { DropboxService } from "./services/dropbox.service"; import { MediaController } from "./media.controller"; diff --git a/src/profile/profile.controller.ts b/src/profile/profile.controller.ts index 2680946..ae313cc 100644 --- a/src/profile/profile.controller.ts +++ b/src/profile/profile.controller.ts @@ -1,7 +1,7 @@ import { Controller, Delete, Get, Param, Post } from "@nestjs/common"; import { CommandBus, QueryBus } from "@nestjs/cqrs"; import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger"; -import { User } from "../user/user.decorator"; +import { User } from "../shared/middleware/user.decorator"; import { FollowProfileCommand, UnFollowProfileCommand } from "./commands"; import { FindProfileQuery } from "./queries"; import { ProfileRO } from "./core/interfaces/profile.interface"; diff --git a/src/profile/profile.module.ts b/src/profile/profile.module.ts index b9ac4bc..1a3b5d8 100644 --- a/src/profile/profile.module.ts +++ b/src/profile/profile.module.ts @@ -6,7 +6,7 @@ import { } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { RabbitMqModule } from "../rabbitmq/rabbitmq.module"; -import { AuthMiddleware } from "../user/auth.middleware"; +import { AuthMiddleware } from "../shared/middleware/auth.middleware"; import { UserModule } from "../user/user.module"; import { CommandModule } from "./commands/command.module"; import { EventModule } from "./events/event.module"; diff --git a/src/rabbitmq/rabbitmq.module.ts b/src/rabbitmq/rabbitmq.module.ts index 40f07e2..c1b0d41 100644 --- a/src/rabbitmq/rabbitmq.module.ts +++ b/src/rabbitmq/rabbitmq.module.ts @@ -1,5 +1,6 @@ import { Module } from "@nestjs/common"; import { connect, Connection } from "amqplib"; + import { ConsumerService } from "./consumer.service"; import { PublisherService } from "./publisher.service"; diff --git a/src/user/auth.middleware.ts b/src/shared/middleware/auth.middleware.ts similarity index 85% rename from src/user/auth.middleware.ts rename to src/shared/middleware/auth.middleware.ts index 58d93f2..c99ec7c 100644 --- a/src/user/auth.middleware.ts +++ b/src/shared/middleware/auth.middleware.ts @@ -4,10 +4,10 @@ import { QueryBus } from "@nestjs/cqrs"; import { NextFunction, Request, Response } from "express"; import { IncomingHttpHeaders } from "http"; import * as jwt from "jsonwebtoken"; -import { SECRET } from "../config"; -import { FindUserById } from "./queries"; -import { UserData } from "./core/interfaces/user.interface"; -import { RedisService } from "../redis/redis.service"; +import { SECRET } from "../../config"; +import { FindUserById } from "../../user/application/queries"; +import { UserData } from "../../user/core/interfaces/user.interface"; +import { RedisService } from "../../redis/redis.service"; interface IRequestCustom extends Request { user: UserData; diff --git a/src/user/user.decorator.ts b/src/shared/middleware/user.decorator.ts similarity index 86% rename from src/user/user.decorator.ts rename to src/shared/middleware/user.decorator.ts index d2fbfda..f6748e4 100644 --- a/src/user/user.decorator.ts +++ b/src/shared/middleware/user.decorator.ts @@ -1,7 +1,7 @@ import { createParamDecorator, ExecutionContext } from "@nestjs/common"; -import { SECRET } from "../config"; +import { SECRET } from "../../config"; import * as jwt from "jsonwebtoken"; -import { CurrentUser } from "./core/interfaces/user.interface"; +import { CurrentUser } from "../../user/core/interfaces/user.interface"; export const User = createParamDecorator((data: any, ctx: ExecutionContext) => { const req = ctx.switchToHttp().getRequest(); diff --git a/src/user/commands/command.module.ts b/src/user/application/commands/command.module.ts similarity index 65% rename from src/user/commands/command.module.ts rename to src/user/application/commands/command.module.ts index 26d0662..c35a950 100644 --- a/src/user/commands/command.module.ts +++ b/src/user/application/commands/command.module.ts @@ -1,11 +1,11 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; + import { CommandHandlers } from "."; -import { WRITE_CONNECTION } from "../../config"; -import { RabbitMqModule } from "../../rabbitmq/rabbitmq.module"; -import { UserController } from "../user.controller"; -import { UserEntity } from "../core"; +import { WRITE_CONNECTION } from "../../../config"; +import { RabbitMqModule } from "../../../rabbitmq/rabbitmq.module"; +import { UserEntity } from "../../core"; import { UserService } from "../services/user.service"; @Module({ @@ -15,7 +15,7 @@ import { UserService } from "../services/user.service"; RabbitMqModule, ], providers: [UserService, ...CommandHandlers], - controllers: [UserController], + controllers: [], exports: [], }) export class CommandModule {} diff --git a/src/user/commands/handlers/create-user.handler.ts b/src/user/application/commands/handlers/create-user.handler.ts similarity index 85% rename from src/user/commands/handlers/create-user.handler.ts rename to src/user/application/commands/handlers/create-user.handler.ts index 6381ff3..338a5d6 100644 --- a/src/user/commands/handlers/create-user.handler.ts +++ b/src/user/application/commands/handlers/create-user.handler.ts @@ -3,12 +3,12 @@ import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { validate } from "class-validator"; import { getRepository, Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { USER_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { UserEntity } from "../../core/entities/user.entity"; -import { MessageType } from "../../core/enums/user.enum"; -import { UserRO } from "../../core/interfaces/user.interface"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { USER_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { UserEntity } from "../../../core/entities/user.entity"; +import { MessageType } from "../../../core/enums/user.enum"; +import { UserRO } from "../../../core/interfaces/user.interface"; import { UserService } from "../../services/user.service"; import { CreateUserCommand } from "../impl"; diff --git a/src/user/commands/handlers/index.ts b/src/user/application/commands/handlers/index.ts similarity index 100% rename from src/user/commands/handlers/index.ts rename to src/user/application/commands/handlers/index.ts diff --git a/src/user/commands/handlers/update-user.handler.ts b/src/user/application/commands/handlers/update-user.handler.ts similarity index 77% rename from src/user/commands/handlers/update-user.handler.ts rename to src/user/application/commands/handlers/update-user.handler.ts index a8522eb..a0be96e 100644 --- a/src/user/commands/handlers/update-user.handler.ts +++ b/src/user/application/commands/handlers/update-user.handler.ts @@ -2,12 +2,12 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { USER_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { UserEntity } from "../../core/entities/user.entity"; -import { MessageType } from "../../core/enums/user.enum"; -import { UserRO } from "../../core/interfaces/user.interface"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { USER_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { UserEntity } from "../../../core/entities/user.entity"; +import { MessageType } from "../../../core/enums/user.enum"; +import { UserRO } from "../../../core/interfaces/user.interface"; import { UserService } from "../../services/user.service"; import { UpdateUserCommand } from "../impl"; diff --git a/src/user/commands/impl/create-user.command.ts b/src/user/application/commands/impl/create-user.command.ts similarity index 63% rename from src/user/commands/impl/create-user.command.ts rename to src/user/application/commands/impl/create-user.command.ts index 8edfb46..3d81841 100644 --- a/src/user/commands/impl/create-user.command.ts +++ b/src/user/application/commands/impl/create-user.command.ts @@ -1,4 +1,4 @@ -import { CreateUserDto } from "../../dto"; +import { CreateUserDto } from "../../../core/dto"; export class CreateUserCommand { constructor(public readonly dto: CreateUserDto) {} diff --git a/src/user/commands/impl/index.ts b/src/user/application/commands/impl/index.ts similarity index 100% rename from src/user/commands/impl/index.ts rename to src/user/application/commands/impl/index.ts diff --git a/src/user/commands/impl/update-user.command.ts b/src/user/application/commands/impl/update-user.command.ts similarity index 69% rename from src/user/commands/impl/update-user.command.ts rename to src/user/application/commands/impl/update-user.command.ts index 0eca571..55b69b8 100644 --- a/src/user/commands/impl/update-user.command.ts +++ b/src/user/application/commands/impl/update-user.command.ts @@ -1,4 +1,4 @@ -import { UpdateUserDto } from "../../dto"; +import { UpdateUserDto } from "../../../core/dto"; export class UpdateUserCommand { constructor(public readonly id: number, public readonly dto: UpdateUserDto) {} diff --git a/src/user/commands/index.ts b/src/user/application/commands/index.ts similarity index 100% rename from src/user/commands/index.ts rename to src/user/application/commands/index.ts diff --git a/src/user/events/event.module.ts b/src/user/application/events/event.module.ts similarity index 71% rename from src/user/events/event.module.ts rename to src/user/application/events/event.module.ts index 7f46ff8..4b9c93c 100644 --- a/src/user/events/event.module.ts +++ b/src/user/application/events/event.module.ts @@ -1,9 +1,9 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; -import { READ_CONNECTION } from "../../config"; -import { UserEntity } from "../core"; -import { EventHandlers } from "../events"; +import { READ_CONNECTION } from "../../../config"; +import { UserEntity } from "../../core"; +import { EventHandlers } from "."; @Module({ imports: [ diff --git a/src/user/events/handlers/index.ts b/src/user/application/events/handlers/index.ts similarity index 100% rename from src/user/events/handlers/index.ts rename to src/user/application/events/handlers/index.ts diff --git a/src/user/events/handlers/user-created.handler.ts b/src/user/application/events/handlers/user-created.handler.ts similarity index 86% rename from src/user/events/handlers/user-created.handler.ts rename to src/user/application/events/handlers/user-created.handler.ts index d118158..fb2aaff 100644 --- a/src/user/events/handlers/user-created.handler.ts +++ b/src/user/application/events/handlers/user-created.handler.ts @@ -3,8 +3,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { UserEntity } from "../../core/entities/user.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { UserEntity } from "../../../core/entities/user.entity"; import { UserCreatedEvent } from "../impl"; @EventsHandler(UserCreatedEvent) diff --git a/src/user/events/handlers/user-updated.handler.ts b/src/user/application/events/handlers/user-updated.handler.ts similarity index 86% rename from src/user/events/handlers/user-updated.handler.ts rename to src/user/application/events/handlers/user-updated.handler.ts index a75b582..045554f 100644 --- a/src/user/events/handlers/user-updated.handler.ts +++ b/src/user/application/events/handlers/user-updated.handler.ts @@ -3,8 +3,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { UserEntity } from "../../core/entities/user.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { UserEntity } from "../../../core/entities/user.entity"; import { UserUpdatedEvent } from "../impl"; @EventsHandler(UserUpdatedEvent) diff --git a/src/user/events/impl/index.ts b/src/user/application/events/impl/index.ts similarity index 100% rename from src/user/events/impl/index.ts rename to src/user/application/events/impl/index.ts diff --git a/src/user/events/impl/user-created.event.ts b/src/user/application/events/impl/user-created.event.ts similarity index 56% rename from src/user/events/impl/user-created.event.ts rename to src/user/application/events/impl/user-created.event.ts index 4d38585..702e7b3 100644 --- a/src/user/events/impl/user-created.event.ts +++ b/src/user/application/events/impl/user-created.event.ts @@ -1,4 +1,4 @@ -import { UserEntity } from "../../core/entities/user.entity"; +import { UserEntity } from "../../../core/entities/user.entity"; export class UserCreatedEvent { constructor(public readonly user: UserEntity) {} diff --git a/src/user/events/impl/user-updated.event.ts b/src/user/application/events/impl/user-updated.event.ts similarity index 56% rename from src/user/events/impl/user-updated.event.ts rename to src/user/application/events/impl/user-updated.event.ts index 9b2a28f..797c103 100644 --- a/src/user/events/impl/user-updated.event.ts +++ b/src/user/application/events/impl/user-updated.event.ts @@ -1,4 +1,4 @@ -import { UserEntity } from "../../core/entities/user.entity"; +import { UserEntity } from "../../../core/entities/user.entity"; export class UserUpdatedEvent { constructor(public readonly user: UserEntity) {} diff --git a/src/user/events/index.ts b/src/user/application/events/index.ts similarity index 100% rename from src/user/events/index.ts rename to src/user/application/events/index.ts diff --git a/src/user/queries/handlers/find-user-by-email.handler.ts b/src/user/application/queries/handlers/find-user-by-email.handler.ts similarity index 76% rename from src/user/queries/handlers/find-user-by-email.handler.ts rename to src/user/application/queries/handlers/find-user-by-email.handler.ts index bf42c2e..e86d755 100644 --- a/src/user/queries/handlers/find-user-by-email.handler.ts +++ b/src/user/application/queries/handlers/find-user-by-email.handler.ts @@ -1,10 +1,10 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { RedisService } from "../../../redis/redis.service"; -import { UserEntity } from "../../core/entities/user.entity"; -import { UserRO } from "../../core/interfaces/user.interface"; +import { READ_CONNECTION } from "../../../../config"; +import { RedisService } from "../../../../redis/redis.service"; +import { UserEntity } from "../../../core/entities/user.entity"; +import { UserRO } from "../../../core/interfaces/user.interface"; import { FindUserByEmailQuery } from "../impl"; @QueryHandler(FindUserByEmailQuery) diff --git a/src/user/queries/handlers/find-user-by-id.handler.ts b/src/user/application/queries/handlers/find-user-by-id.handler.ts similarity index 75% rename from src/user/queries/handlers/find-user-by-id.handler.ts rename to src/user/application/queries/handlers/find-user-by-id.handler.ts index 09a9c32..0295e4d 100644 --- a/src/user/queries/handlers/find-user-by-id.handler.ts +++ b/src/user/application/queries/handlers/find-user-by-id.handler.ts @@ -2,10 +2,10 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { RedisService } from "../../../redis/redis.service"; -import { UserEntity } from "../../core/entities/user.entity"; -import { UserRO } from "../../core/interfaces/user.interface"; +import { READ_CONNECTION } from "../../../../config"; +import { RedisService } from "../../../../redis/redis.service"; +import { UserEntity } from "../../../core/entities/user.entity"; +import { UserRO } from "../../../core/interfaces/user.interface"; import { UserService } from "../../services/user.service"; import { FindUserById } from "../impl"; @@ -17,12 +17,12 @@ export class FindUserByIdHandler implements IQueryHandler { private readonly userService: UserService, private readonly redisCacheService: RedisService - ) { } + ) {} async execute({ id }: FindUserById): Promise { let user: UserEntity; - user = await this.redisCacheService.get(id.toString()) as UserEntity; + user = (await this.redisCacheService.get(id.toString())) as UserEntity; if (!user) { user = await this.userRepository.findOne(id); diff --git a/src/user/queries/handlers/index.ts b/src/user/application/queries/handlers/index.ts similarity index 100% rename from src/user/queries/handlers/index.ts rename to src/user/application/queries/handlers/index.ts diff --git a/src/user/queries/handlers/login.handler.ts b/src/user/application/queries/handlers/login.handler.ts similarity index 80% rename from src/user/queries/handlers/login.handler.ts rename to src/user/application/queries/handlers/login.handler.ts index 540e26f..dfd0ed2 100644 --- a/src/user/queries/handlers/login.handler.ts +++ b/src/user/application/queries/handlers/login.handler.ts @@ -3,14 +3,14 @@ import { QueryHandler, IQueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; import * as argon2 from "argon2"; -import { READ_CONNECTION } from "../../../config"; -import { LoginUserDto } from "../../dto"; -import { UserEntity } from "../../core/entities/user.entity"; -import { UserRO } from "../../core/interfaces/user.interface"; +import { READ_CONNECTION } from "../../../../config"; +import { LoginUserDto } from "../../../core/dto"; +import { UserEntity } from "../../../core/entities/user.entity"; +import { UserRO } from "../../../core/interfaces/user.interface"; import { UserService } from "../../services/user.service"; import { LoginQuery } from "../impl"; -import { RedisService } from "../../../redis/redis.service"; -import { TIME_TO_LIVE } from "../../../redis/redis.constant"; +import { RedisService } from "../../../../redis/redis.service"; +import { TIME_TO_LIVE } from "../../../../redis/redis.constant"; @QueryHandler(LoginQuery) export class LoginQueryHandler implements IQueryHandler { diff --git a/src/user/queries/impl/find-user-by-email.query.ts b/src/user/application/queries/impl/find-user-by-email.query.ts similarity index 100% rename from src/user/queries/impl/find-user-by-email.query.ts rename to src/user/application/queries/impl/find-user-by-email.query.ts diff --git a/src/user/queries/impl/find-user-by-id.query.ts b/src/user/application/queries/impl/find-user-by-id.query.ts similarity index 100% rename from src/user/queries/impl/find-user-by-id.query.ts rename to src/user/application/queries/impl/find-user-by-id.query.ts diff --git a/src/user/queries/impl/index.ts b/src/user/application/queries/impl/index.ts similarity index 100% rename from src/user/queries/impl/index.ts rename to src/user/application/queries/impl/index.ts diff --git a/src/user/queries/impl/login.query.ts b/src/user/application/queries/impl/login.query.ts similarity index 64% rename from src/user/queries/impl/login.query.ts rename to src/user/application/queries/impl/login.query.ts index 46b3ac4..3b61efe 100644 --- a/src/user/queries/impl/login.query.ts +++ b/src/user/application/queries/impl/login.query.ts @@ -1,4 +1,4 @@ -import { LoginUserDto } from "../../dto"; +import { LoginUserDto } from "../../../core/dto"; export class LoginQuery { constructor(public readonly loginUserDto: LoginUserDto) {} diff --git a/src/user/queries/index.ts b/src/user/application/queries/index.ts similarity index 100% rename from src/user/queries/index.ts rename to src/user/application/queries/index.ts diff --git a/src/user/queries/query.module.ts b/src/user/application/queries/query.module.ts similarity index 66% rename from src/user/queries/query.module.ts rename to src/user/application/queries/query.module.ts index 637aeb9..de4cee7 100644 --- a/src/user/queries/query.module.ts +++ b/src/user/application/queries/query.module.ts @@ -1,12 +1,12 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; + import { QueryHandlers } from "."; -import { READ_CONNECTION } from "../../config"; -import { UserController } from "../user.controller"; -import { UserEntity } from "../core"; +import { READ_CONNECTION } from "../../../config"; +import { UserEntity } from "../../core"; import { UserService } from "../services/user.service"; -import { RedisModule } from "../../redis/redis.module"; +import { RedisModule } from "../../../redis/redis.module"; @Module({ imports: [ @@ -15,7 +15,7 @@ import { RedisModule } from "../../redis/redis.module"; RedisModule, ], providers: [UserService, ...QueryHandlers], - controllers: [UserController], + controllers: [], exports: [UserService], }) export class QueryModule {} diff --git a/src/user/services/auth.service.ts b/src/user/application/services/auth.service.ts similarity index 100% rename from src/user/services/auth.service.ts rename to src/user/application/services/auth.service.ts diff --git a/src/user/services/user.service.ts b/src/user/application/services/user.service.ts similarity index 87% rename from src/user/services/user.service.ts rename to src/user/application/services/user.service.ts index 6da4b43..435e638 100644 --- a/src/user/services/user.service.ts +++ b/src/user/application/services/user.service.ts @@ -1,6 +1,6 @@ import { Injectable } from "@nestjs/common"; -import { SECRET } from "../../config"; -import { UserEntity } from "../core/entities/user.entity"; +import { SECRET } from "../../../config"; +import { UserEntity } from "../../core/entities/user.entity"; const jwt = require("jsonwebtoken"); @Injectable() diff --git a/src/user/user.projection.ts b/src/user/application/user.projection.ts similarity index 77% rename from src/user/user.projection.ts rename to src/user/application/user.projection.ts index 0610047..801744c 100644 --- a/src/user/user.projection.ts +++ b/src/user/application/user.projection.ts @@ -1,9 +1,9 @@ import { Injectable } from "@nestjs/common"; import { EventBus } from "@nestjs/cqrs"; -import { ConsumerService } from "../rabbitmq/consumer.service"; -import { USER_QUEUE } from "../rabbitmq/rabbitmq.constants"; -import { IMessage, IProjection } from "./core"; -import { MessageType } from "./core/enums/user.enum"; +import { ConsumerService } from "../../rabbitmq/consumer.service"; +import { USER_QUEUE } from "../../rabbitmq/rabbitmq.constants"; +import { IMessage, IProjection } from "../core"; +import { MessageType } from "../core/enums/user.enum"; import { UserCreatedEvent, UserUpdatedEvent } from "./events"; @Injectable() diff --git a/src/user/dto/create-user.dto.ts b/src/user/core/dto/create-user.dto.ts similarity index 100% rename from src/user/dto/create-user.dto.ts rename to src/user/core/dto/create-user.dto.ts diff --git a/src/user/dto/index.ts b/src/user/core/dto/index.ts similarity index 100% rename from src/user/dto/index.ts rename to src/user/core/dto/index.ts diff --git a/src/user/dto/login-user.dto.ts b/src/user/core/dto/login-user.dto.ts similarity index 100% rename from src/user/dto/login-user.dto.ts rename to src/user/core/dto/login-user.dto.ts diff --git a/src/user/dto/update-user.dto.ts b/src/user/core/dto/update-user.dto.ts similarity index 100% rename from src/user/dto/update-user.dto.ts rename to src/user/core/dto/update-user.dto.ts diff --git a/src/user/user.controller.ts b/src/user/presentation/user.controller.ts similarity index 78% rename from src/user/user.controller.ts rename to src/user/presentation/user.controller.ts index c5bc675..9e9a63e 100644 --- a/src/user/user.controller.ts +++ b/src/user/presentation/user.controller.ts @@ -1,12 +1,13 @@ import { Body, Controller, Get, Post, Put, UsePipes } from "@nestjs/common"; import { CommandBus, QueryBus } from "@nestjs/cqrs"; import { ApiBearerAuth, ApiBody, ApiOperation, ApiTags } from "@nestjs/swagger"; -import { ValidationPipe } from "../shared/pipes/validation.pipe"; -import { CreateUserDto, LoginUserDto, UpdateUserDto } from "./dto"; -import { CreateUserCommand, UpdateUserCommand } from "./commands"; -import { FindUserByEmailQuery, FindUserById, LoginQuery } from "./queries"; -import { User } from "./user.decorator"; -import { UserRO } from "./core/interfaces/user.interface"; + +import { User } from "../../shared/middleware/user.decorator"; +import { ValidationPipe } from "../../shared/pipes/validation.pipe"; +import { CreateUserCommand, UpdateUserCommand } from "../application/commands"; +import { FindUserById, LoginQuery } from "../application/queries"; +import { CreateUserDto, LoginUserDto, UpdateUserDto } from "../core/dto"; +import { UserRO } from "../core/interfaces/user.interface"; @ApiBearerAuth() @ApiTags("user") diff --git a/src/user/user.module.ts b/src/user/user.module.ts index 3095526..3de6eac 100644 --- a/src/user/user.module.ts +++ b/src/user/user.module.ts @@ -5,15 +5,16 @@ import { RequestMethod, } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; + import { RabbitMqModule } from "../rabbitmq/rabbitmq.module"; -import { AuthMiddleware } from "./auth.middleware"; -import { CommandModule } from "./commands/command.module"; -import { EventModule } from "./events/event.module"; -import { QueryModule } from "./queries/query.module"; -import { UserController } from "./user.controller"; -import { UserProjection } from "./user.projection"; -import { UserService } from "./services/user.service"; import { RedisModule } from "../redis/redis.module"; +import { AuthMiddleware } from "../shared/middleware/auth.middleware"; +import { CommandModule } from "./application/commands/command.module"; +import { EventModule } from "./application/events/event.module"; +import { QueryModule } from "./application/queries/query.module"; +import { UserService } from "./application/services/user.service"; +import { UserProjection } from "./application/user.projection"; +import { UserController } from "./presentation/user.controller"; @Module({ imports: [ From 1af67948e4acced411204b34d01d898244a9528b Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Fri, 13 Oct 2023 14:45:21 +0700 Subject: [PATCH 10/19] feat: apply CLEAN Architect for article-module --- .../{ => application}/article.projection.ts | 9 ++++---- .../commands/command.module.ts | 15 +++++++------ .../handlers/create-article.handler.ts | 12 +++++----- .../handlers/create-comment.handler.ts | 16 +++++++------- .../handlers/delete-article.handler.ts | 8 +++---- .../handlers/delete-comment.handler.ts | 14 ++++++------ .../handlers/favorite-article.handler.ts | 14 ++++++------ .../commands/handlers/index.ts | 0 .../handlers/unfavorite-article.handler.ts | 14 ++++++------ .../handlers/update-article.handler.ts | 12 +++++----- .../commands/impl/create-article.command.ts | 2 +- .../commands/impl/create-comment.command.ts | 2 +- .../commands/impl/delete-article.command.ts | 0 .../commands/impl/delete-comment.command.ts | 0 .../commands/impl/favorite-article.command.ts | 0 .../{ => application}/commands/impl/index.ts | 0 .../impl/unfavorite-article.command.ts | 0 .../commands/impl/update-article.command.ts | 2 +- .../{ => application}/commands/index.ts | 0 .../{ => application}/events/event.module.ts | 12 +++++----- .../handlers/article-created.handler.ts | 4 ++-- .../handlers/article-deleted.handler.ts | 4 ++-- .../handlers/article-favorited.handler.ts | 6 ++--- .../handlers/article-unfavorited.handler.ts | 6 ++--- .../handlers/article-updated.handler.ts | 4 ++-- .../handlers/comment-created.handler.ts | 4 ++-- .../handlers/comment-deleted.handler.ts | 4 ++-- .../events/handlers/index.ts | 0 .../handlers/indexing-article.handler.ts | 0 .../events/impl/article-created.event.ts | 2 +- .../events/impl/article-deleted.event.ts | 0 .../events/impl/article-favorited.event.ts | 9 ++++++++ .../events/impl/article-unfavorited.event.ts | 4 ++-- .../events/impl/article-updated.event.ts | 2 +- .../events/impl/comment-created.event.ts | 2 +- .../events/impl/comment-deleted.event.ts | 2 +- .../{ => application}/events/impl/index.ts | 0 src/article/{ => application}/events/index.ts | 0 .../handlers/find-all.article.handler.ts | 10 ++++----- .../queries/handlers/find-comments.handler.ts | 6 ++--- .../handlers/find-feed-article.handler.ts | 12 +++++----- .../handlers/find-one-article.handler.ts | 10 ++++----- .../queries/handlers/index.ts | 0 .../handlers/indexing-article.handler.ts | 0 .../handlers/search-article.handler.ts | 0 .../queries/impl/find-all.article.query.ts | 2 +- .../queries/impl/find-comments.query.ts | 0 .../queries/impl/find-feed-article.query.ts | 2 +- .../queries/impl/find-one-article.query.ts | 0 .../{ => application}/queries/impl/index.ts | 0 .../queries/impl/search-article.query.ts | 0 .../{ => application}/queries/index.ts | 0 .../{ => application}/queries/query.module.ts | 13 ++++++----- .../services/article.service.ts | 4 ++-- src/article/article.module.ts | 13 ++++++----- src/article/{ => core}/dto/article-query.ts | 0 src/article/{ => core}/dto/block.dto.ts | 2 +- .../{ => core}/dto/create-article.dto.ts | 0 src/article/{ => core}/dto/create-comment.ts | 0 src/article/{ => core}/dto/index.ts | 0 src/article/{ => core}/dto/search-article.ts | 0 .../events/impl/article-favorited.event.ts | 9 -------- .../{ => presentation}/article.controller.ts | 22 +++++++++---------- 63 files changed, 147 insertions(+), 143 deletions(-) rename src/article/{ => application}/article.projection.ts (87%) rename src/article/{ => application}/commands/command.module.ts (56%) rename src/article/{ => application}/commands/handlers/create-article.handler.ts (77%) rename src/article/{ => application}/commands/handlers/create-comment.handler.ts (77%) rename src/article/{ => application}/commands/handlers/delete-article.handler.ts (89%) rename src/article/{ => application}/commands/handlers/delete-comment.handler.ts (81%) rename src/article/{ => application}/commands/handlers/favorite-article.handler.ts (80%) rename src/article/{ => application}/commands/handlers/index.ts (100%) rename src/article/{ => application}/commands/handlers/unfavorite-article.handler.ts (78%) rename src/article/{ => application}/commands/handlers/update-article.handler.ts (76%) rename src/article/{ => application}/commands/impl/create-article.command.ts (73%) rename src/article/{ => application}/commands/impl/create-comment.command.ts (77%) rename src/article/{ => application}/commands/impl/delete-article.command.ts (100%) rename src/article/{ => application}/commands/impl/delete-comment.command.ts (100%) rename src/article/{ => application}/commands/impl/favorite-article.command.ts (100%) rename src/article/{ => application}/commands/impl/index.ts (100%) rename src/article/{ => application}/commands/impl/unfavorite-article.command.ts (100%) rename src/article/{ => application}/commands/impl/update-article.command.ts (72%) rename src/article/{ => application}/commands/index.ts (100%) rename src/article/{ => application}/events/event.module.ts (52%) rename src/article/{ => application}/events/handlers/article-created.handler.ts (86%) rename src/article/{ => application}/events/handlers/article-deleted.handler.ts (96%) rename src/article/{ => application}/events/handlers/article-favorited.handler.ts (83%) rename src/article/{ => application}/events/handlers/article-unfavorited.handler.ts (83%) rename src/article/{ => application}/events/handlers/article-updated.handler.ts (89%) rename src/article/{ => application}/events/handlers/comment-created.handler.ts (86%) rename src/article/{ => application}/events/handlers/comment-deleted.handler.ts (86%) rename src/article/{ => application}/events/handlers/index.ts (100%) rename src/article/{ => application}/events/handlers/indexing-article.handler.ts (100%) rename src/article/{ => application}/events/impl/article-created.event.ts (57%) rename src/article/{ => application}/events/impl/article-deleted.event.ts (100%) create mode 100644 src/article/application/events/impl/article-favorited.event.ts rename src/article/{ => application}/events/impl/article-unfavorited.event.ts (50%) rename src/article/{ => application}/events/impl/article-updated.event.ts (57%) rename src/article/{ => application}/events/impl/comment-created.event.ts (78%) rename src/article/{ => application}/events/impl/comment-deleted.event.ts (78%) rename src/article/{ => application}/events/impl/index.ts (100%) rename src/article/{ => application}/events/index.ts (100%) rename src/article/{ => application}/queries/handlers/find-all.article.handler.ts (90%) rename src/article/{ => application}/queries/handlers/find-comments.handler.ts (83%) rename src/article/{ => application}/queries/handlers/find-feed-article.handler.ts (85%) rename src/article/{ => application}/queries/handlers/find-one-article.handler.ts (81%) rename src/article/{ => application}/queries/handlers/index.ts (100%) rename src/article/{ => application}/queries/handlers/indexing-article.handler.ts (100%) rename src/article/{ => application}/queries/handlers/search-article.handler.ts (100%) rename src/article/{ => application}/queries/impl/find-all.article.query.ts (67%) rename src/article/{ => application}/queries/impl/find-comments.query.ts (100%) rename src/article/{ => application}/queries/impl/find-feed-article.query.ts (67%) rename src/article/{ => application}/queries/impl/find-one-article.query.ts (100%) rename src/article/{ => application}/queries/impl/index.ts (100%) rename src/article/{ => application}/queries/impl/search-article.query.ts (100%) rename src/article/{ => application}/queries/index.ts (100%) rename src/article/{ => application}/queries/query.module.ts (65%) rename src/article/{ => application}/services/article.service.ts (96%) rename src/article/{ => core}/dto/article-query.ts (100%) rename src/article/{ => core}/dto/block.dto.ts (91%) rename src/article/{ => core}/dto/create-article.dto.ts (100%) rename src/article/{ => core}/dto/create-comment.ts (100%) rename src/article/{ => core}/dto/index.ts (100%) rename src/article/{ => core}/dto/search-article.ts (100%) delete mode 100644 src/article/events/impl/article-favorited.event.ts rename src/article/{ => presentation}/article.controller.ts (95%) diff --git a/src/article/article.projection.ts b/src/article/application/article.projection.ts similarity index 87% rename from src/article/article.projection.ts rename to src/article/application/article.projection.ts index c981fcc..e9d7f97 100644 --- a/src/article/article.projection.ts +++ b/src/article/application/article.projection.ts @@ -1,9 +1,10 @@ import { Injectable } from "@nestjs/common"; import { EventBus } from "@nestjs/cqrs"; -import { ConsumerService } from "../rabbitmq/consumer.service"; -import { ARTICLE_QUEUE } from "../rabbitmq/rabbitmq.constants"; -import { IMessage, IProjection } from "./core"; -import { MessageType } from "./core/enums/article.enum"; + +import { ConsumerService } from "../../rabbitmq/consumer.service"; +import { ARTICLE_QUEUE } from "../../rabbitmq/rabbitmq.constants"; +import { IMessage, IProjection } from "../core"; +import { MessageType } from "../core/enums/article.enum"; import { ArticleCreatedEvent, ArticleDeletedEvent, diff --git a/src/article/commands/command.module.ts b/src/article/application/commands/command.module.ts similarity index 56% rename from src/article/commands/command.module.ts rename to src/article/application/commands/command.module.ts index 79d93d9..d44a803 100644 --- a/src/article/commands/command.module.ts +++ b/src/article/application/commands/command.module.ts @@ -1,14 +1,15 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; + import { CommandHandlers } from "."; -import { WRITE_CONNECTION } from "../../config"; -import { FollowsEntity } from "../../profile/core/entities/follows.entity"; -import { RabbitMqModule } from "../../rabbitmq/rabbitmq.module"; -import { UserEntity } from "../../user/core"; -import { UserModule } from "../../user/user.module"; -import { ArticleEntity, BlockEntity } from "../core"; -import { CommentEntity } from "../core/entities/comment.entity"; +import { WRITE_CONNECTION } from "../../../config"; +import { FollowsEntity } from "../../../profile/core/entities/follows.entity"; +import { RabbitMqModule } from "../../../rabbitmq/rabbitmq.module"; +import { UserEntity } from "../../../user/core"; +import { UserModule } from "../../../user/user.module"; +import { ArticleEntity, BlockEntity } from "../../core"; +import { CommentEntity } from "../../core/entities/comment.entity"; import { ArticleService } from "../services/article.service"; @Module({ diff --git a/src/article/commands/handlers/create-article.handler.ts b/src/article/application/commands/handlers/create-article.handler.ts similarity index 77% rename from src/article/commands/handlers/create-article.handler.ts rename to src/article/application/commands/handlers/create-article.handler.ts index f6c216c..143c670 100644 --- a/src/article/commands/handlers/create-article.handler.ts +++ b/src/article/application/commands/handlers/create-article.handler.ts @@ -2,12 +2,12 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { MessageType } from "../../core/enums/article.enum"; -import { ArticleRO } from "../../core/interfaces/article.interface"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { MessageType } from "../../../core/enums/article.enum"; +import { ArticleRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { CreateArticleCommand } from "../impl"; diff --git a/src/article/commands/handlers/create-comment.handler.ts b/src/article/application/commands/handlers/create-comment.handler.ts similarity index 77% rename from src/article/commands/handlers/create-comment.handler.ts rename to src/article/application/commands/handlers/create-comment.handler.ts index 0044dcb..6668d22 100644 --- a/src/article/commands/handlers/create-comment.handler.ts +++ b/src/article/application/commands/handlers/create-comment.handler.ts @@ -2,14 +2,14 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { CommentEntity } from "../../core/entities/comment.entity"; -import { MessageType } from "../../core/enums/article.enum"; -import { CommentRO } from "../../core/interfaces/article.interface"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { CommentEntity } from "../../../core/entities/comment.entity"; +import { MessageType } from "../../../core/enums/article.enum"; +import { CommentRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { CreateCommentCommand } from "../impl"; diff --git a/src/article/commands/handlers/delete-article.handler.ts b/src/article/application/commands/handlers/delete-article.handler.ts similarity index 89% rename from src/article/commands/handlers/delete-article.handler.ts rename to src/article/application/commands/handlers/delete-article.handler.ts index b8535f3..175a5ed 100644 --- a/src/article/commands/handlers/delete-article.handler.ts +++ b/src/article/application/commands/handlers/delete-article.handler.ts @@ -2,15 +2,15 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { DeleteResult, Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { CommentEntity, ArticleEntity, BlockEntity, MessageType, -} from "../../core"; +} from "../../../core"; import { DeleteArticleCommand } from "../impl"; @CommandHandler(DeleteArticleCommand) diff --git a/src/article/commands/handlers/delete-comment.handler.ts b/src/article/application/commands/handlers/delete-comment.handler.ts similarity index 81% rename from src/article/commands/handlers/delete-comment.handler.ts rename to src/article/application/commands/handlers/delete-comment.handler.ts index 3547c90..d8d1144 100644 --- a/src/article/commands/handlers/delete-comment.handler.ts +++ b/src/article/application/commands/handlers/delete-comment.handler.ts @@ -2,13 +2,13 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { CommentEntity } from "../../core/entities/comment.entity"; -import { MessageType } from "../../core/enums/article.enum"; -import { ArticleRO } from "../../core/interfaces/article.interface"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { CommentEntity } from "../../../core/entities/comment.entity"; +import { MessageType } from "../../../core/enums/article.enum"; +import { ArticleRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { DeleteCommentCommand } from "../impl"; diff --git a/src/article/commands/handlers/favorite-article.handler.ts b/src/article/application/commands/handlers/favorite-article.handler.ts similarity index 80% rename from src/article/commands/handlers/favorite-article.handler.ts rename to src/article/application/commands/handlers/favorite-article.handler.ts index 2ff1214..763225f 100644 --- a/src/article/commands/handlers/favorite-article.handler.ts +++ b/src/article/application/commands/handlers/favorite-article.handler.ts @@ -2,13 +2,13 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { MessageType } from "../../core/enums/article.enum"; -import { ArticleRO } from "../../core/interfaces/article.interface"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { MessageType } from "../../../core/enums/article.enum"; +import { ArticleRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { FavoriteArticleCommand } from "../impl"; diff --git a/src/article/commands/handlers/index.ts b/src/article/application/commands/handlers/index.ts similarity index 100% rename from src/article/commands/handlers/index.ts rename to src/article/application/commands/handlers/index.ts diff --git a/src/article/commands/handlers/unfavorite-article.handler.ts b/src/article/application/commands/handlers/unfavorite-article.handler.ts similarity index 78% rename from src/article/commands/handlers/unfavorite-article.handler.ts rename to src/article/application/commands/handlers/unfavorite-article.handler.ts index 73352ee..982b083 100644 --- a/src/article/commands/handlers/unfavorite-article.handler.ts +++ b/src/article/application/commands/handlers/unfavorite-article.handler.ts @@ -1,13 +1,13 @@ import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { MessageType } from "../../core/enums/article.enum"; -import { ArticleRO } from "../../core/interfaces/article.interface"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { MessageType } from "../../../core/enums/article.enum"; +import { ArticleRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { UnFavoriteArticleCommand } from "../impl"; diff --git a/src/article/commands/handlers/update-article.handler.ts b/src/article/application/commands/handlers/update-article.handler.ts similarity index 76% rename from src/article/commands/handlers/update-article.handler.ts rename to src/article/application/commands/handlers/update-article.handler.ts index f40c735..ef751e3 100644 --- a/src/article/commands/handlers/update-article.handler.ts +++ b/src/article/application/commands/handlers/update-article.handler.ts @@ -2,12 +2,12 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { MessageType } from "../../core/enums/article.enum"; -import { ArticleRO } from "../../core/interfaces/article.interface"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { MessageType } from "../../../core/enums/article.enum"; +import { ArticleRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { UpdateArticleCommand } from "../impl"; diff --git a/src/article/commands/impl/create-article.command.ts b/src/article/application/commands/impl/create-article.command.ts similarity index 73% rename from src/article/commands/impl/create-article.command.ts rename to src/article/application/commands/impl/create-article.command.ts index 30073fc..c9493ee 100644 --- a/src/article/commands/impl/create-article.command.ts +++ b/src/article/application/commands/impl/create-article.command.ts @@ -1,4 +1,4 @@ -import { CreateArticleDto } from "../../dto"; +import { CreateArticleDto } from "../../../core/dto"; export class CreateArticleCommand { constructor( diff --git a/src/article/commands/impl/create-comment.command.ts b/src/article/application/commands/impl/create-comment.command.ts similarity index 77% rename from src/article/commands/impl/create-comment.command.ts rename to src/article/application/commands/impl/create-comment.command.ts index a294800..9a0d03f 100644 --- a/src/article/commands/impl/create-comment.command.ts +++ b/src/article/application/commands/impl/create-comment.command.ts @@ -1,4 +1,4 @@ -import { CreateCommentDto } from "../../dto"; +import { CreateCommentDto } from "../../../core/dto"; export class CreateCommentCommand { constructor( diff --git a/src/article/commands/impl/delete-article.command.ts b/src/article/application/commands/impl/delete-article.command.ts similarity index 100% rename from src/article/commands/impl/delete-article.command.ts rename to src/article/application/commands/impl/delete-article.command.ts diff --git a/src/article/commands/impl/delete-comment.command.ts b/src/article/application/commands/impl/delete-comment.command.ts similarity index 100% rename from src/article/commands/impl/delete-comment.command.ts rename to src/article/application/commands/impl/delete-comment.command.ts diff --git a/src/article/commands/impl/favorite-article.command.ts b/src/article/application/commands/impl/favorite-article.command.ts similarity index 100% rename from src/article/commands/impl/favorite-article.command.ts rename to src/article/application/commands/impl/favorite-article.command.ts diff --git a/src/article/commands/impl/index.ts b/src/article/application/commands/impl/index.ts similarity index 100% rename from src/article/commands/impl/index.ts rename to src/article/application/commands/impl/index.ts diff --git a/src/article/commands/impl/unfavorite-article.command.ts b/src/article/application/commands/impl/unfavorite-article.command.ts similarity index 100% rename from src/article/commands/impl/unfavorite-article.command.ts rename to src/article/application/commands/impl/unfavorite-article.command.ts diff --git a/src/article/commands/impl/update-article.command.ts b/src/article/application/commands/impl/update-article.command.ts similarity index 72% rename from src/article/commands/impl/update-article.command.ts rename to src/article/application/commands/impl/update-article.command.ts index aa85b5a..c419478 100644 --- a/src/article/commands/impl/update-article.command.ts +++ b/src/article/application/commands/impl/update-article.command.ts @@ -1,4 +1,4 @@ -import { CreateArticleDto } from "../../dto"; +import { CreateArticleDto } from "../../../core/dto"; export class UpdateArticleCommand { constructor( diff --git a/src/article/commands/index.ts b/src/article/application/commands/index.ts similarity index 100% rename from src/article/commands/index.ts rename to src/article/application/commands/index.ts diff --git a/src/article/events/event.module.ts b/src/article/application/events/event.module.ts similarity index 52% rename from src/article/events/event.module.ts rename to src/article/application/events/event.module.ts index 7c7703b..1036669 100644 --- a/src/article/events/event.module.ts +++ b/src/article/application/events/event.module.ts @@ -1,12 +1,12 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; -import { READ_CONNECTION } from "../../config"; -import { UserEntity } from "../../user/core/entities/user.entity"; -import { ArticleEntity, BlockEntity } from "../core"; -import { CommentEntity } from "../core/entities/comment.entity"; -import { EventHandlers } from "../events"; -import { ElasticSearchModule } from "../../elastic-search/elastic-search.module"; +import { READ_CONNECTION } from "../../../config"; +import { UserEntity } from "../../../user/core/entities/user.entity"; +import { ArticleEntity, BlockEntity } from "../../core"; +import { CommentEntity } from "../../core/entities/comment.entity"; +import { EventHandlers } from "."; +import { ElasticSearchModule } from "../../../elastic-search/elastic-search.module"; @Module({ imports: [ diff --git a/src/article/events/handlers/article-created.handler.ts b/src/article/application/events/handlers/article-created.handler.ts similarity index 86% rename from src/article/events/handlers/article-created.handler.ts rename to src/article/application/events/handlers/article-created.handler.ts index 31237a9..24670f0 100644 --- a/src/article/events/handlers/article-created.handler.ts +++ b/src/article/application/events/handlers/article-created.handler.ts @@ -3,8 +3,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { ArticleEntity } from "../../core/entities/article.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { ArticleEntity } from "../../../core/entities/article.entity"; import { ArticleCreatedEvent } from "../impl"; @EventsHandler(ArticleCreatedEvent) diff --git a/src/article/events/handlers/article-deleted.handler.ts b/src/article/application/events/handlers/article-deleted.handler.ts similarity index 96% rename from src/article/events/handlers/article-deleted.handler.ts rename to src/article/application/events/handlers/article-deleted.handler.ts index 330ae11..3d627cd 100644 --- a/src/article/events/handlers/article-deleted.handler.ts +++ b/src/article/application/events/handlers/article-deleted.handler.ts @@ -3,9 +3,9 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; +import { READ_CONNECTION } from "../../../../config"; import { ArticleDeletedEvent } from "../impl"; -import { CommentEntity, ArticleEntity, BlockEntity } from "../../core"; +import { CommentEntity, ArticleEntity, BlockEntity } from "../../../core"; @EventsHandler(ArticleDeletedEvent) export class ArticleDeletedEventHandler diff --git a/src/article/events/handlers/article-favorited.handler.ts b/src/article/application/events/handlers/article-favorited.handler.ts similarity index 83% rename from src/article/events/handlers/article-favorited.handler.ts rename to src/article/application/events/handlers/article-favorited.handler.ts index a637c90..1d274b7 100644 --- a/src/article/events/handlers/article-favorited.handler.ts +++ b/src/article/application/events/handlers/article-favorited.handler.ts @@ -3,9 +3,9 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; import { ArticleFavoritedEvent } from "../impl"; @EventsHandler(ArticleFavoritedEvent) diff --git a/src/article/events/handlers/article-unfavorited.handler.ts b/src/article/application/events/handlers/article-unfavorited.handler.ts similarity index 83% rename from src/article/events/handlers/article-unfavorited.handler.ts rename to src/article/application/events/handlers/article-unfavorited.handler.ts index 5812357..87f64e2 100644 --- a/src/article/events/handlers/article-unfavorited.handler.ts +++ b/src/article/application/events/handlers/article-unfavorited.handler.ts @@ -3,9 +3,9 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; import { ArticleUnFavoritedEvent } from "../impl"; @EventsHandler(ArticleUnFavoritedEvent) diff --git a/src/article/events/handlers/article-updated.handler.ts b/src/article/application/events/handlers/article-updated.handler.ts similarity index 89% rename from src/article/events/handlers/article-updated.handler.ts rename to src/article/application/events/handlers/article-updated.handler.ts index 599e055..b5617f6 100644 --- a/src/article/events/handlers/article-updated.handler.ts +++ b/src/article/application/events/handlers/article-updated.handler.ts @@ -3,8 +3,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { ArticleEntity } from "../../core/entities/article.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { ArticleEntity } from "../../../core/entities/article.entity"; import { ArticleUpdatedEvent } from "../impl"; @EventsHandler(ArticleUpdatedEvent) diff --git a/src/article/events/handlers/comment-created.handler.ts b/src/article/application/events/handlers/comment-created.handler.ts similarity index 86% rename from src/article/events/handlers/comment-created.handler.ts rename to src/article/application/events/handlers/comment-created.handler.ts index e5c5620..c7dc949 100644 --- a/src/article/events/handlers/comment-created.handler.ts +++ b/src/article/application/events/handlers/comment-created.handler.ts @@ -3,8 +3,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { CommentEntity } from "../../core/entities/comment.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { CommentEntity } from "../../../core/entities/comment.entity"; import { CommentCreatedEvent } from "../impl"; @EventsHandler(CommentCreatedEvent) diff --git a/src/article/events/handlers/comment-deleted.handler.ts b/src/article/application/events/handlers/comment-deleted.handler.ts similarity index 86% rename from src/article/events/handlers/comment-deleted.handler.ts rename to src/article/application/events/handlers/comment-deleted.handler.ts index c068d14..284d2c5 100644 --- a/src/article/events/handlers/comment-deleted.handler.ts +++ b/src/article/application/events/handlers/comment-deleted.handler.ts @@ -3,8 +3,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { CommentEntity } from "../../core/entities/comment.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { CommentEntity } from "../../../core/entities/comment.entity"; import { CommentDeletedEvent } from "../impl"; @EventsHandler(CommentDeletedEvent) diff --git a/src/article/events/handlers/index.ts b/src/article/application/events/handlers/index.ts similarity index 100% rename from src/article/events/handlers/index.ts rename to src/article/application/events/handlers/index.ts diff --git a/src/article/events/handlers/indexing-article.handler.ts b/src/article/application/events/handlers/indexing-article.handler.ts similarity index 100% rename from src/article/events/handlers/indexing-article.handler.ts rename to src/article/application/events/handlers/indexing-article.handler.ts diff --git a/src/article/events/impl/article-created.event.ts b/src/article/application/events/impl/article-created.event.ts similarity index 57% rename from src/article/events/impl/article-created.event.ts rename to src/article/application/events/impl/article-created.event.ts index 042a9ac..8a2aba7 100644 --- a/src/article/events/impl/article-created.event.ts +++ b/src/article/application/events/impl/article-created.event.ts @@ -1,4 +1,4 @@ -import { ArticleEntity } from "../../core/entities/article.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; export class ArticleCreatedEvent { constructor(public readonly article: ArticleEntity) {} diff --git a/src/article/events/impl/article-deleted.event.ts b/src/article/application/events/impl/article-deleted.event.ts similarity index 100% rename from src/article/events/impl/article-deleted.event.ts rename to src/article/application/events/impl/article-deleted.event.ts diff --git a/src/article/application/events/impl/article-favorited.event.ts b/src/article/application/events/impl/article-favorited.event.ts new file mode 100644 index 0000000..559ea8b --- /dev/null +++ b/src/article/application/events/impl/article-favorited.event.ts @@ -0,0 +1,9 @@ +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; + +export class ArticleFavoritedEvent { + constructor( + public readonly user: UserEntity, + public readonly article: ArticleEntity + ) {} +} diff --git a/src/article/events/impl/article-unfavorited.event.ts b/src/article/application/events/impl/article-unfavorited.event.ts similarity index 50% rename from src/article/events/impl/article-unfavorited.event.ts rename to src/article/application/events/impl/article-unfavorited.event.ts index 75dfd66..25460f7 100644 --- a/src/article/events/impl/article-unfavorited.event.ts +++ b/src/article/application/events/impl/article-unfavorited.event.ts @@ -1,5 +1,5 @@ -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; export class ArticleUnFavoritedEvent { constructor( diff --git a/src/article/events/impl/article-updated.event.ts b/src/article/application/events/impl/article-updated.event.ts similarity index 57% rename from src/article/events/impl/article-updated.event.ts rename to src/article/application/events/impl/article-updated.event.ts index 35fe7a7..e03e0fb 100644 --- a/src/article/events/impl/article-updated.event.ts +++ b/src/article/application/events/impl/article-updated.event.ts @@ -1,4 +1,4 @@ -import { ArticleEntity } from "../../core/entities/article.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; export class ArticleUpdatedEvent { constructor(public readonly article: ArticleEntity) {} diff --git a/src/article/events/impl/comment-created.event.ts b/src/article/application/events/impl/comment-created.event.ts similarity index 78% rename from src/article/events/impl/comment-created.event.ts rename to src/article/application/events/impl/comment-created.event.ts index 8763d05..c3557e4 100644 --- a/src/article/events/impl/comment-created.event.ts +++ b/src/article/application/events/impl/comment-created.event.ts @@ -1,6 +1,6 @@ // import { Comment } from "../../core/entities/comment.entity"; -import { IComment } from "../../core"; +import { IComment } from "../../../core"; export class CommentCreatedEvent { constructor(public readonly comment: IComment) {} diff --git a/src/article/events/impl/comment-deleted.event.ts b/src/article/application/events/impl/comment-deleted.event.ts similarity index 78% rename from src/article/events/impl/comment-deleted.event.ts rename to src/article/application/events/impl/comment-deleted.event.ts index 3883bb5..a51cef2 100644 --- a/src/article/events/impl/comment-deleted.event.ts +++ b/src/article/application/events/impl/comment-deleted.event.ts @@ -1,6 +1,6 @@ // import { Comment } from "../../core/entities/comment.entity"; -import { IComment } from "../../core"; +import { IComment } from "../../../core"; export class CommentDeletedEvent { constructor(public readonly comment: IComment) {} diff --git a/src/article/events/impl/index.ts b/src/article/application/events/impl/index.ts similarity index 100% rename from src/article/events/impl/index.ts rename to src/article/application/events/impl/index.ts diff --git a/src/article/events/index.ts b/src/article/application/events/index.ts similarity index 100% rename from src/article/events/index.ts rename to src/article/application/events/index.ts diff --git a/src/article/queries/handlers/find-all.article.handler.ts b/src/article/application/queries/handlers/find-all.article.handler.ts similarity index 90% rename from src/article/queries/handlers/find-all.article.handler.ts rename to src/article/application/queries/handlers/find-all.article.handler.ts index 74c332e..7f24028 100644 --- a/src/article/queries/handlers/find-all.article.handler.ts +++ b/src/article/application/queries/handlers/find-all.article.handler.ts @@ -2,11 +2,11 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { getRepository, Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { FollowsEntity } from "../../../profile/core/entities/follows.entity"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { ArticlesRO } from "../../core/interfaces/article.interface"; +import { READ_CONNECTION } from "../../../../config"; +import { FollowsEntity } from "../../../../profile/core/entities/follows.entity"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { ArticlesRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { FindAllArticleQuery } from "../impl"; diff --git a/src/article/queries/handlers/find-comments.handler.ts b/src/article/application/queries/handlers/find-comments.handler.ts similarity index 83% rename from src/article/queries/handlers/find-comments.handler.ts rename to src/article/application/queries/handlers/find-comments.handler.ts index 20e7550..57e61c9 100644 --- a/src/article/queries/handlers/find-comments.handler.ts +++ b/src/article/application/queries/handlers/find-comments.handler.ts @@ -1,9 +1,9 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { CommentsRO } from "../../core/interfaces/article.interface"; +import { READ_CONNECTION } from "../../../../config"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { CommentsRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { FindCommentQuery } from "../impl"; diff --git a/src/article/queries/handlers/find-feed-article.handler.ts b/src/article/application/queries/handlers/find-feed-article.handler.ts similarity index 85% rename from src/article/queries/handlers/find-feed-article.handler.ts rename to src/article/application/queries/handlers/find-feed-article.handler.ts index a0bf739..280b322 100644 --- a/src/article/queries/handlers/find-feed-article.handler.ts +++ b/src/article/application/queries/handlers/find-feed-article.handler.ts @@ -1,11 +1,11 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { getRepository, Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { FollowsEntity } from "../../../profile/core/entities/follows.entity"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { ArticlesRO } from "../../core/interfaces/article.interface"; +import { READ_CONNECTION } from "../../../../config"; +import { FollowsEntity } from "../../../../profile/core/entities/follows.entity"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { ArticlesRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { FindFeedArticleQuery } from "../impl"; @@ -22,7 +22,7 @@ export class FindFeedArticleQueryHandler private readonly articleRepository: Repository, private readonly articleService: ArticleService - ) { } + ) {} async execute({ userId, query }: FindFeedArticleQuery): Promise { const _follows = await this.followsRepository.find({ followerId: userId }); diff --git a/src/article/queries/handlers/find-one-article.handler.ts b/src/article/application/queries/handlers/find-one-article.handler.ts similarity index 81% rename from src/article/queries/handlers/find-one-article.handler.ts rename to src/article/application/queries/handlers/find-one-article.handler.ts index 963bfd5..71ea1c5 100644 --- a/src/article/queries/handlers/find-one-article.handler.ts +++ b/src/article/application/queries/handlers/find-one-article.handler.ts @@ -2,11 +2,11 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { FollowsEntity } from "../../../profile/core/entities/follows.entity"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { ArticleRO } from "../../core/interfaces/article.interface"; +import { READ_CONNECTION } from "../../../../config"; +import { FollowsEntity } from "../../../../profile/core/entities/follows.entity"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { ArticleEntity } from "../../../core/entities/article.entity"; +import { ArticleRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; import { FindOneArticleQuery } from "../impl"; diff --git a/src/article/queries/handlers/index.ts b/src/article/application/queries/handlers/index.ts similarity index 100% rename from src/article/queries/handlers/index.ts rename to src/article/application/queries/handlers/index.ts diff --git a/src/article/queries/handlers/indexing-article.handler.ts b/src/article/application/queries/handlers/indexing-article.handler.ts similarity index 100% rename from src/article/queries/handlers/indexing-article.handler.ts rename to src/article/application/queries/handlers/indexing-article.handler.ts diff --git a/src/article/queries/handlers/search-article.handler.ts b/src/article/application/queries/handlers/search-article.handler.ts similarity index 100% rename from src/article/queries/handlers/search-article.handler.ts rename to src/article/application/queries/handlers/search-article.handler.ts diff --git a/src/article/queries/impl/find-all.article.query.ts b/src/article/application/queries/impl/find-all.article.query.ts similarity index 67% rename from src/article/queries/impl/find-all.article.query.ts rename to src/article/application/queries/impl/find-all.article.query.ts index 9aa0d44..48842e3 100644 --- a/src/article/queries/impl/find-all.article.query.ts +++ b/src/article/application/queries/impl/find-all.article.query.ts @@ -1,4 +1,4 @@ -import { ArticleFilters } from "../../dto/article-query"; +import { ArticleFilters } from "../../../core/dto/article-query"; export class FindAllArticleQuery { constructor( diff --git a/src/article/queries/impl/find-comments.query.ts b/src/article/application/queries/impl/find-comments.query.ts similarity index 100% rename from src/article/queries/impl/find-comments.query.ts rename to src/article/application/queries/impl/find-comments.query.ts diff --git a/src/article/queries/impl/find-feed-article.query.ts b/src/article/application/queries/impl/find-feed-article.query.ts similarity index 67% rename from src/article/queries/impl/find-feed-article.query.ts rename to src/article/application/queries/impl/find-feed-article.query.ts index b4f55bc..b2fbd77 100644 --- a/src/article/queries/impl/find-feed-article.query.ts +++ b/src/article/application/queries/impl/find-feed-article.query.ts @@ -1,4 +1,4 @@ -import { ArticleFilters } from "../../dto/article-query"; +import { ArticleFilters } from "../../../core/dto/article-query"; export class FindFeedArticleQuery { constructor( diff --git a/src/article/queries/impl/find-one-article.query.ts b/src/article/application/queries/impl/find-one-article.query.ts similarity index 100% rename from src/article/queries/impl/find-one-article.query.ts rename to src/article/application/queries/impl/find-one-article.query.ts diff --git a/src/article/queries/impl/index.ts b/src/article/application/queries/impl/index.ts similarity index 100% rename from src/article/queries/impl/index.ts rename to src/article/application/queries/impl/index.ts diff --git a/src/article/queries/impl/search-article.query.ts b/src/article/application/queries/impl/search-article.query.ts similarity index 100% rename from src/article/queries/impl/search-article.query.ts rename to src/article/application/queries/impl/search-article.query.ts diff --git a/src/article/queries/index.ts b/src/article/application/queries/index.ts similarity index 100% rename from src/article/queries/index.ts rename to src/article/application/queries/index.ts diff --git a/src/article/queries/query.module.ts b/src/article/application/queries/query.module.ts similarity index 65% rename from src/article/queries/query.module.ts rename to src/article/application/queries/query.module.ts index 62cc854..cfcf178 100644 --- a/src/article/queries/query.module.ts +++ b/src/article/application/queries/query.module.ts @@ -1,13 +1,14 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; + import { QueryHandlers } from "."; -import { READ_CONNECTION } from "../../config"; -import { FollowsEntity } from "../../profile/core/entities/follows.entity"; -import { UserEntity } from "../../user/core/entities/user.entity"; -import { UserModule } from "../../user/user.module"; -import { ArticleEntity } from "../core"; -import { CommentEntity } from "../core/entities/comment.entity"; +import { READ_CONNECTION } from "../../../config"; +import { FollowsEntity } from "../../../profile/core/entities/follows.entity"; +import { UserEntity } from "../../../user/core/entities/user.entity"; +import { UserModule } from "../../../user/user.module"; +import { ArticleEntity } from "../../core"; +import { CommentEntity } from "../../core/entities/comment.entity"; import { ArticleService } from "../services/article.service"; import { ElasticSearchModule } from "../../elastic-search/elastic-search.module"; import { RabbitMqModule } from "../../rabbitmq/rabbitmq.module"; diff --git a/src/article/services/article.service.ts b/src/article/application/services/article.service.ts similarity index 96% rename from src/article/services/article.service.ts rename to src/article/application/services/article.service.ts index cf10d5b..eb153b3 100644 --- a/src/article/services/article.service.ts +++ b/src/article/application/services/article.service.ts @@ -1,12 +1,12 @@ import { Injectable } from "@nestjs/common"; -import { UserEntity } from "../../user/core/entities/user.entity"; +import { UserEntity } from "../../../user/core/entities/user.entity"; import { ArticleData, IComment, ArticleEntity, BlockEntity, CommentEntity, -} from "../core"; +} from "../../core"; const slug = require("slug"); @Injectable() diff --git a/src/article/article.module.ts b/src/article/article.module.ts index 2b9c0db..e8888d9 100644 --- a/src/article/article.module.ts +++ b/src/article/article.module.ts @@ -5,17 +5,18 @@ import { RequestMethod, } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; + import { RabbitMqModule } from "../rabbitmq/rabbitmq.module"; import { RedisModule } from "../redis/redis.module"; import { AuthMiddleware } from "../shared/middleware/auth.middleware"; import { UserModule } from "../user/user.module"; -import { ArticleController } from "./article.controller"; -import { ArticleProjection } from "./article.projection"; -import { CommandModule } from "./commands/command.module"; +import { ArticleProjection } from "./application/article.projection"; +import { CommandModule } from "./application/commands/command.module"; +import { EventModule } from "./application/events/event.module"; +import { QueryModule } from "./application/queries/query.module"; +import { ArticleService } from "./application/services/article.service"; +import { ArticleController } from "./presentation/article.controller"; import { ElasticSearchArticleProjection } from "./elastic-search-article.projection"; -import { EventModule } from "./events/event.module"; -import { QueryModule } from "./queries/query.module"; -import { ArticleService } from "./services/article.service"; @Module({ imports: [ diff --git a/src/article/dto/article-query.ts b/src/article/core/dto/article-query.ts similarity index 100% rename from src/article/dto/article-query.ts rename to src/article/core/dto/article-query.ts diff --git a/src/article/dto/block.dto.ts b/src/article/core/dto/block.dto.ts similarity index 91% rename from src/article/dto/block.dto.ts rename to src/article/core/dto/block.dto.ts index 443e6c9..f5b2203 100644 --- a/src/article/dto/block.dto.ts +++ b/src/article/core/dto/block.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from "@nestjs/swagger"; -import { BlockType } from "../core/enums/block.enum"; +import { BlockType } from "../enums/block.enum"; class Info { @ApiProperty() diff --git a/src/article/dto/create-article.dto.ts b/src/article/core/dto/create-article.dto.ts similarity index 100% rename from src/article/dto/create-article.dto.ts rename to src/article/core/dto/create-article.dto.ts diff --git a/src/article/dto/create-comment.ts b/src/article/core/dto/create-comment.ts similarity index 100% rename from src/article/dto/create-comment.ts rename to src/article/core/dto/create-comment.ts diff --git a/src/article/dto/index.ts b/src/article/core/dto/index.ts similarity index 100% rename from src/article/dto/index.ts rename to src/article/core/dto/index.ts diff --git a/src/article/dto/search-article.ts b/src/article/core/dto/search-article.ts similarity index 100% rename from src/article/dto/search-article.ts rename to src/article/core/dto/search-article.ts diff --git a/src/article/events/impl/article-favorited.event.ts b/src/article/events/impl/article-favorited.event.ts deleted file mode 100644 index b9fc346..0000000 --- a/src/article/events/impl/article-favorited.event.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { ArticleEntity } from "../../core/entities/article.entity"; - -export class ArticleFavoritedEvent { - constructor( - public readonly user: UserEntity, - public readonly article: ArticleEntity - ) {} -} diff --git a/src/article/article.controller.ts b/src/article/presentation/article.controller.ts similarity index 95% rename from src/article/article.controller.ts rename to src/article/presentation/article.controller.ts index fef294d..1c899b8 100644 --- a/src/article/article.controller.ts +++ b/src/article/presentation/article.controller.ts @@ -17,7 +17,7 @@ import { ApiResponse, ApiTags, } from "@nestjs/swagger"; -import { User } from "../shared/middleware/user.decorator"; +import { User } from "../../shared/middleware/user.decorator"; import { CreateArticleCommand, CreateCommentCommand, @@ -26,22 +26,22 @@ import { FavoriteArticleCommand, UnFavoriteArticleCommand, UpdateArticleCommand, -} from "./commands"; -import { ArticleRO, ArticlesRO, CommentsRO } from "./core"; -import { - ArticleFilters, - CreateArticleDto, - CreateCommentDto, - SearchArticleDto, -} from "./dto"; +} from "../application/commands"; import { FindAllArticleQuery, FindCommentQuery, FindFeedArticleQuery, FindOneArticleQuery, SearchArticleQuery, -} from "./queries"; -import { IndexingArticleQuery } from "./queries/handlers/indexing-article.handler"; +} from "../application/queries"; +import { IndexingArticleQuery } from "../application/queries/handlers/indexing-article.handler"; +import { ArticleRO, ArticlesRO, CommentsRO } from "../core"; +import { + ArticleFilters, + CreateArticleDto, + CreateCommentDto, + SearchArticleDto, +} from "../core/dto"; @ApiBearerAuth() @ApiTags("articles") From a9eac91e1e1d3aff2ef4fe57babd6e2d132fb35b Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Fri, 13 Oct 2023 14:47:15 +0700 Subject: [PATCH 11/19] feat: apply CLEAN Architect for profile-module --- .../{ => application}/commands/command.module.ts | 14 +++++++------- .../commands/handlers/follow-profile.handler.ts | 14 +++++++------- .../{ => application}/commands/handlers/index.ts | 0 .../commands/handlers/unfollow-profile.handler.ts | 14 +++++++------- .../commands/impl/follow-profile.command.ts | 0 .../{ => application}/commands/impl/index.ts | 0 .../commands/impl/unfollow-profile.command.ts | 0 src/profile/{ => application}/commands/index.ts | 0 .../{ => application}/events/event.module.ts | 6 +++--- .../{ => application}/events/handlers/index.ts | 0 .../events/handlers/profile-followed.handler.ts | 4 ++-- .../events/handlers/profile-unfollowed.handler.ts | 4 ++-- src/profile/{ => application}/events/impl/index.ts | 0 .../events/impl/profile-followed.event.ts | 2 +- .../events/impl/profile-unfollowed.event.ts | 2 +- src/profile/{ => application}/events/index.ts | 0 .../{ => application}/profile.projection.ts | 11 ++++++----- .../queries/handlers/find-profile.handler.ts | 8 ++++---- .../{ => application}/queries/handlers/index.ts | 0 .../queries/impl/find-profile.query.ts | 0 .../{ => application}/queries/impl/index.ts | 0 src/profile/{ => application}/queries/index.ts | 0 .../{ => application}/queries/query.module.ts | 12 ++++++------ .../{ => application}/services/profile.service.ts | 0 .../{ => presentation}/profile.controller.ts | 12 ++++++++---- src/profile/profile.module.ts | 12 ++++++------ 26 files changed, 60 insertions(+), 55 deletions(-) rename src/profile/{ => application}/commands/command.module.ts (55%) rename src/profile/{ => application}/commands/handlers/follow-profile.handler.ts (81%) rename src/profile/{ => application}/commands/handlers/index.ts (100%) rename src/profile/{ => application}/commands/handlers/unfollow-profile.handler.ts (79%) rename src/profile/{ => application}/commands/impl/follow-profile.command.ts (100%) rename src/profile/{ => application}/commands/impl/index.ts (100%) rename src/profile/{ => application}/commands/impl/unfollow-profile.command.ts (100%) rename src/profile/{ => application}/commands/index.ts (100%) rename src/profile/{ => application}/events/event.module.ts (67%) rename src/profile/{ => application}/events/handlers/index.ts (100%) rename src/profile/{ => application}/events/handlers/profile-followed.handler.ts (86%) rename src/profile/{ => application}/events/handlers/profile-unfollowed.handler.ts (86%) rename src/profile/{ => application}/events/impl/index.ts (100%) rename src/profile/{ => application}/events/impl/profile-followed.event.ts (57%) rename src/profile/{ => application}/events/impl/profile-unfollowed.event.ts (56%) rename src/profile/{ => application}/events/index.ts (100%) rename src/profile/{ => application}/profile.projection.ts (74%) rename src/profile/{ => application}/queries/handlers/find-profile.handler.ts (82%) rename src/profile/{ => application}/queries/handlers/index.ts (100%) rename src/profile/{ => application}/queries/impl/find-profile.query.ts (100%) rename src/profile/{ => application}/queries/impl/index.ts (100%) rename src/profile/{ => application}/queries/index.ts (100%) rename src/profile/{ => application}/queries/query.module.ts (58%) rename src/profile/{ => application}/services/profile.service.ts (100%) rename src/profile/{ => presentation}/profile.controller.ts (81%) diff --git a/src/profile/commands/command.module.ts b/src/profile/application/commands/command.module.ts similarity index 55% rename from src/profile/commands/command.module.ts rename to src/profile/application/commands/command.module.ts index e90350f..4657a63 100644 --- a/src/profile/commands/command.module.ts +++ b/src/profile/application/commands/command.module.ts @@ -1,13 +1,13 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; + import { CommandHandlers } from "."; -import { WRITE_CONNECTION } from "../../config"; -import { RabbitMqModule } from "../../rabbitmq/rabbitmq.module"; -import { UserEntity } from "../../user/core/entities/user.entity"; -import { UserModule } from "../../user/user.module"; -import { FollowsEntity } from "../core/entities/follows.entity"; -import { ProfileController } from "../profile.controller"; +import { WRITE_CONNECTION } from "../../../config"; +import { RabbitMqModule } from "../../../rabbitmq/rabbitmq.module"; +import { UserEntity } from "../../../user/core/entities/user.entity"; +import { UserModule } from "../../../user/user.module"; +import { FollowsEntity } from "../../core/entities/follows.entity"; import { ProfileService } from "../services/profile.service"; @Module({ @@ -18,7 +18,7 @@ import { ProfileService } from "../services/profile.service"; RabbitMqModule, ], providers: [ProfileService, ...CommandHandlers], - controllers: [ProfileController], + controllers: [], exports: [], }) export class CommandModule {} diff --git a/src/profile/commands/handlers/follow-profile.handler.ts b/src/profile/application/commands/handlers/follow-profile.handler.ts similarity index 81% rename from src/profile/commands/handlers/follow-profile.handler.ts rename to src/profile/application/commands/handlers/follow-profile.handler.ts index 464b1a9..c23ab97 100644 --- a/src/profile/commands/handlers/follow-profile.handler.ts +++ b/src/profile/application/commands/handlers/follow-profile.handler.ts @@ -2,16 +2,16 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { PROFILE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { FollowsEntity } from "../../core/entities/follows.entity"; -import { MessageType } from "../../core/enums/profile.enum"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { PROFILE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { FollowsEntity } from "../../../core/entities/follows.entity"; +import { MessageType } from "../../../core/enums/profile.enum"; import { ProfileData, ProfileRO, -} from "../../core/interfaces/profile.interface"; +} from "../../../core/interfaces/profile.interface"; import { FollowProfileCommand } from "../impl"; @CommandHandler(FollowProfileCommand) diff --git a/src/profile/commands/handlers/index.ts b/src/profile/application/commands/handlers/index.ts similarity index 100% rename from src/profile/commands/handlers/index.ts rename to src/profile/application/commands/handlers/index.ts diff --git a/src/profile/commands/handlers/unfollow-profile.handler.ts b/src/profile/application/commands/handlers/unfollow-profile.handler.ts similarity index 79% rename from src/profile/commands/handlers/unfollow-profile.handler.ts rename to src/profile/application/commands/handlers/unfollow-profile.handler.ts index 1e863d8..e7651f7 100644 --- a/src/profile/commands/handlers/unfollow-profile.handler.ts +++ b/src/profile/application/commands/handlers/unfollow-profile.handler.ts @@ -2,16 +2,16 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { PROFILE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { FollowsEntity } from "../../core/entities/follows.entity"; -import { MessageType } from "../../core/enums/profile.enum"; +import { WRITE_CONNECTION } from "../../../../config"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { PROFILE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { FollowsEntity } from "../../../core/entities/follows.entity"; +import { MessageType } from "../../../core/enums/profile.enum"; import { ProfileData, ProfileRO, -} from "../../core/interfaces/profile.interface"; +} from "../../../core/interfaces/profile.interface"; import { UnFollowProfileCommand } from "../impl"; @CommandHandler(UnFollowProfileCommand) diff --git a/src/profile/commands/impl/follow-profile.command.ts b/src/profile/application/commands/impl/follow-profile.command.ts similarity index 100% rename from src/profile/commands/impl/follow-profile.command.ts rename to src/profile/application/commands/impl/follow-profile.command.ts diff --git a/src/profile/commands/impl/index.ts b/src/profile/application/commands/impl/index.ts similarity index 100% rename from src/profile/commands/impl/index.ts rename to src/profile/application/commands/impl/index.ts diff --git a/src/profile/commands/impl/unfollow-profile.command.ts b/src/profile/application/commands/impl/unfollow-profile.command.ts similarity index 100% rename from src/profile/commands/impl/unfollow-profile.command.ts rename to src/profile/application/commands/impl/unfollow-profile.command.ts diff --git a/src/profile/commands/index.ts b/src/profile/application/commands/index.ts similarity index 100% rename from src/profile/commands/index.ts rename to src/profile/application/commands/index.ts diff --git a/src/profile/events/event.module.ts b/src/profile/application/events/event.module.ts similarity index 67% rename from src/profile/events/event.module.ts rename to src/profile/application/events/event.module.ts index 4e922a3..184b000 100644 --- a/src/profile/events/event.module.ts +++ b/src/profile/application/events/event.module.ts @@ -1,9 +1,9 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; -import { READ_CONNECTION } from "../../config"; -import { EventHandlers } from "../events"; -import { FollowsEntity } from "../core/entities/follows.entity"; +import { READ_CONNECTION } from "../../../config"; +import { EventHandlers } from "."; +import { FollowsEntity } from "../../core/entities/follows.entity"; @Module({ imports: [ diff --git a/src/profile/events/handlers/index.ts b/src/profile/application/events/handlers/index.ts similarity index 100% rename from src/profile/events/handlers/index.ts rename to src/profile/application/events/handlers/index.ts diff --git a/src/profile/events/handlers/profile-followed.handler.ts b/src/profile/application/events/handlers/profile-followed.handler.ts similarity index 86% rename from src/profile/events/handlers/profile-followed.handler.ts rename to src/profile/application/events/handlers/profile-followed.handler.ts index 5048c13..691ba64 100644 --- a/src/profile/events/handlers/profile-followed.handler.ts +++ b/src/profile/application/events/handlers/profile-followed.handler.ts @@ -3,8 +3,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { FollowsEntity } from "../../core/entities/follows.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { FollowsEntity } from "../../../core/entities/follows.entity"; import { ProfileFollowedEvent } from "../impl"; @EventsHandler(ProfileFollowedEvent) diff --git a/src/profile/events/handlers/profile-unfollowed.handler.ts b/src/profile/application/events/handlers/profile-unfollowed.handler.ts similarity index 86% rename from src/profile/events/handlers/profile-unfollowed.handler.ts rename to src/profile/application/events/handlers/profile-unfollowed.handler.ts index 8fe8d13..d6684af 100644 --- a/src/profile/events/handlers/profile-unfollowed.handler.ts +++ b/src/profile/application/events/handlers/profile-unfollowed.handler.ts @@ -3,8 +3,8 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { FollowsEntity } from "../../core/entities/follows.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { FollowsEntity } from "../../../core/entities/follows.entity"; import { ProfileUnFollowedEvent } from "../impl"; @EventsHandler(ProfileUnFollowedEvent) diff --git a/src/profile/events/impl/index.ts b/src/profile/application/events/impl/index.ts similarity index 100% rename from src/profile/events/impl/index.ts rename to src/profile/application/events/impl/index.ts diff --git a/src/profile/events/impl/profile-followed.event.ts b/src/profile/application/events/impl/profile-followed.event.ts similarity index 57% rename from src/profile/events/impl/profile-followed.event.ts rename to src/profile/application/events/impl/profile-followed.event.ts index 0ce6de1..81ebb8f 100644 --- a/src/profile/events/impl/profile-followed.event.ts +++ b/src/profile/application/events/impl/profile-followed.event.ts @@ -1,4 +1,4 @@ -import { FollowsEntity } from "../../core/entities/follows.entity"; +import { FollowsEntity } from "../../../core/entities/follows.entity"; export class ProfileFollowedEvent { constructor(public readonly follow: FollowsEntity) {} diff --git a/src/profile/events/impl/profile-unfollowed.event.ts b/src/profile/application/events/impl/profile-unfollowed.event.ts similarity index 56% rename from src/profile/events/impl/profile-unfollowed.event.ts rename to src/profile/application/events/impl/profile-unfollowed.event.ts index e84a5c9..5ba85cf 100644 --- a/src/profile/events/impl/profile-unfollowed.event.ts +++ b/src/profile/application/events/impl/profile-unfollowed.event.ts @@ -1,4 +1,4 @@ -import { IFollow } from "../../core/interfaces/profile.interface"; +import { IFollow } from "../../../core/interfaces/profile.interface"; export class ProfileUnFollowedEvent { constructor(public readonly follow: IFollow) {} diff --git a/src/profile/events/index.ts b/src/profile/application/events/index.ts similarity index 100% rename from src/profile/events/index.ts rename to src/profile/application/events/index.ts diff --git a/src/profile/profile.projection.ts b/src/profile/application/profile.projection.ts similarity index 74% rename from src/profile/profile.projection.ts rename to src/profile/application/profile.projection.ts index f3c714e..7144494 100644 --- a/src/profile/profile.projection.ts +++ b/src/profile/application/profile.projection.ts @@ -1,10 +1,11 @@ import { Injectable } from "@nestjs/common"; import { EventBus } from "@nestjs/cqrs"; -import { ConsumerService } from "../rabbitmq/consumer.service"; -import { PROFILE_QUEUE } from "../rabbitmq/rabbitmq.constants"; -import { IMessage, IProjection } from "./core"; -import { FollowsEntity } from "./core/entities/follows.entity"; -import { MessageType } from "./core/enums/profile.enum"; + +import { ConsumerService } from "../../rabbitmq/consumer.service"; +import { PROFILE_QUEUE } from "../../rabbitmq/rabbitmq.constants"; +import { IMessage, IProjection } from "../core"; +import { FollowsEntity } from "../core/entities/follows.entity"; +import { MessageType } from "../core/enums/profile.enum"; import { ProfileFollowedEvent, ProfileUnFollowedEvent } from "./events"; @Injectable() diff --git a/src/profile/queries/handlers/find-profile.handler.ts b/src/profile/application/queries/handlers/find-profile.handler.ts similarity index 82% rename from src/profile/queries/handlers/find-profile.handler.ts rename to src/profile/application/queries/handlers/find-profile.handler.ts index 8b5b589..d29670a 100644 --- a/src/profile/queries/handlers/find-profile.handler.ts +++ b/src/profile/application/queries/handlers/find-profile.handler.ts @@ -1,13 +1,13 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../config"; -import { UserEntity } from "../../../user/core/entities/user.entity"; -import { FollowsEntity } from "../../core/entities/follows.entity"; +import { READ_CONNECTION } from "../../../../config"; +import { UserEntity } from "../../../../user/core/entities/user.entity"; +import { FollowsEntity } from "../../../core/entities/follows.entity"; import { ProfileData, ProfileRO, -} from "../../core/interfaces/profile.interface"; +} from "../../../core/interfaces/profile.interface"; import { FindProfileQuery } from "../impl"; @QueryHandler(FindProfileQuery) diff --git a/src/profile/queries/handlers/index.ts b/src/profile/application/queries/handlers/index.ts similarity index 100% rename from src/profile/queries/handlers/index.ts rename to src/profile/application/queries/handlers/index.ts diff --git a/src/profile/queries/impl/find-profile.query.ts b/src/profile/application/queries/impl/find-profile.query.ts similarity index 100% rename from src/profile/queries/impl/find-profile.query.ts rename to src/profile/application/queries/impl/find-profile.query.ts diff --git a/src/profile/queries/impl/index.ts b/src/profile/application/queries/impl/index.ts similarity index 100% rename from src/profile/queries/impl/index.ts rename to src/profile/application/queries/impl/index.ts diff --git a/src/profile/queries/index.ts b/src/profile/application/queries/index.ts similarity index 100% rename from src/profile/queries/index.ts rename to src/profile/application/queries/index.ts diff --git a/src/profile/queries/query.module.ts b/src/profile/application/queries/query.module.ts similarity index 58% rename from src/profile/queries/query.module.ts rename to src/profile/application/queries/query.module.ts index cbe5f28..193a546 100644 --- a/src/profile/queries/query.module.ts +++ b/src/profile/application/queries/query.module.ts @@ -1,12 +1,12 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; + import { QueryHandlers } from "."; -import { READ_CONNECTION } from "../../config"; -import { UserEntity } from "../../user/core/entities/user.entity"; -import { UserModule } from "../../user/user.module"; -import { FollowsEntity } from "../core/entities/follows.entity"; -import { ProfileController } from "../profile.controller"; +import { READ_CONNECTION } from "../../../config"; +import { UserEntity } from "../../../user/core/entities/user.entity"; +import { UserModule } from "../../../user/user.module"; +import { FollowsEntity } from "../../core/entities/follows.entity"; import { ProfileService } from "../services/profile.service"; @Module({ @@ -16,7 +16,7 @@ import { ProfileService } from "../services/profile.service"; CqrsModule, ], providers: [ProfileService, ...QueryHandlers], - controllers: [ProfileController], + controllers: [], exports: [], }) export class QueryModule {} diff --git a/src/profile/services/profile.service.ts b/src/profile/application/services/profile.service.ts similarity index 100% rename from src/profile/services/profile.service.ts rename to src/profile/application/services/profile.service.ts diff --git a/src/profile/profile.controller.ts b/src/profile/presentation/profile.controller.ts similarity index 81% rename from src/profile/profile.controller.ts rename to src/profile/presentation/profile.controller.ts index ae313cc..b5b0d05 100644 --- a/src/profile/profile.controller.ts +++ b/src/profile/presentation/profile.controller.ts @@ -1,10 +1,14 @@ import { Controller, Delete, Get, Param, Post } from "@nestjs/common"; import { CommandBus, QueryBus } from "@nestjs/cqrs"; import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger"; -import { User } from "../shared/middleware/user.decorator"; -import { FollowProfileCommand, UnFollowProfileCommand } from "./commands"; -import { FindProfileQuery } from "./queries"; -import { ProfileRO } from "./core/interfaces/profile.interface"; + +import { User } from "../../shared/middleware/user.decorator"; +import { + FollowProfileCommand, + UnFollowProfileCommand, +} from "../application/commands"; +import { FindProfileQuery } from "../application/queries"; +import { ProfileRO } from "../core/interfaces/profile.interface"; @ApiBearerAuth() @ApiTags("profiles") diff --git a/src/profile/profile.module.ts b/src/profile/profile.module.ts index 1a3b5d8..6ff68c2 100644 --- a/src/profile/profile.module.ts +++ b/src/profile/profile.module.ts @@ -8,12 +8,12 @@ import { CqrsModule } from "@nestjs/cqrs"; import { RabbitMqModule } from "../rabbitmq/rabbitmq.module"; import { AuthMiddleware } from "../shared/middleware/auth.middleware"; import { UserModule } from "../user/user.module"; -import { CommandModule } from "./commands/command.module"; -import { EventModule } from "./events/event.module"; -import { ProfileController } from "./profile.controller"; -import { ProfileProjection } from "./profile.projection"; -import { ProfileService } from "./services/profile.service"; -import { QueryModule } from "./queries/query.module"; +import { CommandModule } from "./application/commands/command.module"; +import { EventModule } from "./application/events/event.module"; +import { ProfileController } from "./presentation/profile.controller"; +import { ProfileProjection } from "./application/profile.projection"; +import { ProfileService } from "./application/services/profile.service"; +import { QueryModule } from "./application/queries/query.module"; import { RedisModule } from "../redis/redis.module"; @Module({ From fa1990893082d8345f7c5d254b8f9cabf4ab00eb Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Fri, 13 Oct 2023 14:58:52 +0700 Subject: [PATCH 12/19] feat: separate db-module --- src/app.module.ts | 44 +++-------------------------- src/database/database.module.ts | 49 +++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 40 deletions(-) create mode 100644 src/database/database.module.ts diff --git a/src/app.module.ts b/src/app.module.ts index 379e85e..69236de 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,60 +1,24 @@ import { Module } from "@nestjs/common"; import { ConfigModule } from "@nestjs/config"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import * as dotenv from "dotenv"; -import { AppController } from "./app.controller"; + import { ArticleModule } from "./article/article.module"; -import { READ_CONNECTION, WRITE_CONNECTION } from "./config"; +import { DatabaseModule } from "./database/database.module"; import { MediaModule } from "./media/media.module"; import { ProfileModule } from "./profile/profile.module"; import { TagModule } from "./tag/tag.module"; import { UserModule } from "./user/user.module"; -dotenv.config(); - -const defaultOptions = { - type: process.env.DATABASE_ENGINE, - host: process.env.DATABASE_HOST, - port: parseInt(process.env.DATABASE_PORT), - username: process.env.DATABASE_USERNAME, - password: process.env.DATABASE_PASSWORD, - entities: [__dirname + process.env.TYPEORM_ENTITIES], - migrations: [__dirname + process.env.TYPEORM_MIGRATIONS], - logging: process.env.TYPEORM_LOGGING === "true", - synchronize: process.env.TYPEORM_SYNCHRONIZE === "true", - migrationsRun: process.env.TYPEORM_MIGRATION_RUN === "true", - migrationsTableName: "migrations", - cli: { - migrationsDir: process.env.TYPEORM_MIGRATIONS_DIR, - }, -}; - @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), - TypeOrmModule.forRootAsync({ - name: WRITE_CONNECTION, - useFactory: () => ({ - ...defaultOptions, - type: "postgres", - database: process.env.WRITE_DATABASE_NAME, - }), - }), - TypeOrmModule.forRootAsync({ - name: READ_CONNECTION, - useFactory: () => ({ - ...defaultOptions, - type: "postgres", - database: process.env.READ_DATABASE_NAME, - }), - }), + DatabaseModule, ArticleModule, UserModule, ProfileModule, TagModule, MediaModule, ], - controllers: [AppController], + controllers: [], providers: [], }) export class ApplicationModule {} diff --git a/src/database/database.module.ts b/src/database/database.module.ts new file mode 100644 index 0000000..bfca8bf --- /dev/null +++ b/src/database/database.module.ts @@ -0,0 +1,49 @@ +import { Module } from "@nestjs/common"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import * as dotenv from "dotenv"; + +import { READ_CONNECTION, WRITE_CONNECTION } from "../config"; +import { join } from "path"; + +dotenv.config(); + +const defaultOptions = { + type: process.env.DATABASE_ENGINE, + host: process.env.DATABASE_HOST, + port: parseInt(process.env.DATABASE_PORT), + username: process.env.DATABASE_USERNAME, + password: process.env.DATABASE_PASSWORD, + entities: [join(__dirname, "../", "/**/core/entities/**.entity{.ts,.js}")], + migrations: [join(__dirname, "../", "/database/migrations/**{.ts,.js}")], + logging: process.env.TYPEORM_LOGGING === "true", + synchronize: process.env.TYPEORM_SYNCHRONIZE === "true", + migrationsRun: process.env.TYPEORM_MIGRATION_RUN === "true", + migrationsTableName: "migrations", + cli: { + migrationsDir: process.env.TYPEORM_MIGRATIONS_DIR, + }, +}; + +@Module({ + imports: [ + TypeOrmModule.forRootAsync({ + name: WRITE_CONNECTION, + useFactory: () => ({ + ...defaultOptions, + type: "postgres", + database: process.env.WRITE_DATABASE_NAME, + }), + }), + TypeOrmModule.forRootAsync({ + name: READ_CONNECTION, + useFactory: () => ({ + ...defaultOptions, + type: "postgres", + database: process.env.READ_DATABASE_NAME, + }), + }), + ], + controllers: [], + providers: [], +}) +export class DatabaseModule {} From 296d8a9d5e7d5653b1bc383750aaebd3572d233d Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Fri, 13 Oct 2023 15:01:57 +0700 Subject: [PATCH 13/19] wip --- src/app.controller.ts | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 src/app.controller.ts diff --git a/src/app.controller.ts b/src/app.controller.ts deleted file mode 100644 index 0cd25d1..0000000 --- a/src/app.controller.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Get, Controller } from '@nestjs/common'; - -@Controller() -export class AppController { - @Get() - root(): string { - return 'Hello World!'; - } -} \ No newline at end of file From 1c53d072a9eef36ca8786fa0c68130ba30173d56 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Fri, 13 Oct 2023 15:14:29 +0700 Subject: [PATCH 14/19] bug: wrong import file path --- src/main.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.ts b/src/main.ts index dadbea3..31f84ea 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,14 +1,14 @@ -import { NestFactory } from "@nestjs/core"; -import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger"; -import { json, urlencoded } from "express"; import { INestApplication, NestApplicationOptions } from "@nestjs/common"; +import { NestFactory } from "@nestjs/core"; +import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; import * as cluster from "cluster"; +import { json, urlencoded } from "express"; import * as os from "os"; import { ApplicationModule } from "./app.module"; -import { ArticleProjection } from "./article/article.projection"; +import { ArticleProjection } from "./article/application/article.projection"; +import { ProfileProjection } from "./profile/application/profile.projection"; import { UserProjection } from "./user/application/user.projection"; -import { ProfileProjection } from "./profile/profile.projection"; import { ElasticSearchArticleProjection } from "./article/elastic-search-article.projection"; async function executeProjection(app: INestApplication) { @@ -30,7 +30,7 @@ async function bootstrap() { const numWorkers = os.cpus().length; console.log(`Master cluster setting up ${numWorkers} workers...`); - for (let i = 0; i < 1; i++) { + for (let i = 0; i < numWorkers; i++) { cluster.fork(); } From 440a7b60a919c4f0c37a262389b53819fc3b0e61 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Sat, 14 Oct 2023 21:44:29 +0700 Subject: [PATCH 15/19] feat: enhance connection variables with .env --- .env.example | 5 +++++ src/article/application/commands/command.module.ts | 2 +- .../commands/handlers/create-article.handler.ts | 2 +- .../commands/handlers/create-comment.handler.ts | 2 +- .../commands/handlers/delete-article.handler.ts | 2 +- .../commands/handlers/delete-comment.handler.ts | 2 +- .../commands/handlers/favorite-article.handler.ts | 2 +- .../commands/handlers/unfavorite-article.handler.ts | 2 +- .../commands/handlers/update-article.handler.ts | 2 +- src/article/application/events/event.module.ts | 2 +- .../events/handlers/article-created.handler.ts | 2 +- .../events/handlers/article-deleted.handler.ts | 2 +- .../events/handlers/article-favorited.handler.ts | 2 +- .../events/handlers/article-unfavorited.handler.ts | 2 +- .../events/handlers/article-updated.handler.ts | 2 +- .../events/handlers/comment-created.handler.ts | 2 +- .../events/handlers/comment-deleted.handler.ts | 2 +- .../queries/handlers/find-all.article.handler.ts | 2 +- .../queries/handlers/find-comments.handler.ts | 2 +- .../queries/handlers/find-feed-article.handler.ts | 2 +- .../queries/handlers/find-one-article.handler.ts | 2 +- src/article/application/queries/query.module.ts | 2 +- src/config.ts | 4 ---- src/configs/index.ts | 4 ++++ src/database/database.module.ts | 2 +- src/profile/application/commands/command.module.ts | 2 +- .../commands/handlers/follow-profile.handler.ts | 2 +- .../commands/handlers/unfollow-profile.handler.ts | 2 +- src/profile/application/events/event.module.ts | 2 +- .../events/handlers/profile-followed.handler.ts | 2 +- .../events/handlers/profile-unfollowed.handler.ts | 2 +- .../queries/handlers/find-profile.handler.ts | 2 +- src/profile/application/queries/query.module.ts | 2 +- src/shared/base.controller.ts | 11 +++++------ src/shared/middleware/auth.middleware.ts | 7 ++++--- src/shared/middleware/user.decorator.ts | 5 +++-- src/tag/tag.module.ts | 2 +- src/tag/tag.service.ts | 2 +- src/user/application/commands/command.module.ts | 2 +- .../commands/handlers/create-user.handler.ts | 2 +- .../commands/handlers/update-user.handler.ts | 2 +- src/user/application/events/event.module.ts | 2 +- .../events/handlers/user-created.handler.ts | 2 +- .../events/handlers/user-updated.handler.ts | 2 +- .../queries/handlers/find-user-by-email.handler.ts | 2 +- .../queries/handlers/find-user-by-id.handler.ts | 2 +- .../application/queries/handlers/login.handler.ts | 2 +- src/user/application/queries/query.module.ts | 2 +- src/user/application/services/user.service.ts | 7 ++++--- 49 files changed, 67 insertions(+), 60 deletions(-) delete mode 100644 src/config.ts create mode 100644 src/configs/index.ts diff --git a/.env.example b/.env.example index d81f0fc..1d4d139 100644 --- a/.env.example +++ b/.env.example @@ -8,6 +8,9 @@ DATABASE_PASSWORD=postgres WRITE_DATABASE_NAME=master-db READ_DATABASE_NAME=slave-db +WRITE_CONNECTION_NAME= +READ_CONNECTION_NAME= + TYPEORM_ENTITIES=/**/core/entities/**.entity{.ts,.js} TYPEORM_MIGRATIONS=/database/migrations/*{.ts,.js} TYPEORM_MIGRATIONS_DIR=src/database/migrations @@ -15,6 +18,8 @@ TYPEORM_LOGGING=true TYPEORM_SYNCHRONIZE=false TYPEORM_MIGRATION_RUN=false +JWT_SECRET_KEY=jwt-secret-key + DROPBOX_TOKEN= DROPBOX_KEY= DROPBOX_SECRET= diff --git a/src/article/application/commands/command.module.ts b/src/article/application/commands/command.module.ts index d44a803..6769986 100644 --- a/src/article/application/commands/command.module.ts +++ b/src/article/application/commands/command.module.ts @@ -3,7 +3,7 @@ import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; import { CommandHandlers } from "."; -import { WRITE_CONNECTION } from "../../../config"; +import { WRITE_CONNECTION } from "../../../configs"; import { FollowsEntity } from "../../../profile/core/entities/follows.entity"; import { RabbitMqModule } from "../../../rabbitmq/rabbitmq.module"; import { UserEntity } from "../../../user/core"; diff --git a/src/article/application/commands/handlers/create-article.handler.ts b/src/article/application/commands/handlers/create-article.handler.ts index 143c670..8aea40c 100644 --- a/src/article/application/commands/handlers/create-article.handler.ts +++ b/src/article/application/commands/handlers/create-article.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { ArticleEntity } from "../../../core/entities/article.entity"; diff --git a/src/article/application/commands/handlers/create-comment.handler.ts b/src/article/application/commands/handlers/create-comment.handler.ts index 6668d22..4088c5c 100644 --- a/src/article/application/commands/handlers/create-comment.handler.ts +++ b/src/article/application/commands/handlers/create-comment.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { UserEntity } from "../../../../user/core/entities/user.entity"; diff --git a/src/article/application/commands/handlers/delete-article.handler.ts b/src/article/application/commands/handlers/delete-article.handler.ts index 175a5ed..cb9dde9 100644 --- a/src/article/application/commands/handlers/delete-article.handler.ts +++ b/src/article/application/commands/handlers/delete-article.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { DeleteResult, Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { diff --git a/src/article/application/commands/handlers/delete-comment.handler.ts b/src/article/application/commands/handlers/delete-comment.handler.ts index d8d1144..be4a8ef 100644 --- a/src/article/application/commands/handlers/delete-comment.handler.ts +++ b/src/article/application/commands/handlers/delete-comment.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { ArticleEntity } from "../../../core/entities/article.entity"; diff --git a/src/article/application/commands/handlers/favorite-article.handler.ts b/src/article/application/commands/handlers/favorite-article.handler.ts index 763225f..cf632d6 100644 --- a/src/article/application/commands/handlers/favorite-article.handler.ts +++ b/src/article/application/commands/handlers/favorite-article.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { UserEntity } from "../../../../user/core/entities/user.entity"; diff --git a/src/article/application/commands/handlers/unfavorite-article.handler.ts b/src/article/application/commands/handlers/unfavorite-article.handler.ts index 982b083..53e1e57 100644 --- a/src/article/application/commands/handlers/unfavorite-article.handler.ts +++ b/src/article/application/commands/handlers/unfavorite-article.handler.ts @@ -1,7 +1,7 @@ import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { UserEntity } from "../../../../user/core/entities/user.entity"; diff --git a/src/article/application/commands/handlers/update-article.handler.ts b/src/article/application/commands/handlers/update-article.handler.ts index ef751e3..07a10bd 100644 --- a/src/article/application/commands/handlers/update-article.handler.ts +++ b/src/article/application/commands/handlers/update-article.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { ArticleEntity } from "../../../core/entities/article.entity"; diff --git a/src/article/application/events/event.module.ts b/src/article/application/events/event.module.ts index 1036669..1f277e2 100644 --- a/src/article/application/events/event.module.ts +++ b/src/article/application/events/event.module.ts @@ -1,7 +1,7 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; -import { READ_CONNECTION } from "../../../config"; +import { READ_CONNECTION } from "../../../configs"; import { UserEntity } from "../../../user/core/entities/user.entity"; import { ArticleEntity, BlockEntity } from "../../core"; import { CommentEntity } from "../../core/entities/comment.entity"; diff --git a/src/article/application/events/handlers/article-created.handler.ts b/src/article/application/events/handlers/article-created.handler.ts index 24670f0..629e7be 100644 --- a/src/article/application/events/handlers/article-created.handler.ts +++ b/src/article/application/events/handlers/article-created.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { ArticleEntity } from "../../../core/entities/article.entity"; import { ArticleCreatedEvent } from "../impl"; diff --git a/src/article/application/events/handlers/article-deleted.handler.ts b/src/article/application/events/handlers/article-deleted.handler.ts index 3d627cd..6acf6f2 100644 --- a/src/article/application/events/handlers/article-deleted.handler.ts +++ b/src/article/application/events/handlers/article-deleted.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { ArticleDeletedEvent } from "../impl"; import { CommentEntity, ArticleEntity, BlockEntity } from "../../../core"; diff --git a/src/article/application/events/handlers/article-favorited.handler.ts b/src/article/application/events/handlers/article-favorited.handler.ts index 1d274b7..ea98ec2 100644 --- a/src/article/application/events/handlers/article-favorited.handler.ts +++ b/src/article/application/events/handlers/article-favorited.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { UserEntity } from "../../../../user/core/entities/user.entity"; import { ArticleEntity } from "../../../core/entities/article.entity"; import { ArticleFavoritedEvent } from "../impl"; diff --git a/src/article/application/events/handlers/article-unfavorited.handler.ts b/src/article/application/events/handlers/article-unfavorited.handler.ts index 87f64e2..cc00f71 100644 --- a/src/article/application/events/handlers/article-unfavorited.handler.ts +++ b/src/article/application/events/handlers/article-unfavorited.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { UserEntity } from "../../../../user/core/entities/user.entity"; import { ArticleEntity } from "../../../core/entities/article.entity"; import { ArticleUnFavoritedEvent } from "../impl"; diff --git a/src/article/application/events/handlers/article-updated.handler.ts b/src/article/application/events/handlers/article-updated.handler.ts index b5617f6..7b44358 100644 --- a/src/article/application/events/handlers/article-updated.handler.ts +++ b/src/article/application/events/handlers/article-updated.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { ArticleEntity } from "../../../core/entities/article.entity"; import { ArticleUpdatedEvent } from "../impl"; diff --git a/src/article/application/events/handlers/comment-created.handler.ts b/src/article/application/events/handlers/comment-created.handler.ts index c7dc949..bf99a04 100644 --- a/src/article/application/events/handlers/comment-created.handler.ts +++ b/src/article/application/events/handlers/comment-created.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { CommentEntity } from "../../../core/entities/comment.entity"; import { CommentCreatedEvent } from "../impl"; diff --git a/src/article/application/events/handlers/comment-deleted.handler.ts b/src/article/application/events/handlers/comment-deleted.handler.ts index 284d2c5..0d82464 100644 --- a/src/article/application/events/handlers/comment-deleted.handler.ts +++ b/src/article/application/events/handlers/comment-deleted.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { CommentEntity } from "../../../core/entities/comment.entity"; import { CommentDeletedEvent } from "../impl"; diff --git a/src/article/application/queries/handlers/find-all.article.handler.ts b/src/article/application/queries/handlers/find-all.article.handler.ts index 7f24028..fd58228 100644 --- a/src/article/application/queries/handlers/find-all.article.handler.ts +++ b/src/article/application/queries/handlers/find-all.article.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { getRepository, Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { FollowsEntity } from "../../../../profile/core/entities/follows.entity"; import { UserEntity } from "../../../../user/core/entities/user.entity"; import { ArticleEntity } from "../../../core/entities/article.entity"; diff --git a/src/article/application/queries/handlers/find-comments.handler.ts b/src/article/application/queries/handlers/find-comments.handler.ts index 57e61c9..bba788e 100644 --- a/src/article/application/queries/handlers/find-comments.handler.ts +++ b/src/article/application/queries/handlers/find-comments.handler.ts @@ -1,7 +1,7 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { ArticleEntity } from "../../../core/entities/article.entity"; import { CommentsRO } from "../../../core/interfaces/article.interface"; import { ArticleService } from "../../services/article.service"; diff --git a/src/article/application/queries/handlers/find-feed-article.handler.ts b/src/article/application/queries/handlers/find-feed-article.handler.ts index 280b322..38f03e0 100644 --- a/src/article/application/queries/handlers/find-feed-article.handler.ts +++ b/src/article/application/queries/handlers/find-feed-article.handler.ts @@ -1,7 +1,7 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { getRepository, Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { FollowsEntity } from "../../../../profile/core/entities/follows.entity"; import { UserEntity } from "../../../../user/core/entities/user.entity"; import { ArticleEntity } from "../../../core/entities/article.entity"; diff --git a/src/article/application/queries/handlers/find-one-article.handler.ts b/src/article/application/queries/handlers/find-one-article.handler.ts index 71ea1c5..2c9dd0b 100644 --- a/src/article/application/queries/handlers/find-one-article.handler.ts +++ b/src/article/application/queries/handlers/find-one-article.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { FollowsEntity } from "../../../../profile/core/entities/follows.entity"; import { UserEntity } from "../../../../user/core/entities/user.entity"; import { ArticleEntity } from "../../../core/entities/article.entity"; diff --git a/src/article/application/queries/query.module.ts b/src/article/application/queries/query.module.ts index cfcf178..dc8edf5 100644 --- a/src/article/application/queries/query.module.ts +++ b/src/article/application/queries/query.module.ts @@ -3,7 +3,7 @@ import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; import { QueryHandlers } from "."; -import { READ_CONNECTION } from "../../../config"; +import { READ_CONNECTION } from "../../../configs"; import { FollowsEntity } from "../../../profile/core/entities/follows.entity"; import { UserEntity } from "../../../user/core/entities/user.entity"; import { UserModule } from "../../../user/user.module"; diff --git a/src/config.ts b/src/config.ts deleted file mode 100644 index a1d66e8..0000000 --- a/src/config.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const SECRET = "jwt-secret-key"; - -export const WRITE_CONNECTION = "master-db"; -export const READ_CONNECTION = "slave-db"; diff --git a/src/configs/index.ts b/src/configs/index.ts new file mode 100644 index 0000000..155f5b3 --- /dev/null +++ b/src/configs/index.ts @@ -0,0 +1,4 @@ +export const JWT_SECRET_KEY = process.env.JWT_SECRET_KEY; + +export const WRITE_CONNECTION = process.env.WRITE_CONNECTION; +export const READ_CONNECTION = process.env.READ_CONNECTION; diff --git a/src/database/database.module.ts b/src/database/database.module.ts index bfca8bf..a4d5393 100644 --- a/src/database/database.module.ts +++ b/src/database/database.module.ts @@ -2,7 +2,7 @@ import { Module } from "@nestjs/common"; import { TypeOrmModule } from "@nestjs/typeorm"; import * as dotenv from "dotenv"; -import { READ_CONNECTION, WRITE_CONNECTION } from "../config"; +import { READ_CONNECTION, WRITE_CONNECTION } from "../configs"; import { join } from "path"; dotenv.config(); diff --git a/src/profile/application/commands/command.module.ts b/src/profile/application/commands/command.module.ts index 4657a63..591079b 100644 --- a/src/profile/application/commands/command.module.ts +++ b/src/profile/application/commands/command.module.ts @@ -3,7 +3,7 @@ import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; import { CommandHandlers } from "."; -import { WRITE_CONNECTION } from "../../../config"; +import { WRITE_CONNECTION } from "../../../configs"; import { RabbitMqModule } from "../../../rabbitmq/rabbitmq.module"; import { UserEntity } from "../../../user/core/entities/user.entity"; import { UserModule } from "../../../user/user.module"; diff --git a/src/profile/application/commands/handlers/follow-profile.handler.ts b/src/profile/application/commands/handlers/follow-profile.handler.ts index c23ab97..c3f9fb2 100644 --- a/src/profile/application/commands/handlers/follow-profile.handler.ts +++ b/src/profile/application/commands/handlers/follow-profile.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { PROFILE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { UserEntity } from "../../../../user/core/entities/user.entity"; diff --git a/src/profile/application/commands/handlers/unfollow-profile.handler.ts b/src/profile/application/commands/handlers/unfollow-profile.handler.ts index e7651f7..9e549d0 100644 --- a/src/profile/application/commands/handlers/unfollow-profile.handler.ts +++ b/src/profile/application/commands/handlers/unfollow-profile.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { PROFILE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { UserEntity } from "../../../../user/core/entities/user.entity"; diff --git a/src/profile/application/events/event.module.ts b/src/profile/application/events/event.module.ts index 184b000..49a7161 100644 --- a/src/profile/application/events/event.module.ts +++ b/src/profile/application/events/event.module.ts @@ -1,7 +1,7 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; -import { READ_CONNECTION } from "../../../config"; +import { READ_CONNECTION } from "../../../configs"; import { EventHandlers } from "."; import { FollowsEntity } from "../../core/entities/follows.entity"; diff --git a/src/profile/application/events/handlers/profile-followed.handler.ts b/src/profile/application/events/handlers/profile-followed.handler.ts index 691ba64..58a2724 100644 --- a/src/profile/application/events/handlers/profile-followed.handler.ts +++ b/src/profile/application/events/handlers/profile-followed.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { FollowsEntity } from "../../../core/entities/follows.entity"; import { ProfileFollowedEvent } from "../impl"; diff --git a/src/profile/application/events/handlers/profile-unfollowed.handler.ts b/src/profile/application/events/handlers/profile-unfollowed.handler.ts index d6684af..a53426f 100644 --- a/src/profile/application/events/handlers/profile-unfollowed.handler.ts +++ b/src/profile/application/events/handlers/profile-unfollowed.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { FollowsEntity } from "../../../core/entities/follows.entity"; import { ProfileUnFollowedEvent } from "../impl"; diff --git a/src/profile/application/queries/handlers/find-profile.handler.ts b/src/profile/application/queries/handlers/find-profile.handler.ts index d29670a..9256390 100644 --- a/src/profile/application/queries/handlers/find-profile.handler.ts +++ b/src/profile/application/queries/handlers/find-profile.handler.ts @@ -1,7 +1,7 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { UserEntity } from "../../../../user/core/entities/user.entity"; import { FollowsEntity } from "../../../core/entities/follows.entity"; import { diff --git a/src/profile/application/queries/query.module.ts b/src/profile/application/queries/query.module.ts index 193a546..b40f8dc 100644 --- a/src/profile/application/queries/query.module.ts +++ b/src/profile/application/queries/query.module.ts @@ -3,7 +3,7 @@ import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; import { QueryHandlers } from "."; -import { READ_CONNECTION } from "../../../config"; +import { READ_CONNECTION } from "../../../configs"; import { UserEntity } from "../../../user/core/entities/user.entity"; import { UserModule } from "../../../user/user.module"; import { FollowsEntity } from "../../core/entities/follows.entity"; diff --git a/src/shared/base.controller.ts b/src/shared/base.controller.ts index ca48827..c8db17d 100644 --- a/src/shared/base.controller.ts +++ b/src/shared/base.controller.ts @@ -1,15 +1,14 @@ -import { SECRET } from '../config'; -import * as jwt from 'jsonwebtoken'; +import * as jwt from "jsonwebtoken"; +import { JWT_SECRET_KEY } from "../configs"; export class BaseController { - constructor() {} protected getUserIdFromToken(authorization) { if (!authorization) return null; - const token = authorization.split(' ')[1]; - const decoded: any = jwt.verify(token, SECRET); + const token = authorization.split(" ")[1]; + const decoded: any = jwt.verify(token, JWT_SECRET_KEY); return decoded.id; } -} \ No newline at end of file +} diff --git a/src/shared/middleware/auth.middleware.ts b/src/shared/middleware/auth.middleware.ts index c99ec7c..3c7a125 100644 --- a/src/shared/middleware/auth.middleware.ts +++ b/src/shared/middleware/auth.middleware.ts @@ -4,10 +4,11 @@ import { QueryBus } from "@nestjs/cqrs"; import { NextFunction, Request, Response } from "express"; import { IncomingHttpHeaders } from "http"; import * as jwt from "jsonwebtoken"; -import { SECRET } from "../../config"; + +import { JWT_SECRET_KEY } from "../../configs"; +import { RedisService } from "../../redis/redis.service"; import { FindUserById } from "../../user/application/queries"; import { UserData } from "../../user/core/interfaces/user.interface"; -import { RedisService } from "../../redis/redis.service"; interface IRequestCustom extends Request { user: UserData; @@ -25,7 +26,7 @@ export class AuthMiddleware implements NestMiddleware { const authHeaders = req.headers.authorization; if (authHeaders && (authHeaders as string).split(" ")[1]) { const token = (authHeaders as string).split(" ")[1]; - const decoded: any = jwt.verify(token, SECRET); + const decoded: any = jwt.verify(token, JWT_SECRET_KEY); const _user = await this.redisCacheService.get(decoded.id); if (_user) { diff --git a/src/shared/middleware/user.decorator.ts b/src/shared/middleware/user.decorator.ts index f6748e4..b27c03b 100644 --- a/src/shared/middleware/user.decorator.ts +++ b/src/shared/middleware/user.decorator.ts @@ -1,6 +1,7 @@ import { createParamDecorator, ExecutionContext } from "@nestjs/common"; -import { SECRET } from "../../config"; import * as jwt from "jsonwebtoken"; + +import { JWT_SECRET_KEY } from "../../configs"; import { CurrentUser } from "../../user/core/interfaces/user.interface"; export const User = createParamDecorator((data: any, ctx: ExecutionContext) => { @@ -15,7 +16,7 @@ export const User = createParamDecorator((data: any, ctx: ExecutionContext) => { ? (req.headers.authorization as string).split(" ") : null; if (token && token[1]) { - const decoded: CurrentUser = jwt.verify(token[1], SECRET); + const decoded: CurrentUser = jwt.verify(token[1], JWT_SECRET_KEY); return !!data ? decoded[data] : decoded; } }); diff --git a/src/tag/tag.module.ts b/src/tag/tag.module.ts index cc0389d..9a0e810 100644 --- a/src/tag/tag.module.ts +++ b/src/tag/tag.module.ts @@ -1,6 +1,6 @@ import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common"; import { TypeOrmModule } from "@nestjs/typeorm"; -import { READ_CONNECTION } from "../config"; +import { READ_CONNECTION } from "../configs"; import { UserModule } from "../user/user.module"; import { TagController } from "./tag.controller"; import { TagEntity } from "./core/entities/tag.entity"; diff --git a/src/tag/tag.service.ts b/src/tag/tag.service.ts index 9d68902..b4d4f7f 100644 --- a/src/tag/tag.service.ts +++ b/src/tag/tag.service.ts @@ -1,7 +1,7 @@ import { Injectable } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../config"; +import { READ_CONNECTION } from "../configs"; import { TagEntity } from "./core/entities/tag.entity"; import { TagRO } from "./core/interfaces/tag.interface"; diff --git a/src/user/application/commands/command.module.ts b/src/user/application/commands/command.module.ts index c35a950..9397f6b 100644 --- a/src/user/application/commands/command.module.ts +++ b/src/user/application/commands/command.module.ts @@ -3,7 +3,7 @@ import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; import { CommandHandlers } from "."; -import { WRITE_CONNECTION } from "../../../config"; +import { WRITE_CONNECTION } from "../../../configs"; import { RabbitMqModule } from "../../../rabbitmq/rabbitmq.module"; import { UserEntity } from "../../core"; import { UserService } from "../services/user.service"; diff --git a/src/user/application/commands/handlers/create-user.handler.ts b/src/user/application/commands/handlers/create-user.handler.ts index 338a5d6..5798bc3 100644 --- a/src/user/application/commands/handlers/create-user.handler.ts +++ b/src/user/application/commands/handlers/create-user.handler.ts @@ -3,7 +3,7 @@ import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { validate } from "class-validator"; import { getRepository, Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { USER_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { UserEntity } from "../../../core/entities/user.entity"; diff --git a/src/user/application/commands/handlers/update-user.handler.ts b/src/user/application/commands/handlers/update-user.handler.ts index a0be96e..94665d3 100644 --- a/src/user/application/commands/handlers/update-user.handler.ts +++ b/src/user/application/commands/handlers/update-user.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { CommandHandler, ICommandHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { WRITE_CONNECTION } from "../../../../config"; +import { WRITE_CONNECTION } from "../../../../configs"; import { PublisherService } from "../../../../rabbitmq/publisher.service"; import { USER_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; import { UserEntity } from "../../../core/entities/user.entity"; diff --git a/src/user/application/events/event.module.ts b/src/user/application/events/event.module.ts index 4b9c93c..13161e9 100644 --- a/src/user/application/events/event.module.ts +++ b/src/user/application/events/event.module.ts @@ -1,7 +1,7 @@ import { Module } from "@nestjs/common"; import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; -import { READ_CONNECTION } from "../../../config"; +import { READ_CONNECTION } from "../../../configs"; import { UserEntity } from "../../core"; import { EventHandlers } from "."; diff --git a/src/user/application/events/handlers/user-created.handler.ts b/src/user/application/events/handlers/user-created.handler.ts index fb2aaff..f7e39a9 100644 --- a/src/user/application/events/handlers/user-created.handler.ts +++ b/src/user/application/events/handlers/user-created.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { UserEntity } from "../../../core/entities/user.entity"; import { UserCreatedEvent } from "../impl"; diff --git a/src/user/application/events/handlers/user-updated.handler.ts b/src/user/application/events/handlers/user-updated.handler.ts index 045554f..d1a8a00 100644 --- a/src/user/application/events/handlers/user-updated.handler.ts +++ b/src/user/application/events/handlers/user-updated.handler.ts @@ -3,7 +3,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { UserEntity } from "../../../core/entities/user.entity"; import { UserUpdatedEvent } from "../impl"; diff --git a/src/user/application/queries/handlers/find-user-by-email.handler.ts b/src/user/application/queries/handlers/find-user-by-email.handler.ts index e86d755..d33e4d3 100644 --- a/src/user/application/queries/handlers/find-user-by-email.handler.ts +++ b/src/user/application/queries/handlers/find-user-by-email.handler.ts @@ -1,7 +1,7 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { RedisService } from "../../../../redis/redis.service"; import { UserEntity } from "../../../core/entities/user.entity"; import { UserRO } from "../../../core/interfaces/user.interface"; diff --git a/src/user/application/queries/handlers/find-user-by-id.handler.ts b/src/user/application/queries/handlers/find-user-by-id.handler.ts index 0295e4d..67258ae 100644 --- a/src/user/application/queries/handlers/find-user-by-id.handler.ts +++ b/src/user/application/queries/handlers/find-user-by-id.handler.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from "@nestjs/common"; import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { RedisService } from "../../../../redis/redis.service"; import { UserEntity } from "../../../core/entities/user.entity"; import { UserRO } from "../../../core/interfaces/user.interface"; diff --git a/src/user/application/queries/handlers/login.handler.ts b/src/user/application/queries/handlers/login.handler.ts index dfd0ed2..d12061d 100644 --- a/src/user/application/queries/handlers/login.handler.ts +++ b/src/user/application/queries/handlers/login.handler.ts @@ -3,7 +3,7 @@ import { QueryHandler, IQueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; import * as argon2 from "argon2"; -import { READ_CONNECTION } from "../../../../config"; +import { READ_CONNECTION } from "../../../../configs"; import { LoginUserDto } from "../../../core/dto"; import { UserEntity } from "../../../core/entities/user.entity"; import { UserRO } from "../../../core/interfaces/user.interface"; diff --git a/src/user/application/queries/query.module.ts b/src/user/application/queries/query.module.ts index de4cee7..5dcdd40 100644 --- a/src/user/application/queries/query.module.ts +++ b/src/user/application/queries/query.module.ts @@ -3,7 +3,7 @@ import { CqrsModule } from "@nestjs/cqrs"; import { TypeOrmModule } from "@nestjs/typeorm"; import { QueryHandlers } from "."; -import { READ_CONNECTION } from "../../../config"; +import { READ_CONNECTION } from "../../../configs"; import { UserEntity } from "../../core"; import { UserService } from "../services/user.service"; import { RedisModule } from "../../../redis/redis.module"; diff --git a/src/user/application/services/user.service.ts b/src/user/application/services/user.service.ts index 435e638..1a60a33 100644 --- a/src/user/application/services/user.service.ts +++ b/src/user/application/services/user.service.ts @@ -1,8 +1,9 @@ import { Injectable } from "@nestjs/common"; -import { SECRET } from "../../../config"; -import { UserEntity } from "../../core/entities/user.entity"; const jwt = require("jsonwebtoken"); +import { JWT_SECRET_KEY } from "../../../configs"; +import { UserEntity } from "../../core/entities/user.entity"; + @Injectable() export class UserService { constructor() {} @@ -19,7 +20,7 @@ export class UserService { email: user.email, exp: exp.getTime() / 1000, }, - SECRET + JWT_SECRET_KEY ); } From 4b0db1855ddac929e4e11a2300a80f68a9d07b5d Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Sun, 15 Oct 2023 09:42:22 +0700 Subject: [PATCH 16/19] update: enhance folder structure --- .../{ => projections}/article.projection.ts | 10 +++++----- src/article/application/projections/index.ts | 1 + src/article/article.module.ts | 2 +- src/main.ts | 7 +++---- src/profile/application/projections/index.ts | 1 + .../{ => projections}/profile.projection.ts | 12 ++++++------ src/profile/profile.module.ts | 2 +- src/user/application/projections/index.ts | 1 + .../application/{ => projections}/user.projection.ts | 11 ++++++----- src/user/user.module.ts | 2 +- 10 files changed, 26 insertions(+), 23 deletions(-) rename src/article/application/{ => projections}/article.projection.ts (86%) create mode 100644 src/article/application/projections/index.ts create mode 100644 src/profile/application/projections/index.ts rename src/profile/application/{ => projections}/profile.projection.ts (67%) create mode 100644 src/user/application/projections/index.ts rename src/user/application/{ => projections}/user.projection.ts (71%) diff --git a/src/article/application/article.projection.ts b/src/article/application/projections/article.projection.ts similarity index 86% rename from src/article/application/article.projection.ts rename to src/article/application/projections/article.projection.ts index e9d7f97..4d6f09b 100644 --- a/src/article/application/article.projection.ts +++ b/src/article/application/projections/article.projection.ts @@ -1,10 +1,10 @@ import { Injectable } from "@nestjs/common"; import { EventBus } from "@nestjs/cqrs"; -import { ConsumerService } from "../../rabbitmq/consumer.service"; -import { ARTICLE_QUEUE } from "../../rabbitmq/rabbitmq.constants"; -import { IMessage, IProjection } from "../core"; -import { MessageType } from "../core/enums/article.enum"; +import { ConsumerService } from "../../../rabbitmq/consumer.service"; +import { ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; +import { IMessage, IProjection } from "../../core"; +import { MessageType } from "../../core/enums/article.enum"; import { ArticleCreatedEvent, ArticleDeletedEvent, @@ -13,7 +13,7 @@ import { ArticleUpdatedEvent, CommentCreatedEvent, CommentDeletedEvent, -} from "./events"; +} from "../events"; @Injectable() export class ArticleProjection implements IProjection { diff --git a/src/article/application/projections/index.ts b/src/article/application/projections/index.ts new file mode 100644 index 0000000..7064b22 --- /dev/null +++ b/src/article/application/projections/index.ts @@ -0,0 +1 @@ +export * from "./article.projection"; diff --git a/src/article/article.module.ts b/src/article/article.module.ts index e8888d9..480d75d 100644 --- a/src/article/article.module.ts +++ b/src/article/article.module.ts @@ -10,7 +10,7 @@ import { RabbitMqModule } from "../rabbitmq/rabbitmq.module"; import { RedisModule } from "../redis/redis.module"; import { AuthMiddleware } from "../shared/middleware/auth.middleware"; import { UserModule } from "../user/user.module"; -import { ArticleProjection } from "./application/article.projection"; +import { ArticleProjection } from "./application/projections"; import { CommandModule } from "./application/commands/command.module"; import { EventModule } from "./application/events/event.module"; import { QueryModule } from "./application/queries/query.module"; diff --git a/src/main.ts b/src/main.ts index 31f84ea..1f3a7c1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,10 +6,9 @@ import { json, urlencoded } from "express"; import * as os from "os"; import { ApplicationModule } from "./app.module"; -import { ArticleProjection } from "./article/application/article.projection"; -import { ProfileProjection } from "./profile/application/profile.projection"; -import { UserProjection } from "./user/application/user.projection"; -import { ElasticSearchArticleProjection } from "./article/elastic-search-article.projection"; +import { ArticleProjection } from "./article/application/projections"; +import { ProfileProjection } from "./profile/application/projections"; +import { UserProjection } from "./user/application/projections"; async function executeProjection(app: INestApplication) { const articleProjection = app.get(ArticleProjection); diff --git a/src/profile/application/projections/index.ts b/src/profile/application/projections/index.ts new file mode 100644 index 0000000..7513782 --- /dev/null +++ b/src/profile/application/projections/index.ts @@ -0,0 +1 @@ +export * from "./profile.projection"; diff --git a/src/profile/application/profile.projection.ts b/src/profile/application/projections/profile.projection.ts similarity index 67% rename from src/profile/application/profile.projection.ts rename to src/profile/application/projections/profile.projection.ts index 7144494..ee65d9d 100644 --- a/src/profile/application/profile.projection.ts +++ b/src/profile/application/projections/profile.projection.ts @@ -1,12 +1,12 @@ import { Injectable } from "@nestjs/common"; import { EventBus } from "@nestjs/cqrs"; -import { ConsumerService } from "../../rabbitmq/consumer.service"; -import { PROFILE_QUEUE } from "../../rabbitmq/rabbitmq.constants"; -import { IMessage, IProjection } from "../core"; -import { FollowsEntity } from "../core/entities/follows.entity"; -import { MessageType } from "../core/enums/profile.enum"; -import { ProfileFollowedEvent, ProfileUnFollowedEvent } from "./events"; +import { ConsumerService } from "../../../rabbitmq/consumer.service"; +import { PROFILE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; +import { IMessage, IProjection } from "../../core"; +import { FollowsEntity } from "../../core/entities/follows.entity"; +import { MessageType } from "../../core/enums/profile.enum"; +import { ProfileFollowedEvent, ProfileUnFollowedEvent } from "../events"; @Injectable() export class ProfileProjection implements IProjection { diff --git a/src/profile/profile.module.ts b/src/profile/profile.module.ts index 6ff68c2..dc42240 100644 --- a/src/profile/profile.module.ts +++ b/src/profile/profile.module.ts @@ -11,7 +11,7 @@ import { UserModule } from "../user/user.module"; import { CommandModule } from "./application/commands/command.module"; import { EventModule } from "./application/events/event.module"; import { ProfileController } from "./presentation/profile.controller"; -import { ProfileProjection } from "./application/profile.projection"; +import { ProfileProjection } from "./application/projections"; import { ProfileService } from "./application/services/profile.service"; import { QueryModule } from "./application/queries/query.module"; import { RedisModule } from "../redis/redis.module"; diff --git a/src/user/application/projections/index.ts b/src/user/application/projections/index.ts new file mode 100644 index 0000000..c7d370d --- /dev/null +++ b/src/user/application/projections/index.ts @@ -0,0 +1 @@ +export * from "./user.projection"; diff --git a/src/user/application/user.projection.ts b/src/user/application/projections/user.projection.ts similarity index 71% rename from src/user/application/user.projection.ts rename to src/user/application/projections/user.projection.ts index 801744c..8bb599f 100644 --- a/src/user/application/user.projection.ts +++ b/src/user/application/projections/user.projection.ts @@ -1,10 +1,11 @@ import { Injectable } from "@nestjs/common"; import { EventBus } from "@nestjs/cqrs"; -import { ConsumerService } from "../../rabbitmq/consumer.service"; -import { USER_QUEUE } from "../../rabbitmq/rabbitmq.constants"; -import { IMessage, IProjection } from "../core"; -import { MessageType } from "../core/enums/user.enum"; -import { UserCreatedEvent, UserUpdatedEvent } from "./events"; + +import { ConsumerService } from "../../../rabbitmq/consumer.service"; +import { USER_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; +import { IMessage, IProjection } from "../../core"; +import { MessageType } from "../../core/enums/user.enum"; +import { UserCreatedEvent, UserUpdatedEvent } from "../events"; @Injectable() export class UserProjection implements IProjection { diff --git a/src/user/user.module.ts b/src/user/user.module.ts index 3de6eac..8bd313f 100644 --- a/src/user/user.module.ts +++ b/src/user/user.module.ts @@ -13,7 +13,7 @@ import { CommandModule } from "./application/commands/command.module"; import { EventModule } from "./application/events/event.module"; import { QueryModule } from "./application/queries/query.module"; import { UserService } from "./application/services/user.service"; -import { UserProjection } from "./application/user.projection"; +import { UserProjection } from "./application/projections"; import { UserController } from "./presentation/user.controller"; @Module({ From 2213ee8a46641716bab83e8bdc1e2a6f4e073676 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Fri, 13 Oct 2023 15:14:29 +0700 Subject: [PATCH 17/19] bug: wrong import file path --- src/main.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.ts b/src/main.ts index 1f3a7c1..31f84ea 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,9 +6,10 @@ import { json, urlencoded } from "express"; import * as os from "os"; import { ApplicationModule } from "./app.module"; -import { ArticleProjection } from "./article/application/projections"; -import { ProfileProjection } from "./profile/application/projections"; -import { UserProjection } from "./user/application/projections"; +import { ArticleProjection } from "./article/application/article.projection"; +import { ProfileProjection } from "./profile/application/profile.projection"; +import { UserProjection } from "./user/application/user.projection"; +import { ElasticSearchArticleProjection } from "./article/elastic-search-article.projection"; async function executeProjection(app: INestApplication) { const articleProjection = app.get(ArticleProjection); From ca111b2b744a90c32382893bda27d96a0661d96c Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Sun, 15 Oct 2023 12:39:02 +0700 Subject: [PATCH 18/19] WIP --- .../events/handlers/indexing-article.handler.ts | 5 ++--- .../projections}/elastic-search-article.projection.ts | 10 +++++----- src/article/application/projections/index.ts | 1 + .../queries/handlers/indexing-article.handler.ts | 10 ++++------ .../queries/handlers/search-article.handler.ts | 2 +- .../application/queries/impl/search-article.query.ts | 2 +- src/article/application/queries/query.module.ts | 4 ++-- src/article/article.module.ts | 2 +- src/main.ts | 10 ++++++---- 9 files changed, 23 insertions(+), 23 deletions(-) rename src/article/{ => application/projections}/elastic-search-article.projection.ts (68%) diff --git a/src/article/application/events/handlers/indexing-article.handler.ts b/src/article/application/events/handlers/indexing-article.handler.ts index c36a92c..8130a74 100644 --- a/src/article/application/events/handlers/indexing-article.handler.ts +++ b/src/article/application/events/handlers/indexing-article.handler.ts @@ -1,8 +1,7 @@ import { IEventHandler } from "@nestjs/cqrs"; import { EventsHandler } from "@nestjs/cqrs/dist/decorators/events-handler.decorator"; - -import { ArticleEntity } from "../../core/entities/article.entity"; -import { SearchService } from "../../../elastic-search/elastic-search.service"; +import { ArticleEntity } from "../../../core"; +import { SearchService } from "../../../../elastic-search/elastic-search.service"; export class IndexingArticleEvent { constructor(public readonly articles: ArticleEntity[]) {} diff --git a/src/article/elastic-search-article.projection.ts b/src/article/application/projections/elastic-search-article.projection.ts similarity index 68% rename from src/article/elastic-search-article.projection.ts rename to src/article/application/projections/elastic-search-article.projection.ts index 90fdd5d..209f7bb 100644 --- a/src/article/elastic-search-article.projection.ts +++ b/src/article/application/projections/elastic-search-article.projection.ts @@ -1,10 +1,10 @@ import { Injectable } from "@nestjs/common"; import { EventBus } from "@nestjs/cqrs"; -import { ConsumerService } from "../rabbitmq/consumer.service"; -import { ES_ARTICLE_QUEUE } from "../rabbitmq/rabbitmq.constants"; -import { IMessage, IProjection } from "./core"; -import { MessageType } from "./core/enums/article.enum"; -import { IndexingArticleEvent } from "./events"; +import { ConsumerService } from "../../../rabbitmq/consumer.service"; +import { ES_ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; +import { IMessage, IProjection } from "../../core"; +import { MessageType } from "../../core/enums/article.enum"; +import { IndexingArticleEvent } from "../events"; @Injectable() export class ElasticSearchArticleProjection implements IProjection { diff --git a/src/article/application/projections/index.ts b/src/article/application/projections/index.ts index 7064b22..799b525 100644 --- a/src/article/application/projections/index.ts +++ b/src/article/application/projections/index.ts @@ -1 +1,2 @@ export * from "./article.projection"; +export * from "./elastic-search-article.projection"; diff --git a/src/article/application/queries/handlers/indexing-article.handler.ts b/src/article/application/queries/handlers/indexing-article.handler.ts index 806bcbd..9e5c750 100644 --- a/src/article/application/queries/handlers/indexing-article.handler.ts +++ b/src/article/application/queries/handlers/indexing-article.handler.ts @@ -1,12 +1,10 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; - -import { READ_CONNECTION } from "../../../config"; -import { PublisherService } from "../../../rabbitmq/publisher.service"; -import { ArticleEntity } from "../../core/entities/article.entity"; -import { ES_ARTICLE_QUEUE } from "../../../rabbitmq/rabbitmq.constants"; -import { MessageType } from "../../core"; +import { READ_CONNECTION } from "../../../../configs"; +import { PublisherService } from "../../../../rabbitmq/publisher.service"; +import { ES_ARTICLE_QUEUE } from "../../../../rabbitmq/rabbitmq.constants"; +import { ArticleEntity, MessageType } from "../../../core"; export class IndexingArticleQuery { constructor() {} diff --git a/src/article/application/queries/handlers/search-article.handler.ts b/src/article/application/queries/handlers/search-article.handler.ts index ef72266..171cc65 100644 --- a/src/article/application/queries/handlers/search-article.handler.ts +++ b/src/article/application/queries/handlers/search-article.handler.ts @@ -1,8 +1,8 @@ import { IQueryHandler, QueryHandler } from "@nestjs/cqrs"; import { ElasticsearchService } from "@nestjs/elasticsearch"; -import { IArticleSearchResult } from "../../core/interfaces/article.interface"; import { SearchArticleQuery } from "../impl"; +import { IArticleSearchResult } from "../../../core"; @QueryHandler(SearchArticleQuery) export class SearchArticleQueryHandler diff --git a/src/article/application/queries/impl/search-article.query.ts b/src/article/application/queries/impl/search-article.query.ts index 5b11602..d3f60a1 100644 --- a/src/article/application/queries/impl/search-article.query.ts +++ b/src/article/application/queries/impl/search-article.query.ts @@ -1,4 +1,4 @@ -import { SearchArticleDto } from "../../dto"; +import { SearchArticleDto } from "../../../core/dto"; export class SearchArticleQuery { constructor(public readonly query: SearchArticleDto) {} diff --git a/src/article/application/queries/query.module.ts b/src/article/application/queries/query.module.ts index dc8edf5..a7f65c8 100644 --- a/src/article/application/queries/query.module.ts +++ b/src/article/application/queries/query.module.ts @@ -10,8 +10,8 @@ import { UserModule } from "../../../user/user.module"; import { ArticleEntity } from "../../core"; import { CommentEntity } from "../../core/entities/comment.entity"; import { ArticleService } from "../services/article.service"; -import { ElasticSearchModule } from "../../elastic-search/elastic-search.module"; -import { RabbitMqModule } from "../../rabbitmq/rabbitmq.module"; +import { ElasticSearchModule } from "../../../elastic-search/elastic-search.module"; +import { RabbitMqModule } from "../../../rabbitmq/rabbitmq.module"; @Module({ imports: [ diff --git a/src/article/article.module.ts b/src/article/article.module.ts index 480d75d..47b70d7 100644 --- a/src/article/article.module.ts +++ b/src/article/article.module.ts @@ -16,7 +16,7 @@ import { EventModule } from "./application/events/event.module"; import { QueryModule } from "./application/queries/query.module"; import { ArticleService } from "./application/services/article.service"; import { ArticleController } from "./presentation/article.controller"; -import { ElasticSearchArticleProjection } from "./elastic-search-article.projection"; +import { ElasticSearchArticleProjection } from "./application/projections/elastic-search-article.projection"; @Module({ imports: [ diff --git a/src/main.ts b/src/main.ts index 31f84ea..81f7cfb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,10 +6,12 @@ import { json, urlencoded } from "express"; import * as os from "os"; import { ApplicationModule } from "./app.module"; -import { ArticleProjection } from "./article/application/article.projection"; -import { ProfileProjection } from "./profile/application/profile.projection"; -import { UserProjection } from "./user/application/user.projection"; -import { ElasticSearchArticleProjection } from "./article/elastic-search-article.projection"; +import { + ArticleProjection, + ElasticSearchArticleProjection, +} from "./article/application/projections"; +import { UserProjection } from "./user/application/projections"; +import { ProfileProjection } from "./profile/application/projections"; async function executeProjection(app: INestApplication) { const articleProjection = app.get(ArticleProjection); From 21ba07d35ed1bb21fe44a4cc69831f8fd3889c31 Mon Sep 17 00:00:00 2001 From: anhtt2211 Date: Mon, 16 Oct 2023 09:40:14 +0700 Subject: [PATCH 19/19] chore: sync from master --- docker-compose.yaml | 33 +++++++++++++++++++++++++-------- src/redis/redis.module.ts | 6 ++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index d4722f7..70eb528 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -14,10 +14,10 @@ services: - rabbitmq - redis env_file: - - .env - environment: - - NODE_ENV=staging - - DATABASE_HOST=host.docker.internal + - .env.docker + networks: + - social-network + social-api-2: build: context: . @@ -31,10 +31,9 @@ services: - rabbitmq - redis env_file: - - .env - environment: - - NODE_ENV=staging - - DATABASE_HOST=host.docker.internal + - .env.docker + networks: + - social-network db: container_name: social-postgres @@ -46,17 +45,26 @@ services: - /data/postgres/ ports: - 5432:5432 + networks: + - social-network + rabbitmq: container_name: social-rabbitmq image: rabbitmq:3-management ports: - "15672:15672" - "5672:5672" + networks: + - social-network + redis: container_name: social-redis image: "redis:alpine" ports: - "6379:6379" + networks: + - social-network + nginx: container_name: social-nginx build: ./nginx @@ -65,6 +73,9 @@ services: depends_on: - social-api-1 - social-api-2 + networks: + - social-network + elasticsearch: container_name: social-es image: docker.elastic.co/elasticsearch/elasticsearch:7.11.0 @@ -83,3 +94,9 @@ services: - 9200:9200 volumes: - /data/elasticsearch/ + networks: + - social-network + +networks: + social-network: + driver: bridge diff --git a/src/redis/redis.module.ts b/src/redis/redis.module.ts index e00a096..44d5c13 100644 --- a/src/redis/redis.module.ts +++ b/src/redis/redis.module.ts @@ -7,6 +7,12 @@ import { RedisService } from "./redis.service"; { provide: "REDIS_CLIENT", useFactory: () => { + if (process.env.NODE_ENV !== "development") { + return new Redis({ + host: process.env.REDIS_HOST, + port: Number(process.env.REDIS_PORT), + }); + } return new Redis(process.env.REDIS_URL); }, },