From 3e26bae2d3f034a1bc2af510685f236e643abcd8 Mon Sep 17 00:00:00 2001 From: seungo Date: Mon, 22 Jan 2024 00:34:36 +0900 Subject: [PATCH] feat: trade post comment transaction --- .../responses/trade-post-comment.response.ts | 3 ++ .../schemas/trade-post-comment.schema.ts | 3 ++ .../services/trade-post-comment.service.ts | 34 +++++++++++-------- src/trade-posts/trade-post.service.ts | 2 +- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/trade-posts/responses/trade-post-comment.response.ts b/src/trade-posts/responses/trade-post-comment.response.ts index eb67bf7..01265a0 100644 --- a/src/trade-posts/responses/trade-post-comment.response.ts +++ b/src/trade-posts/responses/trade-post-comment.response.ts @@ -15,11 +15,14 @@ export class TradePostCommentResponse extends BaseResponse implements ITradePost @Field((_) => UserResponse, { description: 'The author of the trade post comment' }) author: UserResponse; + postId: string; + constructor(partial: Partial) { super(partial); Object.assign(this, { authorId: partial?.authorId, content: partial?.content, + postId: partial?.postId, }); } } diff --git a/src/trade-posts/schemas/trade-post-comment.schema.ts b/src/trade-posts/schemas/trade-post-comment.schema.ts index 4942037..f28697a 100644 --- a/src/trade-posts/schemas/trade-post-comment.schema.ts +++ b/src/trade-posts/schemas/trade-post-comment.schema.ts @@ -19,6 +19,9 @@ export type TradePostCommentDocument = HydratedDocument; export class TradePostComment { id: string; + @Prop({ required: true, index: true }) + postId: string; + @Prop({ required: true, index: true }) content: string; diff --git a/src/trade-posts/services/trade-post-comment.service.ts b/src/trade-posts/services/trade-post-comment.service.ts index ef3e87e..f742618 100644 --- a/src/trade-posts/services/trade-post-comment.service.ts +++ b/src/trade-posts/services/trade-post-comment.service.ts @@ -1,7 +1,6 @@ import { Injectable, Logger } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model, PaginateModel } from 'mongoose'; -import { TradePostNotFound } from '../exceptions/trade-post.exception'; import { CreateTradePostCommentInput, GetTradePostCommentListInput, @@ -24,7 +23,7 @@ export class TradePostCommentService { const session = await this.tradePostCommentModel.startSession(); const result = await session.withTransaction(async () => { - const comment = await this.tradePostCommentModel.create({ ...input, authorId }); + const comment = await this.tradePostCommentModel.create({ ...input, authorId, postId: tradePostId }); await this.tradePostModel.findByIdAndUpdate(tradePostId, { $push: { comments: comment.id } }); return new TradePostCommentResponse(comment); }); @@ -34,29 +33,34 @@ export class TradePostCommentService { } async getTradePostCommentList({ tradePostId, pagination }: GetTradePostCommentListInput) { - const tradePost = await this.tradePostModel.findById(tradePostId); - - if (!tradePost) { - throw new TradePostNotFound(tradePostId); - } - - const comments = await this.tradePostCommentModel.paginate({ _id: tradePost.comments }, pagination.options); + const paginatedResult = await this.tradePostCommentModel.paginate({ postId: tradePostId }, pagination.options); return new TradePostCommentList({ - ...comments, - docs: comments.docs.map((doc) => new TradePostCommentResponse(doc)), + ...paginatedResult, + docs: paginatedResult.docs.map((doc) => new TradePostCommentResponse(doc)), }); } async deleteTradePostComment(tradePostCommentId: string) { const tradePostComment = await this.getTradePostComment(tradePostCommentId); - await this.tradePostCommentModel.findByIdAndDelete(tradePostCommentId); - return tradePostComment; + if (!tradePostComment) return null; + + const session = await this.tradePostCommentModel.startSession(); + const result = await session.withTransaction(async () => { + await this.tradePostCommentModel.findByIdAndDelete(tradePostCommentId); + await this.tradePostModel.findOneAndUpdate( + { _id: tradePostComment.postId }, + { $pull: { comments: tradePostCommentId } }, + ); + return tradePostComment; + }); + + return result; } - async deleteTradePostComments(tradePostCommentIds: string[] | TradePostComment[]) { + async deleteTradePostComments(tradePostId: string) { try { - await this.tradePostCommentModel.deleteMany({ _id: tradePostCommentIds }); + await this.tradePostCommentModel.deleteMany({ postId: tradePostId }); } catch (err) { this.logger.error('Fail to delete trade post comments', err); } diff --git a/src/trade-posts/trade-post.service.ts b/src/trade-posts/trade-post.service.ts index c34feb3..673caa3 100644 --- a/src/trade-posts/trade-post.service.ts +++ b/src/trade-posts/trade-post.service.ts @@ -112,7 +112,7 @@ export class TradePostService implements ITradePostService { const session = await this.tradePostModel.startSession(); await session.withTransaction(async () => { await this.bookmarkService.deleteBookmarks(tradePostId); - this.tradePostCommentService.deleteTradePostComments(tradePost.comments); + this.tradePostCommentService.deleteTradePostComments(tradePost.id); this.tradePostStorageService.deleteImage(tradePostId); await this.tradePostModel.findByIdAndDelete(tradePostId); });