From 84672d8b5f7e2497f3b68e8db38aafd9154d4750 Mon Sep 17 00:00:00 2001 From: Benjamin Frost Date: Mon, 6 May 2024 23:28:07 +0200 Subject: [PATCH] feat: add post comments --- src/posts/dto/comment-post.dto.ts | 7 +++++++ src/posts/posts.controller.ts | 15 +++++++++++++-- src/posts/posts.module.ts | 3 ++- src/posts/posts.service.ts | 28 +++++++++++++++++++++++++--- 4 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 src/posts/dto/comment-post.dto.ts diff --git a/src/posts/dto/comment-post.dto.ts b/src/posts/dto/comment-post.dto.ts new file mode 100644 index 0000000..ed2b6ea --- /dev/null +++ b/src/posts/dto/comment-post.dto.ts @@ -0,0 +1,7 @@ +import { IsNotEmpty, IsString } from 'class-validator'; + +export class CommentPostDto { + @IsString() + @IsNotEmpty() + text: string; +} diff --git a/src/posts/posts.controller.ts b/src/posts/posts.controller.ts index 8eff6fa..bf63dff 100644 --- a/src/posts/posts.controller.ts +++ b/src/posts/posts.controller.ts @@ -1,6 +1,7 @@ import { Body, Controller, + Delete, FileTypeValidator, Get, Param, @@ -14,6 +15,7 @@ import { randomUUID } from 'crypto'; import { diskStorage } from 'multer'; import { extname } from 'path'; import { User, UserPayload } from 'src/auth/decorators/user.decorator'; +import { CommentPostDto } from './dto/comment-post.dto'; import { CreatePostDto } from './dto/create-post.dto'; import { PostsService } from './posts.service'; @@ -52,13 +54,22 @@ export class PostsController { return this.postsService.findAll(); } - @Post(':id/like') + @Post(':id/likes') like(@User() user: UserPayload, @Param('id') id: string) { return this.postsService.like(+id, user.sub); } - @Post(':id/unlike') + @Delete(':id/likes') unlike(@User() user: UserPayload, @Param('id') id: string) { return this.postsService.unlike(+id, user.sub); } + + @Post(':id/comments') + comment( + @User() user: UserPayload, + @Param('id') id: string, + @Body() commentPostDto: CommentPostDto, + ) { + return this.postsService.comment(+id, user.sub, commentPostDto); + } } diff --git a/src/posts/posts.module.ts b/src/posts/posts.module.ts index 130bbe5..bb60860 100644 --- a/src/posts/posts.module.ts +++ b/src/posts/posts.module.ts @@ -1,12 +1,13 @@ import { MikroOrmModule } from '@mikro-orm/nestjs'; import { Module } from '@nestjs/common'; import { User } from 'src/users/entities/user.entity'; +import { PostComment } from './entities/post-comment.entity'; import { Post } from './entities/post.entity'; import { PostsController } from './posts.controller'; import { PostsService } from './posts.service'; @Module({ - imports: [MikroOrmModule.forFeature([Post, User])], + imports: [MikroOrmModule.forFeature([Post, PostComment, User])], controllers: [PostsController], providers: [PostsService], }) diff --git a/src/posts/posts.service.ts b/src/posts/posts.service.ts index d3e6fd0..4cc6c09 100644 --- a/src/posts/posts.service.ts +++ b/src/posts/posts.service.ts @@ -4,7 +4,9 @@ import { EntityManager } from '@mikro-orm/postgresql'; import { Injectable } from '@nestjs/common'; import { UserPayload } from 'src/auth/decorators/user.decorator'; import { User } from 'src/users/entities/user.entity'; +import { CommentPostDto } from './dto/comment-post.dto'; import { CreatePostDto } from './dto/create-post.dto'; +import { PostComment } from './entities/post-comment.entity'; import { Post } from './entities/post.entity'; @Injectable() @@ -14,6 +16,8 @@ export class PostsService { private readonly postRepository: EntityRepository, @InjectRepository(User) private readonly userRepository: EntityRepository, + @InjectRepository(PostComment) + private readonly postCommentRepository: EntityRepository, private readonly em: EntityManager, ) {} @@ -33,14 +37,14 @@ export class PostsService { findAll() { return this.postRepository.findAll({ - populate: ['author', 'likedBy', 'comments'], + populate: ['author', 'likedBy', 'comments', 'comments.author'], }); } async like(id: number, userId: number) { const post = await this.postRepository.findOneOrFail( { id }, - { populate: ['author', 'likedBy', 'comments'] }, + { populate: ['author', 'likedBy', 'comments', 'comments.author'] }, ); const user = await this.userRepository.findOneOrFail({ id: userId }); @@ -53,7 +57,7 @@ export class PostsService { async unlike(id: number, userId: number) { const post = await this.postRepository.findOneOrFail( { id }, - { populate: ['author', 'likedBy', 'comments'] }, + { populate: ['author', 'likedBy', 'comments', 'comments.author'] }, ); const user = await this.userRepository.findOneOrFail({ id: userId }); @@ -62,4 +66,22 @@ export class PostsService { await this.em.flush(); return post; } + + async comment(id: number, userId: number, comment: CommentPostDto) { + const post = await this.postRepository.findOneOrFail( + { id }, + { populate: ['author', 'likedBy', 'comments', 'comments.author'] }, + ); + const user = await this.userRepository.findOneOrFail({ id: userId }); + + const postComment = this.postCommentRepository.create({ + ...comment, + post, + author: user, + }); + post.comments.add(postComment); + + await this.em.flush(); + return post; + } }