diff --git a/server/apps/api/src/user/dto/add-following.dto.ts b/server/apps/api/src/user/dto/follower.dto.ts similarity index 78% rename from server/apps/api/src/user/dto/add-following.dto.ts rename to server/apps/api/src/user/dto/follower.dto.ts index 69e0cc8b..99ffd33a 100644 --- a/server/apps/api/src/user/dto/add-following.dto.ts +++ b/server/apps/api/src/user/dto/follower.dto.ts @@ -1,6 +1,6 @@ import { IsString } from 'class-validator'; -export class AddFollowingDto { +export class followerDto { @IsString() myId: string; diff --git a/server/apps/api/src/user/user.controller.ts b/server/apps/api/src/user/user.controller.ts index 4792608d..9abcccc5 100644 --- a/server/apps/api/src/user/user.controller.ts +++ b/server/apps/api/src/user/user.controller.ts @@ -1,9 +1,7 @@ -import { Body, Controller, Get, Inject, LoggerService, Param, Post } from '@nestjs/common'; +import {Body, Controller, Delete, Get, Inject, LoggerService, Param, Post} from '@nestjs/common'; import { UserService } from './user.service'; -import { AddFollowingDto } from '@user/dto/add-following.dto'; +import { followerDto } from '@user/dto/follower.dto'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; -import { User } from '@schemas/user.schema'; -import { CreateUserDto } from '@user/dto/create-user.dto'; import { responseForm } from '@utils/responseForm'; @Controller('api/user') @@ -25,7 +23,7 @@ export class UserController { try { const myId = '63734e98384f478a32c3a1cc'; // TODO: Request Header에서 access token으로 현재 사용자 알아내기 - const addFollowingDto: AddFollowingDto = { myId, followId: id }; + const addFollowingDto: followerDto = { myId, followId: id }; await this.userService.addFollowing(addFollowingDto); return responseForm(200, {}); } catch (error) { @@ -34,6 +32,19 @@ export class UserController { } } + @Delete('following/:id') + async unFollowing(@Param('id') id: string) { + try { + const myId = '63734e98384f478a32c3a1cc'; + // TODO: Request Header에서 access token으로 현재 사용자 알아내기 + const unFollowingDto: followerDto = { myId, followId: id }; + await this.userService.unFollowing(unFollowingDto); + return responseForm(200, {}); + } catch (error) { + this.logger.error(JSON.stringify(error.response)); + return error.response; + } + } // @Post() // createUser(@Body() createUserDto: CreateUserDto) { diff --git a/server/apps/api/src/user/user.service.ts b/server/apps/api/src/user/user.service.ts index 78ec1559..428a3061 100644 --- a/server/apps/api/src/user/user.service.ts +++ b/server/apps/api/src/user/user.service.ts @@ -1,6 +1,5 @@ import { BadRequestException, ConflictException, Injectable } from '@nestjs/common'; -import { AddFollowingDto } from '@user/dto/add-following.dto'; -import { CreateUserDto } from '@user/dto/create-user.dto'; +import { followerDto } from '@user/dto/follower.dto'; import { UserRepository } from '@repository/user.repository'; @Injectable() @@ -11,7 +10,7 @@ export class UserService { // this.userRepository.create(createUserDto); // } - async addFollowing(addFollowingDto: AddFollowingDto) { + async addFollowing(addFollowingDto: followerDto) { const user = await this.userRepository.findById(addFollowingDto.myId); const otherUser = await this.userRepository.findById(addFollowingDto.followId); if (!user || !otherUser) { @@ -21,7 +20,38 @@ export class UserService { } else if (otherUser.followers.includes(addFollowingDto.myId)) { throw new ConflictException('상대방의 팔로워 목록에 이미 있습니다.'); } - this.userRepository.appendFollowing(addFollowingDto); - this.userRepository.appendFollwer(addFollowingDto); + + this.userRepository.appendElementAtArr( + { _id: addFollowingDto.myId }, + { followings: addFollowingDto.followId }, + ); + this.userRepository.appendElementAtArr( + { _id: addFollowingDto.followId }, + { followers: addFollowingDto.myId }, + ); + } + + async unFollowing(unFollowingDto: followerDto) { + const user = await this.userRepository.findById(unFollowingDto.myId); + const otherUser = await this.userRepository.findById(unFollowingDto.followId); + if (!user || !otherUser) { + throw new BadRequestException('해당하는 사용자의 _id가 올바르지 않습니다.'); + } else if (!user.followings.includes(unFollowingDto.followId)) { + throw new BadRequestException( + `팔로우 요청한 사용자 ${user.nickname}은 ${otherUser.nickname}을 팔로우하고 있지 않습니다.`, + ); + } else if (!otherUser.followers.includes(unFollowingDto.myId)) { + throw new ConflictException( + `${otherUser.nickname}의 팔로워 목록에 ${user.nickname}가 없습니다.`, + ); + } + this.userRepository.deleteElementAtArr( + { _id: unFollowingDto.myId }, + { followings: [unFollowingDto.followId] }, + ); + this.userRepository.deleteElementAtArr( + { _id: unFollowingDto.followId }, + { followers: [unFollowingDto.myId] }, + ); } } diff --git a/server/dao/repository/user.repository.ts b/server/dao/repository/user.repository.ts index 8292e2c3..8172ab67 100644 --- a/server/dao/repository/user.repository.ts +++ b/server/dao/repository/user.repository.ts @@ -1,8 +1,8 @@ import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { User, UserDocument } from '@schemas/user.schema'; -import { Model } from 'mongoose'; -import { AddFollowingDto } from '@user/dto/add-following.dto'; +import mongoose, { Model, Schema, Types } from 'mongoose'; +import { followerDto } from '@user/dto/follower.dto'; import { SignUpDto } from '@api/src/auth/dto'; @Injectable() @@ -22,25 +22,11 @@ export class UserRepository { return await this.userModel.findById(_id); } - appendFollowing(addFollowingDto: AddFollowingDto) { - this.userModel.updateOne( - { _id: addFollowingDto.myId }, - { $push: { followings: addFollowingDto.followId } }, - (err, res) => { - if (err) throw err; - }, - ); + async appendElementAtArr(filter, appendElement) { + await this.userModel.updateOne(filter, { $push: appendElement }); } - appendFollwer(addFollowingDto: AddFollowingDto) { - this.userModel.updateOne( - { _id: addFollowingDto.followId }, - { - $push: { followers: addFollowingDto.myId }, - }, - (err, res) => { - if (err) throw err; - }, - ); + async deleteElementAtArr(filter, removeElement) { + await this.userModel.updateOne(filter, { $pullAll: removeElement }); } }