From 5b30d305712ae295c53ad961bf1b86e8984c73f8 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Mon, 21 Nov 2022 22:30:06 +0900 Subject: [PATCH 01/44] test: Server Jest --- .github/workflows/server_jest.yml | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/server_jest.yml diff --git a/.github/workflows/server_jest.yml b/.github/workflows/server_jest.yml new file mode 100644 index 00000000..3dd095a6 --- /dev/null +++ b/.github/workflows/server_jest.yml @@ -0,0 +1,66 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs + +name: Server Jest + +on: + push: + branches: [ "main", "dev","dev-be" ] + paths: 'server/**' + pull_request: + branches: [ "main", "dev","dev-be" ] + paths: 'server/**' + +jobs: + build: + runs-on: ubuntu-latest + steps: + # 해당 저장소의 코드를 가져옵니다. + - name: Checkout + uses: actions/checkout@v2 + + # Node 18 버전을 사용합니다. + - name: Install node + uses: actions/setup-node@v2 + with: + node-version: '18' + cache: 'npm' + + # yarn을 설치합니다. + - name: Install Yarn + run: npm install yarn + + # 설치된 yarn을 통해 패키지를 설치합니다. + - name: Install dependencies + run: yarn install + + # 테스트 수행과 그 테스트 결과를 xml파일로 생성합니다. + - name: Run tests + run: yarn server-test | tee ./coverage.txt + + # 테스트 결과를 담은 xml 파일을 레포트로 변환합니다. + - name: Test Report + uses: dorny/test-reporter@v1 + if: success() || failure() # run this step even if previous step failed + with: + name: test-results + path: server/junit.xml + fail-on-error: 'false' + reporter: jest-junit # Format of test results + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Jest Coverage Comment + uses: MishaKav/jest-coverage-comment@main + with: + coverage-path: ./coverage.txt + coverage-summary-path: ./server/coverage/coverage-final.json + junitxml-path: ./server/junit.xml + - name: build 실패 시 Slack 알림 + uses: 8398a7/action-slack@v3 + with: + status: ${{ job.status }} + author_name: 백엔드 빌드 실패 알림 + fields: repo, message, commit, author, action, eventName, ref, workflow, job, took + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_FAIL_WEBHOOK_URL }} + if: failure() \ No newline at end of file From 8d7f8fe4fb21936558afda9dba482ba6c8428dbc Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Tue, 22 Nov 2022 00:19:07 +0900 Subject: [PATCH 02/44] =?UTF-8?q?refactor:=20auth.dto=20=EB=A5=BC=20sign-i?= =?UTF-8?q?n.dto,=20sign-up.dto=20=EB=A1=9C=20=EB=B6=84=ED=95=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/auth/dto/index.ts | 3 ++- server/apps/api/src/auth/dto/sign-in.dto.ts | 11 +++++++++++ .../api/src/auth/dto/{auth.dto.ts => sign-up.dto.ts} | 10 ---------- 3 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 server/apps/api/src/auth/dto/sign-in.dto.ts rename server/apps/api/src/auth/dto/{auth.dto.ts => sign-up.dto.ts} (67%) diff --git a/server/apps/api/src/auth/dto/index.ts b/server/apps/api/src/auth/dto/index.ts index 0ee0429b..aa80f504 100644 --- a/server/apps/api/src/auth/dto/index.ts +++ b/server/apps/api/src/auth/dto/index.ts @@ -1 +1,2 @@ -export * from './auth.dto'; +export * from './sign-in.dto'; +export * from './sign-up.dto'; diff --git a/server/apps/api/src/auth/dto/sign-in.dto.ts b/server/apps/api/src/auth/dto/sign-in.dto.ts new file mode 100644 index 00000000..f23a0ee1 --- /dev/null +++ b/server/apps/api/src/auth/dto/sign-in.dto.ts @@ -0,0 +1,11 @@ +import { IsEmail, IsNotEmpty, IsString, MinLength } from 'class-validator'; + +export class SignInDto { + @IsEmail() + @IsNotEmpty() + id: string; + + @IsString() + @MinLength(8) + password: string; +} diff --git a/server/apps/api/src/auth/dto/auth.dto.ts b/server/apps/api/src/auth/dto/sign-up.dto.ts similarity index 67% rename from server/apps/api/src/auth/dto/auth.dto.ts rename to server/apps/api/src/auth/dto/sign-up.dto.ts index 87a5fdcd..66bda45e 100644 --- a/server/apps/api/src/auth/dto/auth.dto.ts +++ b/server/apps/api/src/auth/dto/sign-up.dto.ts @@ -1,15 +1,5 @@ import { IsEmail, IsNotEmpty, IsString, Length, MinLength } from 'class-validator'; -export class SignInDto { - @IsEmail() - @IsNotEmpty() - id: string; - - @IsString() - @MinLength(8) - password: string; -} - export class SignUpDto { @IsEmail() @IsNotEmpty() From 0dda191679305f0961d7edc43f7f206c5d078889 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Mon, 21 Nov 2022 20:22:23 +0900 Subject: [PATCH 03/44] feat: create community #86 --- server/apps/api/src/api.module.ts | 3 -- .../api/src/community/community.controller.ts | 34 +++++++++++++++++-- .../api/src/community/community.module.ts | 11 +++++- .../api/src/community/community.service.ts | 23 +++++++++++-- .../src/community/dto/create-community.dto.ts | 22 ++++++++++++ server/apps/api/src/user/user.controller.ts | 1 - server/apps/api/src/user/user.module.ts | 3 +- server/dao/repository/community.repository.ts | 15 ++++++++ server/dao/schemas/community.schema.ts | 1 - 9 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 server/apps/api/src/community/dto/create-community.dto.ts create mode 100644 server/dao/repository/community.repository.ts diff --git a/server/apps/api/src/api.module.ts b/server/apps/api/src/api.module.ts index ecc0fc45..fefba2ab 100644 --- a/server/apps/api/src/api.module.ts +++ b/server/apps/api/src/api.module.ts @@ -9,9 +9,6 @@ import { UserModule } from './user/user.module'; import * as winston from 'winston'; import { utilities as nestWinstonModuleUtilities, WinstonModule } from 'nest-winston'; import { AuthModule } from './auth/auth.module'; -import { APP_INTERCEPTOR } from '@nestjs/core'; -import { SentryInterceptor } from '../../webhook.interceptor'; -import { RavenInterceptor, RavenModule } from 'nest-raven'; @Module({ imports: [ diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index a169f161..c2963ed2 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -1,4 +1,32 @@ -import { Controller } from '@nestjs/common'; +import { Body, Controller, Inject, LoggerService, Post } from '@nestjs/common'; +import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; +import { CommunityService } from '@api/src/community/community.service'; +import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; +import { responseForm } from '@utils/responseForm'; -@Controller('community') -export class CommunityController {} +@Controller('api/community') +export class CommunityController { + constructor( + @Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService, + private communityService: CommunityService, + ) {} + + @Post() + async crateCommunity(@Body() createCommunityDto: CreateCommunityDto) { + try { + const _id = '6379c1b25d4f08bbe0c940e1'; + const result = await this.communityService.createCommunity({ + managerId: _id, + ...createCommunityDto, + }); + return responseForm(200, result); + } catch (error) { + this.logger.error(JSON.stringify(error.response)); + if (process.env.NODE_ENV == 'prod') { + throw error; + } else { + return error.response; + } + } + } +} diff --git a/server/apps/api/src/community/community.module.ts b/server/apps/api/src/community/community.module.ts index d4fb4995..e1949041 100644 --- a/server/apps/api/src/community/community.module.ts +++ b/server/apps/api/src/community/community.module.ts @@ -1,9 +1,18 @@ import { Module } from '@nestjs/common'; import { CommunityController } from './community.controller'; import { CommunityService } from './community.service'; +import { MongooseModule } from '@nestjs/mongoose'; +import { Community, CommunitySchema } from '@schemas/community.schema'; +import { CommunityRepository } from '@repository/community.repository'; +import { UserRepository } from '@repository/user.repository'; +import { UserModule } from '@user/user.module'; @Module({ + imports: [ + MongooseModule.forFeature([{ name: Community.name, schema: CommunitySchema }]), + UserModule, + ], controllers: [CommunityController], - providers: [CommunityService], + providers: [CommunityService, CommunityRepository, UserRepository], }) export class CommunityModule {} diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 4cd3bcc7..4b7602ea 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -1,4 +1,23 @@ -import { Injectable } from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; +import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; +import { CommunityRepository } from '@repository/community.repository'; +import { UserRepository } from '@repository/user.repository'; @Injectable() -export class CommunityService {} +export class CommunityService { + constructor( + private readonly communityRepository: CommunityRepository, + private readonly userRepository: UserRepository, + ) {} + + async createCommunity(createCommunityDto: CreateCommunityDto) { + const manager = await this.userRepository.findById(createCommunityDto.managerId); + if (!manager) { + throw new BadRequestException('해당하는 매니저의 _id가 올바르지 않습니다.'); + } + return await this.communityRepository.create({ + ...createCommunityDto, + users: [createCommunityDto.managerId], + }); + } +} diff --git a/server/apps/api/src/community/dto/create-community.dto.ts b/server/apps/api/src/community/dto/create-community.dto.ts new file mode 100644 index 00000000..7d7d173d --- /dev/null +++ b/server/apps/api/src/community/dto/create-community.dto.ts @@ -0,0 +1,22 @@ +import { IsNotEmpty, IsOptional, IsString } from 'class-validator'; + +export class CreateCommunityDto { + @IsNotEmpty() + @IsString() + name: string; + + @IsOptional() + @IsString() + managerId: string; + + @IsOptional() + @IsString() + description: string; + + @IsOptional() + @IsString() + profileUrl: string; + + @IsOptional() + users: string[]; +} diff --git a/server/apps/api/src/user/user.controller.ts b/server/apps/api/src/user/user.controller.ts index 5d24caed..93d1db11 100644 --- a/server/apps/api/src/user/user.controller.ts +++ b/server/apps/api/src/user/user.controller.ts @@ -16,7 +16,6 @@ import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { responseForm } from '@utils/responseForm'; import { ObjectIdValidationPipe } from '@custom_pipe/mongodbObjectIdValidation.pipe'; import { ModifyUserDto } from '@user/dto/modify-user.dto'; -import { Response } from 'express'; @Controller('api/user') export class UserController { diff --git a/server/apps/api/src/user/user.module.ts b/server/apps/api/src/user/user.module.ts index 7a7310b2..8726018d 100644 --- a/server/apps/api/src/user/user.module.ts +++ b/server/apps/api/src/user/user.module.ts @@ -2,15 +2,14 @@ import { Module } from '@nestjs/common'; import { UserController } from '@user/user.controller'; import { UserService } from '@user/user.service'; import { MongooseModule } from '@nestjs/mongoose'; -import { WinstonModule } from 'nest-winston'; import { User, UserSchema } from '@schemas/user.schema'; import { AuthModule } from '../auth/auth.module'; import { UserRepository } from '@repository/user.repository'; -import { AuthController } from '../auth/auth.controller'; @Module({ imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]), AuthModule], controllers: [UserController], providers: [UserService, UserRepository], + exports: [MongooseModule], }) export class UserModule {} diff --git a/server/dao/repository/community.repository.ts b/server/dao/repository/community.repository.ts new file mode 100644 index 00000000..f73f1f2f --- /dev/null +++ b/server/dao/repository/community.repository.ts @@ -0,0 +1,15 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { Community, CommunityDocument } from '@schemas/community.schema'; +import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; + +@Injectable() +export class CommunityRepository { + constructor(@InjectModel(Community.name) private communityModel: Model) {} + + async create(createCommunityDto: CreateCommunityDto) { + const result = await this.communityModel.create(createCommunityDto); + return (result as any)._doc; + } +} diff --git a/server/dao/schemas/community.schema.ts b/server/dao/schemas/community.schema.ts index 87b231f8..5b3ee72c 100644 --- a/server/dao/schemas/community.schema.ts +++ b/server/dao/schemas/community.schema.ts @@ -13,7 +13,6 @@ export class Community { @Prop({ required: true, - unique: true, }) @IsString() @IsNotEmpty() From 8023619b5598415f6929746d0089fac68514f339 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Mon, 21 Nov 2022 21:08:28 +0900 Subject: [PATCH 04/44] test: createCommunity test --- server/__mock__/community.mock.ts | 8 +++ .../apps/api/test/community.service.spec.ts | 54 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 server/__mock__/community.mock.ts create mode 100644 server/apps/api/test/community.service.spec.ts diff --git a/server/__mock__/community.mock.ts b/server/__mock__/community.mock.ts new file mode 100644 index 00000000..f631960e --- /dev/null +++ b/server/__mock__/community.mock.ts @@ -0,0 +1,8 @@ +import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; + +export const communityDto1 = { + name: 'asnity commu', + managerId: '63734af9e62b37012c73e399', + description: 'test description', + profileUrl: 'test profileUrl', +} as CreateCommunityDto; diff --git a/server/apps/api/test/community.service.spec.ts b/server/apps/api/test/community.service.spec.ts new file mode 100644 index 00000000..36870c3c --- /dev/null +++ b/server/apps/api/test/community.service.spec.ts @@ -0,0 +1,54 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { getModelToken } from '@nestjs/mongoose'; +import * as _ from 'lodash'; +import { CommunityService } from '@api/src/community/community.service'; +import { Community } from '@schemas/community.schema'; +import { CommunityRepository } from '@repository/community.repository'; +import { user1 } from '@mock/user.mock'; +import { UserRepository } from '@repository/user.repository'; +import { communityDto1 } from '@mock/community.mock'; +import { UserModule } from '@user/user.module'; +import { User } from '@schemas/user.schema'; + +describe('[Community Service]', () => { + let communityService: CommunityService; + let communityRepository: CommunityRepository; + let userRepository: UserRepository; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + CommunityService, + CommunityRepository, + UserRepository, + { + provide: getModelToken(Community.name), + useFactory: () => {}, + }, + { + provide: getModelToken(User.name), + useFactory: () => {}, + }, + ], + }).compile(); + + communityService = module.get(CommunityService); + communityRepository = module.get(CommunityRepository); + userRepository = module.get(UserRepository); + }); + + it('should be defined', () => { + expect(communityService).toBeDefined(); + }); + + describe('[createCommunity] 커뮤니티 생성', () => { + it('커뮤니티 생성 정상 동작', async () => { + const community1 = _.cloneDeep(user1); + community1.users = [user1._id]; + jest.spyOn(userRepository, 'findById').mockResolvedValue(user1); + jest.spyOn(communityRepository, 'create').mockResolvedValue(community1); + const result = await communityService.createCommunity(communityDto1); + expect(result).toEqual(community1); + }); + }); +}); From 27c10f08a11393a10b5381f8225a1bcde7f5c082 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Tue, 22 Nov 2022 13:53:57 +0900 Subject: [PATCH 05/44] =?UTF-8?q?refactor:=20access=20token=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=99=80=EC=84=9C=20=5Fid=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 8 +++--- .../api/src/community/community.service.ts | 8 +++--- server/apps/api/src/user/user.controller.ts | 27 ++++++++++--------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index c2963ed2..6f8acb76 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -1,8 +1,9 @@ -import { Body, Controller, Inject, LoggerService, Post } from '@nestjs/common'; +import { Body, Controller, Inject, LoggerService, Post, Req, UseGuards } from '@nestjs/common'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { CommunityService } from '@api/src/community/community.service'; import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; import { responseForm } from '@utils/responseForm'; +import { JwtAccessGuard } from '@api/src/auth/guard'; @Controller('api/community') export class CommunityController { @@ -12,9 +13,10 @@ export class CommunityController { ) {} @Post() - async crateCommunity(@Body() createCommunityDto: CreateCommunityDto) { + @UseGuards(JwtAccessGuard) + async crateCommunity(@Body() createCommunityDto: CreateCommunityDto, @Req() req: any) { try { - const _id = '6379c1b25d4f08bbe0c940e1'; + const _id = req.user._id; const result = await this.communityService.createCommunity({ managerId: _id, ...createCommunityDto, diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 4b7602ea..5b033bca 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -11,10 +11,10 @@ export class CommunityService { ) {} async createCommunity(createCommunityDto: CreateCommunityDto) { - const manager = await this.userRepository.findById(createCommunityDto.managerId); - if (!manager) { - throw new BadRequestException('해당하는 매니저의 _id가 올바르지 않습니다.'); - } + // const manager = await this.userRepository.findById(createCommunityDto.managerId); + // if (!manager) { + // throw new BadRequestException('해당하는 매니저의 _id가 올바르지 않습니다.'); + // } return await this.communityRepository.create({ ...createCommunityDto, users: [createCommunityDto.managerId], diff --git a/server/apps/api/src/user/user.controller.ts b/server/apps/api/src/user/user.controller.ts index 93d1db11..4cfa7e94 100644 --- a/server/apps/api/src/user/user.controller.ts +++ b/server/apps/api/src/user/user.controller.ts @@ -8,7 +8,9 @@ import { Param, Patch, Post, + Req, Res, + UseGuards, } from '@nestjs/common'; import { UserService } from './user.service'; import { FollowerDto } from '@user/dto/follower.dto'; @@ -16,6 +18,7 @@ import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { responseForm } from '@utils/responseForm'; import { ObjectIdValidationPipe } from '@custom_pipe/mongodbObjectIdValidation.pipe'; import { ModifyUserDto } from '@user/dto/modify-user.dto'; +import { JwtAccessGuard } from '@api/src/auth/guard'; @Controller('api/user') export class UserController { @@ -32,10 +35,10 @@ export class UserController { // } @Post('following/:id') - async addFollowing(@Param('id', ObjectIdValidationPipe) id: string) { + @UseGuards(JwtAccessGuard) + async addFollowing(@Param('id', ObjectIdValidationPipe) id: string, @Req() req: any) { try { - const myId = '63786b635d4f08bbe0c940de'; - // TODO: Request Header에서 access token으로 현재 사용자 알아내기 + const myId = req.user._id; const addFollowingDto: FollowerDto = { myId, followId: id }; const result = await this.userService.toggleFollowing(addFollowingDto); return responseForm(200, result); @@ -47,10 +50,10 @@ export class UserController { } @Get('followers') - async getFollowers() { + @UseGuards(JwtAccessGuard) + async getFollowers(@Req() req: any) { try { - const _id = '63786b635d4f08bbe0c940dc'; - // TODO: Request Header에서 access token으로 현재 사용자 알아내기 + const _id = req.user._id; const result = await this.userService.getRelatedUsers(_id, 'followers'); return responseForm(200, { followers: result }); } catch (error) { @@ -60,10 +63,10 @@ export class UserController { } @Get('followings') - async getFollowings() { + @UseGuards(JwtAccessGuard) + async getFollowings(@Req() req: any) { try { - const _id = '63739b643969101c3fec884'; - // TODO: Request Header에서 access token으로 현재 사용자 알아내기 + const _id = req.user._id; const result = await this.userService.getRelatedUsers(_id, 'followings'); return responseForm(200, { followings: result }); } catch (error) { @@ -84,10 +87,10 @@ export class UserController { } @Patch('settings') - async modifyUserSetting(@Body() modifyUserDto: ModifyUserDto) { + @UseGuards(JwtAccessGuard) + async modifyUserSetting(@Body() modifyUserDto: ModifyUserDto, @Req() req: any) { try { - const _id = '63786b635d4f08bbe0c940de'; - // TODO: Request Header에서 access token으로 현재 사용자 알아내기 + const _id = req.user._id; await this.userService.modifyUser({ ...modifyUserDto, _id }); return responseForm(200, {}); } catch (error) { From a3c11c8da7c480d202cd8a0ccd45813148c62dfe Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Tue, 22 Nov 2022 14:50:02 +0900 Subject: [PATCH 06/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20controller=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 6f8acb76..a499bcb9 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -1,4 +1,13 @@ -import { Body, Controller, Inject, LoggerService, Post, Req, UseGuards } from '@nestjs/common'; +import { + Body, + Controller, + Inject, + LoggerService, + Param, + Post, + Req, + UseGuards, +} from '@nestjs/common'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { CommunityService } from '@api/src/community/community.service'; import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; @@ -31,4 +40,25 @@ export class CommunityController { } } } + + @Post(':community_id/participants') + @UseGuards(JwtAccessGuard) + async appendParticipantsToCommunity( + @Param('community_id') community_id: string, + @Body('users') users: string[], + @Req() req: any, + ) { + try { + const _id = req.user._id; + const appendUsersToCommunityDto = { requestUser_id: _id, community_id }; + console.log(users); + const result = await this.communityService.appendParticipantsToCommunity(); + } catch (error) { + if (process.env.NODE_ENV == 'prod') { + throw error; + } else { + return error.response; + } + } + } } From 8589e0b8fa8bb4380ff17f0b1bba35a52d0fbd12 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Tue, 22 Nov 2022 23:55:51 +0900 Subject: [PATCH 07/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20service=20layer=20=EA=B5=AC=ED=98=84=20#95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 22 +++++++++++---- .../api/src/community/community.service.ts | 28 +++++++++++++++++++ .../append-particitants-to-community.dto.ts | 23 +++++++++++++++ server/dao/repository/community.repository.ts | 10 +++++++ server/tsconfig.json | 1 + 5 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 server/apps/api/src/community/dto/append-particitants-to-community.dto.ts diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index a499bcb9..70d9e8c6 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -13,6 +13,7 @@ import { CommunityService } from '@api/src/community/community.service'; import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; import { responseForm } from '@utils/responseForm'; import { JwtAccessGuard } from '@api/src/auth/guard'; +import { AppendUsersToCommunityDto } from '@community/dto/append-particitants-to-community.dto'; @Controller('api/community') export class CommunityController { @@ -41,19 +42,28 @@ export class CommunityController { } } - @Post(':community_id/participants') + @Post('participants') @UseGuards(JwtAccessGuard) async appendParticipantsToCommunity( - @Param('community_id') community_id: string, - @Body('users') users: string[], + // @Param('community_id') community_id: string, + // @Body('users') users: string[], + @Body() appendUsersToCommunityDto: AppendUsersToCommunityDto, @Req() req: any, ) { try { const _id = req.user._id; - const appendUsersToCommunityDto = { requestUser_id: _id, community_id }; - console.log(users); - const result = await this.communityService.appendParticipantsToCommunity(); + // const appendUsersToCommunityDto: AppendUsersToCommunityDto = { + // requestUser_id: _id, + // community_id, + // }; + // console.log(users); + const result = await this.communityService.appendParticipantsToCommunity({ + ...appendUsersToCommunityDto, + requestUser_id: _id, + }); + return responseForm(200, result); } catch (error) { + this.logger.error(JSON.stringify(error.response)); if (process.env.NODE_ENV == 'prod') { throw error; } else { diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 5b033bca..a3651cd5 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -2,6 +2,8 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; import { CommunityRepository } from '@repository/community.repository'; import { UserRepository } from '@repository/user.repository'; +import { AppendUsersToCommunityDto } from '@api/src/community/dto/append-particitants-to-community.dto'; +import { getUserBasicInfo } from '@user/dto/user-basic-info.dto'; @Injectable() export class CommunityService { @@ -20,4 +22,30 @@ export class CommunityService { users: [createCommunityDto.managerId], }); } + + async appendParticipantsToCommunity(appendUsersToCommunityDto: AppendUsersToCommunityDto) { + const community = await this.communityRepository.findById( + appendUsersToCommunityDto.community_id, + ); + if (!community) { + throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.'); + } + await Promise.all( + appendUsersToCommunityDto.users.map((user) => + this.userRepository.findById(user).then((result) => { + if (!result) { + throw new BadRequestException( + `커뮤니티에 추가를 요청한 사용자 _id(${user})가 올바르지 않습니다.`, + ); + } + }), + ), + ); + await this.communityRepository.addArrAtArr( + { _id: appendUsersToCommunityDto.community_id }, + 'users', + appendUsersToCommunityDto.users, + ); + return { message: '커뮤니티 사용자 추가 완료' }; + } } diff --git a/server/apps/api/src/community/dto/append-particitants-to-community.dto.ts b/server/apps/api/src/community/dto/append-particitants-to-community.dto.ts new file mode 100644 index 00000000..fb6b8ab7 --- /dev/null +++ b/server/apps/api/src/community/dto/append-particitants-to-community.dto.ts @@ -0,0 +1,23 @@ +import { + ArrayNotEmpty, + IsArray, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, +} from 'class-validator'; + +export class AppendUsersToCommunityDto { + @IsNotEmpty() + @IsString() + community_id: string; + + @IsOptional() + @IsString() + requestUser_id: string; + + @IsNotEmpty() + @IsArray() + @ArrayNotEmpty() + users: string[]; +} diff --git a/server/dao/repository/community.repository.ts b/server/dao/repository/community.repository.ts index f73f1f2f..d7becfb0 100644 --- a/server/dao/repository/community.repository.ts +++ b/server/dao/repository/community.repository.ts @@ -12,4 +12,14 @@ export class CommunityRepository { const result = await this.communityModel.create(createCommunityDto); return (result as any)._doc; } + + async findById(_id: string) { + return await this.communityModel.findById(_id); + } + + async addArrAtArr(filter, attribute, appendArr) { + const addArr = {}; + addArr[attribute] = { $each: appendArr }; + await this.communityModel.updateOne(filter, { $addToSet: addArr }); + } } diff --git a/server/tsconfig.json b/server/tsconfig.json index b43f558a..28fdce23 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -23,6 +23,7 @@ "@utils/*": ["utils/*"], "@custom_pipe/*": ["custom_pipe/*"], "@user/*": ["apps/api/src/user/*"], + "@community/*": ["apps/api/src/community/*"], "@api/*": ["apps/api/*"], "@mock/*": ["__mock__/*"], } From 0d2a8a055e3188949cadef318f2e786faf469038 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 00:04:16 +0900 Subject: [PATCH 08/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=20updatedAt=20=EA=B0=B1=EC=8B=A0=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=8A=A4=ED=82=A4=EB=A7=88=20=EC=88=98=EC=A0=95=20#95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/dao/schemas/community.schema.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/server/dao/schemas/community.schema.ts b/server/dao/schemas/community.schema.ts index 5b3ee72c..e6fe5806 100644 --- a/server/dao/schemas/community.schema.ts +++ b/server/dao/schemas/community.schema.ts @@ -4,7 +4,7 @@ import { IsNotEmpty, IsString } from 'class-validator'; export type CommunityDocument = Community & Document; -@Schema() +@Schema({ timestamps: true }) export class Community { @Prop() @IsString() @@ -26,12 +26,6 @@ export class Community { @IsString() profileUrl: string; - @Prop({ default: new Date(), type: mongoose.Schema.Types.Date }) - createdAt: Date; - - @Prop({ default: new Date(), type: mongoose.Schema.Types.Date }) - updatedAt: Date; - @Prop({ type: mongoose.Schema.Types.Date }) deletedAt: Date; From 181c52b7890ef0ecb16149374c5e0946b0f6aaf7 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 02:04:56 +0900 Subject: [PATCH 09/44] =?UTF-8?q?refactor:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20update=20->=20findAndUpdate=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=20#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.service.ts | 29 ++++++++----------- server/dao/repository/community.repository.ts | 2 +- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index a3651cd5..6080f41e 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -3,7 +3,6 @@ import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto' import { CommunityRepository } from '@repository/community.repository'; import { UserRepository } from '@repository/user.repository'; import { AppendUsersToCommunityDto } from '@api/src/community/dto/append-particitants-to-community.dto'; -import { getUserBasicInfo } from '@user/dto/user-basic-info.dto'; @Injectable() export class CommunityService { @@ -24,28 +23,24 @@ export class CommunityService { } async appendParticipantsToCommunity(appendUsersToCommunityDto: AppendUsersToCommunityDto) { - const community = await this.communityRepository.findById( - appendUsersToCommunityDto.community_id, - ); - if (!community) { - throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.'); - } await Promise.all( - appendUsersToCommunityDto.users.map((user) => - this.userRepository.findById(user).then((result) => { - if (!result) { - throw new BadRequestException( - `커뮤니티에 추가를 요청한 사용자 _id(${user})가 올바르지 않습니다.`, - ); - } - }), - ), + appendUsersToCommunityDto.users.map(async (user_id) => { + const user = this.userRepository.findById(user_id); + if (!user) { + throw new BadRequestException( + `커뮤니티에 추가를 요청한 사용자 _id(${user_id})가 올바르지 않습니다.`, + ); + } + }), ); - await this.communityRepository.addArrAtArr( + const community = await this.communityRepository.addArrAtArr( { _id: appendUsersToCommunityDto.community_id }, 'users', appendUsersToCommunityDto.users, ); + if (!community) { + throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.'); + } return { message: '커뮤니티 사용자 추가 완료' }; } } diff --git a/server/dao/repository/community.repository.ts b/server/dao/repository/community.repository.ts index d7becfb0..c92a8c4a 100644 --- a/server/dao/repository/community.repository.ts +++ b/server/dao/repository/community.repository.ts @@ -20,6 +20,6 @@ export class CommunityRepository { async addArrAtArr(filter, attribute, appendArr) { const addArr = {}; addArr[attribute] = { $each: appendArr }; - await this.communityModel.updateOne(filter, { $addToSet: addArr }); + return await this.communityModel.findOneAndUpdate(filter, { $addToSet: addArr }, { new: true }); } } From 68fab2aa8f1213bae6f9941ae37cb0b5cf38ed31 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Tue, 22 Nov 2022 13:53:57 +0900 Subject: [PATCH 10/44] =?UTF-8?q?fix:=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yarn.lock | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index e4da8cb0..f9ae5416 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2529,6 +2529,14 @@ multer "1.4.4-lts.1" tslib "2.4.1" +"@nestjs/platform-socket.io@^9.2.0": + version "9.2.0" + resolved "https://registry.yarnpkg.com/@nestjs/platform-socket.io/-/platform-socket.io-9.2.0.tgz#5194a13d4ef5c70b32b2bcc64379e07674ddf0ab" + integrity sha512-ttxXtqHV3Cpk5AfZOxfE8urILV5oLBpG21vdyqUHiL0YDuhHdc2tBz5GKSYAfsWefmVeQQiBAV9dqaa23Rf0nQ== + dependencies: + socket.io "4.5.3" + tslib "2.4.1" + "@nestjs/schematics@^9.0.0": version "9.0.3" resolved "https://registry.yarnpkg.com/@nestjs/schematics/-/schematics-9.0.3.tgz#175218350fb3829c9a903e980046a11950310e24" @@ -2547,6 +2555,15 @@ dependencies: tslib "2.4.1" +"@nestjs/websockets@^9.2.0": + version "9.2.0" + resolved "https://registry.yarnpkg.com/@nestjs/websockets/-/websockets-9.2.0.tgz#cbe8d446eff653d9c63234ef396ccc1ea031e875" + integrity sha512-AbG4eN9p9O6QmNSOWsk0lrA+CtHkrdDkogcl1sGyTrg+LRd6IUlkaTu9fFK9Hl6o7bs2ieGgDmxAvl+Xd156Aw== + dependencies: + iterare "1.2.1" + object-hash "3.0.0" + tslib "2.4.1" + "@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3": version "2.1.8-no-fsevents.3" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz#323d72dd25103d0c4fbdce89dadf574a787b1f9b" @@ -2782,6 +2799,11 @@ "@types/node" ">=12.0.0" axios "^0.21.4" +"@socket.io/component-emitter@~3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" + integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== + "@tanstack/match-sorter-utils@8.1.1": version "8.1.1" resolved "https://registry.yarnpkg.com/@tanstack/match-sorter-utils/-/match-sorter-utils-8.1.1.tgz#895f407813254a46082a6bbafad9b39b943dc834" @@ -2964,6 +2986,11 @@ resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8" integrity sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog== +"@types/cors@^2.8.12": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + "@types/debug@^4.1.7": version "4.1.7" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" @@ -3125,7 +3152,7 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== -"@types/node@*", "@types/node@>=12.0.0", "@types/node@>=8.9.0": +"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.0.0", "@types/node@>=8.9.0": version "18.11.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== @@ -3242,6 +3269,13 @@ dependencies: "@types/node" "*" +"@types/socket.io@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/socket.io/-/socket.io-3.0.2.tgz#606c9639e3f93bb8454cba8f5f0a283d47917759" + integrity sha512-pu0sN9m5VjCxBZVK8hW37ZcMe8rjn4HHggBN5CbaRTvFwv5jOmuIRZEuddsBPa9Th0ts0SIo3Niukq+95cMBbQ== + dependencies: + socket.io "*" + "@types/sockjs@^0.3.33": version "0.3.33" resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" @@ -4069,6 +4103,11 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -4650,7 +4689,7 @@ cookie@0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -cookie@^0.4.1, cookie@^0.4.2: +cookie@^0.4.1, cookie@^0.4.2, cookie@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== @@ -4689,7 +4728,7 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cors@2.8.5: +cors@2.8.5, cors@~2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== @@ -4899,7 +4938,7 @@ debug@2.6.9, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4, debug@4.x, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@4.x, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -5242,6 +5281,27 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +engine.io-parser@~5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.4.tgz#0b13f704fa9271b3ec4f33112410d8f3f41d0fc0" + integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg== + +engine.io@~6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.1.tgz#e3f7826ebc4140db9bbaa9021ad6b1efb175878f" + integrity sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.2.3" + enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0: version "5.10.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" @@ -10040,6 +10100,31 @@ smart-buffer@^4.2.0: resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== +socket.io-adapter@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" + integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg== + +socket.io-parser@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.1.tgz#01c96efa11ded938dcb21cbe590c26af5eff65e5" + integrity sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + +socket.io@*, socket.io@4.5.3, socket.io@^4.5.3: + version "4.5.3" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.3.tgz#44dffea48d7f5aa41df4a66377c386b953bc521c" + integrity sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.2.0" + socket.io-adapter "~2.4.0" + socket.io-parser "~4.2.0" + sockjs@^0.3.24: version "0.3.24" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" @@ -11309,6 +11394,11 @@ ws@^5.2.0: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + xml-name-validator@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" From 5dbe7b4442b13d292f9054179e17db4371ceb491 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 02:23:40 +0900 Subject: [PATCH 11/44] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=9E=88=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=20skip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/community/community.service.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 6080f41e..9c78f063 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -12,10 +12,6 @@ export class CommunityService { ) {} async createCommunity(createCommunityDto: CreateCommunityDto) { - // const manager = await this.userRepository.findById(createCommunityDto.managerId); - // if (!manager) { - // throw new BadRequestException('해당하는 매니저의 _id가 올바르지 않습니다.'); - // } return await this.communityRepository.create({ ...createCommunityDto, users: [createCommunityDto.managerId], From d6829fecf933d1b88c59ac2debbc91294014c3ca Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 02:48:24 +0900 Subject: [PATCH 12/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=8B=9C=20=EC=82=AC=EC=9A=A9=EC=9E=90=20document=20update=20#?= =?UTF-8?q?95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/community/community.service.ts | 13 ++++++++++++- server/dao/repository/user.repository.ts | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 9c78f063..5cf7c94a 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -21,12 +21,15 @@ export class CommunityService { async appendParticipantsToCommunity(appendUsersToCommunityDto: AppendUsersToCommunityDto) { await Promise.all( appendUsersToCommunityDto.users.map(async (user_id) => { - const user = this.userRepository.findById(user_id); + const user = await this.userRepository.findById(user_id); if (!user) { throw new BadRequestException( `커뮤니티에 추가를 요청한 사용자 _id(${user_id})가 올바르지 않습니다.`, ); } + await this.userRepository.addArrAtArr({ _id: user_id }, 'communities', [ + appendUsersToCommunityDto.community_id, + ]); }), ); const community = await this.communityRepository.addArrAtArr( @@ -35,6 +38,14 @@ export class CommunityService { appendUsersToCommunityDto.users, ); if (!community) { + await Promise.all( + appendUsersToCommunityDto.users.map((user_id) => { + this.userRepository.deleteElementAtArr( + { _id: user_id }, + { communities: [appendUsersToCommunityDto.community_id] }, + ); + }), + ); throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.'); } return { message: '커뮤니티 사용자 추가 완료' }; diff --git a/server/dao/repository/user.repository.ts b/server/dao/repository/user.repository.ts index 60d99b9d..a3720bb4 100644 --- a/server/dao/repository/user.repository.ts +++ b/server/dao/repository/user.repository.ts @@ -36,4 +36,10 @@ export class UserRepository { async deleteElementAtArr(filter, removeElement) { await this.userModel.updateOne(filter, { $pullAll: removeElement }); } + + async addArrAtArr(filter, attribute, appendArr) { + const addArr = {}; + addArr[attribute] = { $each: appendArr }; + return await this.userModel.findOneAndUpdate(filter, { $addToSet: addArr }, { new: true }); + } } From 0c769b66c24fa2e98d9b515f3728748913db213e Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 13:16:47 +0900 Subject: [PATCH 13/44] =?UTF-8?q?fix:=20cors=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/main.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/apps/api/src/main.ts b/server/apps/api/src/main.ts index 22661db8..8e5e4cdb 100644 --- a/server/apps/api/src/main.ts +++ b/server/apps/api/src/main.ts @@ -8,7 +8,11 @@ import * as cookieParser from 'cookie-parser'; async function bootstrap() { const app = await NestFactory.create(ApiModule); - app.enableCors(); + app.enableCors({ + origin: true, + methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS', + credentials: true, + }); if (process.env.NODE_ENV == 'prod') { Sentry.init({ dsn: process.env.SENTRY_DSN, From 1115f825c2e13816f1d03cdf3b9cbc39d442efb7 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 00:30:44 +0900 Subject: [PATCH 14/44] =?UTF-8?q?fix:=20=EC=B6=A9=EB=8F=8C=20=EB=B3=91?= =?UTF-8?q?=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 15 ++++++++++++ .../src/community/dto/modify-community.dto.ts | 23 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 server/apps/api/src/community/dto/modify-community.dto.ts diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 70d9e8c6..d98fcdbe 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -4,6 +4,7 @@ import { Inject, LoggerService, Param, + Patch, Post, Req, UseGuards, @@ -14,6 +15,7 @@ import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto' import { responseForm } from '@utils/responseForm'; import { JwtAccessGuard } from '@api/src/auth/guard'; import { AppendUsersToCommunityDto } from '@community/dto/append-particitants-to-community.dto'; +import { ModifyCommunityDto } from '@api/src/community/dto/modify-community.dto'; @Controller('api/community') export class CommunityController { @@ -71,4 +73,17 @@ export class CommunityController { } } } + + @Patch('settings') + @UseGuards(JwtAccessGuard) + async modifyCommunitySetting(@Body() modifyCommunityDto: ModifyCommunityDto, @Req() req: any) { + try { + const _id = req.user._id; + await this.communityService.modifyCommunity({ ...modifyCommunityDto, managerId: _id }); + return responseForm(200, {}); + } catch (error) { + this.logger.error(JSON.stringify(error.response)); + throw error; + } + } } diff --git a/server/apps/api/src/community/dto/modify-community.dto.ts b/server/apps/api/src/community/dto/modify-community.dto.ts new file mode 100644 index 00000000..bf382f10 --- /dev/null +++ b/server/apps/api/src/community/dto/modify-community.dto.ts @@ -0,0 +1,23 @@ +import { IsNotEmpty, IsOptional, IsString } from 'class-validator'; + +export class ModifyCommunityDto { + @IsNotEmpty() + @IsString() + _id: string; + + @IsOptional() + @IsString() + name: string; + + @IsOptional() + @IsString() + managerId: string; + + @IsOptional() + @IsString() + description: string; + + @IsOptional() + @IsString() + profileUrl: string; +} From 3e8e34df89d4d637d183689075a02880beba5fba Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 00:39:48 +0900 Subject: [PATCH 15/44] =?UTF-8?q?fix:=20cherry=20fix=20=EC=B6=A9=EB=8F=8C?= =?UTF-8?q?=20=EB=B3=91=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.service.ts | 22 +++++++++++++++++++ .../src/community/dto/modify-community.dto.ts | 2 +- server/dao/repository/community.repository.ts | 4 ++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 5cf7c94a..e8315d61 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -3,6 +3,7 @@ import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto' import { CommunityRepository } from '@repository/community.repository'; import { UserRepository } from '@repository/user.repository'; import { AppendUsersToCommunityDto } from '@api/src/community/dto/append-particitants-to-community.dto'; +import { ModifyCommunityDto } from '@api/src/community/dto/modify-community.dto'; @Injectable() export class CommunityService { @@ -50,4 +51,25 @@ export class CommunityService { } return { message: '커뮤니티 사용자 추가 완료' }; } + + async modifyCommunity(modifyCommunityDto: ModifyCommunityDto) { + this.verfiyManager(modifyCommunityDto.managerId); + this.verfiyCommunity(modifyCommunityDto.community_id); + } + + async verfiyManager(managerId: string) { + const manager = await this.userRepository.findById(managerId); + if (!manager) { + throw new BadRequestException('해당하는 매니저의 _id가 올바르지 않습니다.'); + } + return manager; + } + + async verfiyCommunity(community_id: string) { + const community = await this.communityRepository.findOne(community_id); + if (!community) { + throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.'); + } + return community; + } } diff --git a/server/apps/api/src/community/dto/modify-community.dto.ts b/server/apps/api/src/community/dto/modify-community.dto.ts index bf382f10..18a5a292 100644 --- a/server/apps/api/src/community/dto/modify-community.dto.ts +++ b/server/apps/api/src/community/dto/modify-community.dto.ts @@ -3,7 +3,7 @@ import { IsNotEmpty, IsOptional, IsString } from 'class-validator'; export class ModifyCommunityDto { @IsNotEmpty() @IsString() - _id: string; + community_id: string; @IsOptional() @IsString() diff --git a/server/dao/repository/community.repository.ts b/server/dao/repository/community.repository.ts index c92a8c4a..d9cdd4ab 100644 --- a/server/dao/repository/community.repository.ts +++ b/server/dao/repository/community.repository.ts @@ -22,4 +22,8 @@ export class CommunityRepository { addArr[attribute] = { $each: appendArr }; return await this.communityModel.findOneAndUpdate(filter, { $addToSet: addArr }, { new: true }); } + + async findOne(condition: any) { + return await this.communityModel.findOne(condition); + } } From c34dc7cc52db838c79bfcce74db949a871c76d99 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 00:56:06 +0900 Subject: [PATCH 16/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=20service?= =?UTF-8?q?=20layer=20=EA=B5=AC=ED=98=84=20#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/community/community.service.ts | 12 +++++++++--- server/dao/repository/community.repository.ts | 4 ++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index e8315d61..976d2827 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -53,8 +53,14 @@ export class CommunityService { } async modifyCommunity(modifyCommunityDto: ModifyCommunityDto) { - this.verfiyManager(modifyCommunityDto.managerId); - this.verfiyCommunity(modifyCommunityDto.community_id); + await this.verfiyManager(modifyCommunityDto.managerId); + const community = await this.verfiyCommunity(modifyCommunityDto.community_id); + if (community.managerId != modifyCommunityDto.managerId) { + throw new BadRequestException('사용자의 커뮤니티 수정 권한이 없습니다.'); + } + const { managerId, community_id, ...updateField } = modifyCommunityDto; + // TODO: 꼭 기다려줘야하는지 생각해보기 + return await this.communityRepository.updateOne({ _id: community_id }, updateField); } async verfiyManager(managerId: string) { @@ -66,7 +72,7 @@ export class CommunityService { } async verfiyCommunity(community_id: string) { - const community = await this.communityRepository.findOne(community_id); + const community = await this.communityRepository.findOne({ _id: community_id }); if (!community) { throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.'); } diff --git a/server/dao/repository/community.repository.ts b/server/dao/repository/community.repository.ts index d9cdd4ab..10e9706d 100644 --- a/server/dao/repository/community.repository.ts +++ b/server/dao/repository/community.repository.ts @@ -26,4 +26,8 @@ export class CommunityRepository { async findOne(condition: any) { return await this.communityModel.findOne(condition); } + + async updateOne(filter, updateField) { + await this.communityModel.updateOne(filter, updateField); + } } From d14969a27316ea43ac632f3a0e1fde4be659d837 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 01:39:30 +0900 Subject: [PATCH 17/44] todo: error response --- server/apps/api/src/community/community.controller.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index d98fcdbe..09dc8dfd 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -83,7 +83,8 @@ export class CommunityController { return responseForm(200, {}); } catch (error) { this.logger.error(JSON.stringify(error.response)); - throw error; + // TODO : error response header status code 어떻게 할지 논의 + throw error; // 이렇게하면 header status code 400 간다. } } } From 05236b031f67cfa812b7d4552de9a96d82067bcc Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 02:21:55 +0900 Subject: [PATCH 18/44] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=9E=88=EB=8A=94=EC=A7=80=20=EA=B2=80=EC=A6=9D=20skip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/community/community.service.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 976d2827..2d7b81eb 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -53,7 +53,6 @@ export class CommunityService { } async modifyCommunity(modifyCommunityDto: ModifyCommunityDto) { - await this.verfiyManager(modifyCommunityDto.managerId); const community = await this.verfiyCommunity(modifyCommunityDto.community_id); if (community.managerId != modifyCommunityDto.managerId) { throw new BadRequestException('사용자의 커뮤니티 수정 권한이 없습니다.'); @@ -63,14 +62,6 @@ export class CommunityService { return await this.communityRepository.updateOne({ _id: community_id }, updateField); } - async verfiyManager(managerId: string) { - const manager = await this.userRepository.findById(managerId); - if (!manager) { - throw new BadRequestException('해당하는 매니저의 _id가 올바르지 않습니다.'); - } - return manager; - } - async verfiyCommunity(community_id: string) { const community = await this.communityRepository.findOne({ _id: community_id }); if (!community) { From 5097443366760d0a2c61f0f18c95c5542f988c01 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 15:56:41 +0900 Subject: [PATCH 19/44] =?UTF-8?q?refactor:=20dto=20index.ts=EB=A1=9C=20?= =?UTF-8?q?=EB=B2=88=EB=93=A4=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/community/community.controller.ts | 4 +--- server/apps/api/src/community/community.service.ts | 4 +--- server/apps/api/src/community/dto/index.ts | 3 +++ server/apps/api/src/user/dto/index.ts | 4 ++++ server/apps/api/src/user/user.controller.ts | 3 +-- server/apps/api/src/user/user.service.ts | 4 +--- 6 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 server/apps/api/src/community/dto/index.ts create mode 100644 server/apps/api/src/user/dto/index.ts diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 09dc8dfd..9adeb89c 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -11,11 +11,9 @@ import { } from '@nestjs/common'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { CommunityService } from '@api/src/community/community.service'; -import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; import { responseForm } from '@utils/responseForm'; import { JwtAccessGuard } from '@api/src/auth/guard'; -import { AppendUsersToCommunityDto } from '@community/dto/append-particitants-to-community.dto'; -import { ModifyCommunityDto } from '@api/src/community/dto/modify-community.dto'; +import { CreateCommunityDto, AppendUsersToCommunityDto, ModifyCommunityDto } from './dto'; @Controller('api/community') export class CommunityController { diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 2d7b81eb..80d48054 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -1,9 +1,7 @@ import { BadRequestException, Injectable } from '@nestjs/common'; -import { CreateCommunityDto } from '@api/src/community/dto/create-community.dto'; import { CommunityRepository } from '@repository/community.repository'; import { UserRepository } from '@repository/user.repository'; -import { AppendUsersToCommunityDto } from '@api/src/community/dto/append-particitants-to-community.dto'; -import { ModifyCommunityDto } from '@api/src/community/dto/modify-community.dto'; +import { CreateCommunityDto, AppendUsersToCommunityDto, ModifyCommunityDto } from './dto'; @Injectable() export class CommunityService { diff --git a/server/apps/api/src/community/dto/index.ts b/server/apps/api/src/community/dto/index.ts new file mode 100644 index 00000000..c592ead6 --- /dev/null +++ b/server/apps/api/src/community/dto/index.ts @@ -0,0 +1,3 @@ +export * from './append-particitants-to-community.dto'; +export * from './create-community.dto'; +export * from './modify-community.dto'; diff --git a/server/apps/api/src/user/dto/index.ts b/server/apps/api/src/user/dto/index.ts new file mode 100644 index 00000000..c9dac182 --- /dev/null +++ b/server/apps/api/src/user/dto/index.ts @@ -0,0 +1,4 @@ +export * from './modify-user.dto'; +export * from './create-user.dto'; +export * from './follower.dto'; +export * from './user-basic-info.dto'; diff --git a/server/apps/api/src/user/user.controller.ts b/server/apps/api/src/user/user.controller.ts index 4cfa7e94..b2f3c814 100644 --- a/server/apps/api/src/user/user.controller.ts +++ b/server/apps/api/src/user/user.controller.ts @@ -13,12 +13,11 @@ import { UseGuards, } from '@nestjs/common'; import { UserService } from './user.service'; -import { FollowerDto } from '@user/dto/follower.dto'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { responseForm } from '@utils/responseForm'; import { ObjectIdValidationPipe } from '@custom_pipe/mongodbObjectIdValidation.pipe'; -import { ModifyUserDto } from '@user/dto/modify-user.dto'; import { JwtAccessGuard } from '@api/src/auth/guard'; +import { FollowerDto, ModifyUserDto } from './dto'; @Controller('api/user') export class UserController { diff --git a/server/apps/api/src/user/user.service.ts b/server/apps/api/src/user/user.service.ts index 32508f9b..2526a47c 100644 --- a/server/apps/api/src/user/user.service.ts +++ b/server/apps/api/src/user/user.service.ts @@ -1,8 +1,6 @@ import { BadRequestException, ConflictException, Injectable, Param } from '@nestjs/common'; -import { FollowerDto } from '@user/dto/follower.dto'; import { UserRepository } from '@repository/user.repository'; -import { getUserBasicInfo } from '@user/dto/user-basic-info.dto'; -import { ModifyUserDto } from '@user/dto/modify-user.dto'; +import { FollowerDto, ModifyUserDto, getUserBasicInfo } from './dto'; @Injectable() export class UserService { From ac25bd384b1a04000a5897284931bc8260d5cb6b Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 16:41:24 +0900 Subject: [PATCH 20/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20deletedAt=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20#110?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 26 ++++++++++++++- .../api/src/community/community.service.ts | 32 +++++++++++++++++-- .../src/community/dto/delete-community.dto.ts | 11 +++++++ server/apps/api/src/community/dto/index.ts | 1 + server/dao/repository/community.repository.ts | 8 +++-- server/dao/schemas/channel.schema.ts | 3 +- 6 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 server/apps/api/src/community/dto/delete-community.dto.ts diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 9adeb89c..8ccfa513 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -1,6 +1,7 @@ import { Body, Controller, + Delete, Inject, LoggerService, Param, @@ -13,7 +14,12 @@ import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { CommunityService } from '@api/src/community/community.service'; import { responseForm } from '@utils/responseForm'; import { JwtAccessGuard } from '@api/src/auth/guard'; -import { CreateCommunityDto, AppendUsersToCommunityDto, ModifyCommunityDto } from './dto'; +import { + CreateCommunityDto, + AppendUsersToCommunityDto, + ModifyCommunityDto, + DeleteCommunityDto, +} from './dto'; @Controller('api/community') export class CommunityController { @@ -85,4 +91,22 @@ export class CommunityController { throw error; // 이렇게하면 header status code 400 간다. } } + + @Delete(':_id') + @UseGuards(JwtAccessGuard) + async deleteCommunity(@Param('_id') community_id: string, @Req() req: any) { + try { + const managerId = req.user._id; + const deleteCommunityDto: DeleteCommunityDto = { managerId, community_id }; + const result = await this.communityService.deleteCommunity(deleteCommunityDto); + return responseForm(200, {}); + } catch (error) { + this.logger.error(JSON.stringify(error.response)); + if (process.env.NODE_ENV == 'prod') { + throw error; + } else { + return error.response; + } + } + } } diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 80d48054..8de4b670 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -1,7 +1,12 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { CommunityRepository } from '@repository/community.repository'; import { UserRepository } from '@repository/user.repository'; -import { CreateCommunityDto, AppendUsersToCommunityDto, ModifyCommunityDto } from './dto'; +import { + CreateCommunityDto, + AppendUsersToCommunityDto, + ModifyCommunityDto, + DeleteCommunityDto, +} from './dto'; @Injectable() export class CommunityService { @@ -26,13 +31,13 @@ export class CommunityService { `커뮤니티에 추가를 요청한 사용자 _id(${user_id})가 올바르지 않습니다.`, ); } - await this.userRepository.addArrAtArr({ _id: user_id }, 'communities', [ + await this.userRepository.addArrAtArr(user_id, 'communities', [ appendUsersToCommunityDto.community_id, ]); }), ); const community = await this.communityRepository.addArrAtArr( - { _id: appendUsersToCommunityDto.community_id }, + appendUsersToCommunityDto.community_id, 'users', appendUsersToCommunityDto.users, ); @@ -51,6 +56,7 @@ export class CommunityService { } async modifyCommunity(modifyCommunityDto: ModifyCommunityDto) { + // TODO : refactoring을 findAndUpdate로 해서 매니저 id, deletedAt인지 바로 검증이랑 동시에 하도록.. const community = await this.verfiyCommunity(modifyCommunityDto.community_id); if (community.managerId != modifyCommunityDto.managerId) { throw new BadRequestException('사용자의 커뮤니티 수정 권한이 없습니다.'); @@ -60,6 +66,26 @@ export class CommunityService { return await this.communityRepository.updateOne({ _id: community_id }, updateField); } + async deleteCommunity(deleteCommunityDto: DeleteCommunityDto) { + const updateField = { deletedAt: new Date() }; + let community = await this.communityRepository.findAndUpdateOne( + { + _id: deleteCommunityDto.community_id, + managerId: deleteCommunityDto.managerId, + deletedAt: { $exists: false }, + }, + updateField, + ); + if (!community) { + community = await this.verfiyCommunity(deleteCommunityDto.community_id); + if (community.managerId != deleteCommunityDto.managerId) { + throw new BadRequestException('사용자의 커뮤니티 수정 권한이 없습니다.'); + } else if (community.deletedAt) { + throw new BadRequestException('이미 삭제된 커뮤니티입니다.'); + } + } + return community; + } async verfiyCommunity(community_id: string) { const community = await this.communityRepository.findOne({ _id: community_id }); if (!community) { diff --git a/server/apps/api/src/community/dto/delete-community.dto.ts b/server/apps/api/src/community/dto/delete-community.dto.ts new file mode 100644 index 00000000..0ad34141 --- /dev/null +++ b/server/apps/api/src/community/dto/delete-community.dto.ts @@ -0,0 +1,11 @@ +import { IsNotEmpty, IsString } from 'class-validator'; + +export class DeleteCommunityDto { + @IsNotEmpty() + @IsString() + community_id: string; + + @IsNotEmpty() + @IsString() + managerId: string; +} diff --git a/server/apps/api/src/community/dto/index.ts b/server/apps/api/src/community/dto/index.ts index c592ead6..751dd193 100644 --- a/server/apps/api/src/community/dto/index.ts +++ b/server/apps/api/src/community/dto/index.ts @@ -1,3 +1,4 @@ export * from './append-particitants-to-community.dto'; export * from './create-community.dto'; export * from './modify-community.dto'; +export * from './delete-community.dto'; diff --git a/server/dao/repository/community.repository.ts b/server/dao/repository/community.repository.ts index 10e9706d..683299c2 100644 --- a/server/dao/repository/community.repository.ts +++ b/server/dao/repository/community.repository.ts @@ -17,10 +17,10 @@ export class CommunityRepository { return await this.communityModel.findById(_id); } - async addArrAtArr(filter, attribute, appendArr) { + async addArrAtArr(_id, attribute, appendArr) { const addArr = {}; addArr[attribute] = { $each: appendArr }; - return await this.communityModel.findOneAndUpdate(filter, { $addToSet: addArr }, { new: true }); + return await this.communityModel.findByIdAndUpdate(_id, { $addToSet: addArr }, { new: true }); } async findOne(condition: any) { @@ -30,4 +30,8 @@ export class CommunityRepository { async updateOne(filter, updateField) { await this.communityModel.updateOne(filter, updateField); } + + async findAndUpdateOne(filter, updateField) { + return await this.communityModel.findOneAndUpdate(filter, updateField, { new: true }); + } } diff --git a/server/dao/schemas/channel.schema.ts b/server/dao/schemas/channel.schema.ts index 605b3d0d..13e19274 100644 --- a/server/dao/schemas/channel.schema.ts +++ b/server/dao/schemas/channel.schema.ts @@ -1,7 +1,7 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import { Document } from 'mongoose'; import { CHANNEL_TYPE } from '@utils/def'; -import { IsBoolean, IsIn, IsNotEmpty, IsString } from 'class-validator'; +import { IsBoolean, IsIn, IsNotEmpty, IsString, Length } from 'class-validator'; export type ChannelDocument = Channel & Document; @@ -13,6 +13,7 @@ export class Channel { }) @IsString() @IsNotEmpty() + @Length(2, 20) name: string; @Prop({ From 5f6fef16d1515bb9595128334814a7419ad0b678 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 20:37:56 +0900 Subject: [PATCH 21/44] =?UTF-8?q?fix:=20guard=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=A0=95=EB=B3=B4=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=ED=9B=84=20=5Fid=20ObjectId=20->=20string=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/auth/strategy/jwt-access.strategy.ts | 2 +- .../api/src/community/community.service.ts | 20 ++++++++++++++++++- server/apps/api/src/user/user.controller.ts | 2 +- server/dao/repository/user.repository.ts | 6 +++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/server/apps/api/src/auth/strategy/jwt-access.strategy.ts b/server/apps/api/src/auth/strategy/jwt-access.strategy.ts index e890d211..e82bd868 100644 --- a/server/apps/api/src/auth/strategy/jwt-access.strategy.ts +++ b/server/apps/api/src/auth/strategy/jwt-access.strategy.ts @@ -19,6 +19,6 @@ export class JwtAccessStrategy extends PassportStrategy(Strategy, 'jwt-access-to throw new ForbiddenException('잘못된 요청입니다.'); } delete user.password; - return user; + return { ...user, _id: user._id.toString() }; } } diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 8de4b670..c61fae7f 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -16,10 +16,15 @@ export class CommunityService { ) {} async createCommunity(createCommunityDto: CreateCommunityDto) { - return await this.communityRepository.create({ + const community = await this.communityRepository.create({ ...createCommunityDto, users: [createCommunityDto.managerId], }); + await this.userRepository.appendElementAtArr( + { _id: createCommunityDto.managerId }, + { communities: community._id.toString() }, + ); + return community; } async appendParticipantsToCommunity(appendUsersToCommunityDto: AppendUsersToCommunityDto) { @@ -84,6 +89,11 @@ export class CommunityService { throw new BadRequestException('이미 삭제된 커뮤니티입니다.'); } } + await Promise.all( + community.users.map( + async (user_id) => await this.deleteCommunityAtUserDocument(user_id, community._id), + ), + ); return community; } async verfiyCommunity(community_id: string) { @@ -93,4 +103,12 @@ export class CommunityService { } return community; } + + async deleteCommunityAtUserDocument(user_id: string, community_id: string) { + console.log(user_id, typeof user_id); + const result = await this.userRepository.deleteElementAtArr2(user_id, { + communities: [community_id], + }); + console.log(result); + } } diff --git a/server/apps/api/src/user/user.controller.ts b/server/apps/api/src/user/user.controller.ts index b2f3c814..47957488 100644 --- a/server/apps/api/src/user/user.controller.ts +++ b/server/apps/api/src/user/user.controller.ts @@ -78,7 +78,7 @@ export class UserController { async getUser(@Param('id') id: string) { try { const result = await this.userService.getUser(id); - return responseForm(200, { result }); + return responseForm(200, { users: result }); } catch (error) { this.logger.error(JSON.stringify(error.response)); throw error; diff --git a/server/dao/repository/user.repository.ts b/server/dao/repository/user.repository.ts index a3720bb4..25345714 100644 --- a/server/dao/repository/user.repository.ts +++ b/server/dao/repository/user.repository.ts @@ -37,9 +37,13 @@ export class UserRepository { await this.userModel.updateOne(filter, { $pullAll: removeElement }); } + async deleteElementAtArr2(_id, removeElement) { + await this.userModel.findByIdAndUpdate(_id, { $pullAll: removeElement }, { new: true }); + } + async addArrAtArr(filter, attribute, appendArr) { const addArr = {}; addArr[attribute] = { $each: appendArr }; - return await this.userModel.findOneAndUpdate(filter, { $addToSet: addArr }, { new: true }); + return await this.userModel.findByIdAndUpdate(filter, { $addToSet: addArr }, { new: true }); } } From 4eacf1faeb08ea271744e5ca5092ff051f931d07 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 20:58:43 +0900 Subject: [PATCH 22/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20document=EC=97=90=EC=84=9C=EB=8F=84=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20#110?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 4 ++-- .../api/src/community/community.service.ts | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 8ccfa513..5ad00afe 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -98,8 +98,8 @@ export class CommunityController { try { const managerId = req.user._id; const deleteCommunityDto: DeleteCommunityDto = { managerId, community_id }; - const result = await this.communityService.deleteCommunity(deleteCommunityDto); - return responseForm(200, {}); + await this.communityService.deleteCommunity(deleteCommunityDto); + return responseForm(200, { message: '커뮤니티 삭제 성공' }); } catch (error) { this.logger.error(JSON.stringify(error.response)); if (process.env.NODE_ENV == 'prod') { diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index c61fae7f..fff2c7f4 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -90,11 +90,10 @@ export class CommunityService { } } await Promise.all( - community.users.map( - async (user_id) => await this.deleteCommunityAtUserDocument(user_id, community._id), + community.users.map((user_id) => + this.deleteCommunityAtUserDocument(user_id, community._id.toString()), ), ); - return community; } async verfiyCommunity(community_id: string) { const community = await this.communityRepository.findOne({ _id: community_id }); @@ -104,11 +103,12 @@ export class CommunityService { return community; } - async deleteCommunityAtUserDocument(user_id: string, community_id: string) { - console.log(user_id, typeof user_id); - const result = await this.userRepository.deleteElementAtArr2(user_id, { - communities: [community_id], - }); - console.log(result); + deleteCommunityAtUserDocument(user_id: string, community_id: string) { + this.userRepository.deleteElementAtArr( + { _id: user_id }, + { + communities: [community_id], + }, + ); } } From e51b4f8b4c39cbf36d351a30b071472ca88b0bc2 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 21:06:19 +0900 Subject: [PATCH 23/44] =?UTF-8?q?refactor:=20throw=20error=20=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=BC=EC=9B=90=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 28 +++---------------- server/apps/api/src/user/user.controller.ts | 13 --------- 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 5ad00afe..01b4cfba 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -40,29 +40,18 @@ export class CommunityController { return responseForm(200, result); } catch (error) { this.logger.error(JSON.stringify(error.response)); - if (process.env.NODE_ENV == 'prod') { - throw error; - } else { - return error.response; - } + throw error; } } @Post('participants') @UseGuards(JwtAccessGuard) async appendParticipantsToCommunity( - // @Param('community_id') community_id: string, - // @Body('users') users: string[], @Body() appendUsersToCommunityDto: AppendUsersToCommunityDto, @Req() req: any, ) { try { const _id = req.user._id; - // const appendUsersToCommunityDto: AppendUsersToCommunityDto = { - // requestUser_id: _id, - // community_id, - // }; - // console.log(users); const result = await this.communityService.appendParticipantsToCommunity({ ...appendUsersToCommunityDto, requestUser_id: _id, @@ -70,11 +59,7 @@ export class CommunityController { return responseForm(200, result); } catch (error) { this.logger.error(JSON.stringify(error.response)); - if (process.env.NODE_ENV == 'prod') { - throw error; - } else { - return error.response; - } + throw error; } } @@ -87,8 +72,7 @@ export class CommunityController { return responseForm(200, {}); } catch (error) { this.logger.error(JSON.stringify(error.response)); - // TODO : error response header status code 어떻게 할지 논의 - throw error; // 이렇게하면 header status code 400 간다. + throw error; } } @@ -102,11 +86,7 @@ export class CommunityController { return responseForm(200, { message: '커뮤니티 삭제 성공' }); } catch (error) { this.logger.error(JSON.stringify(error.response)); - if (process.env.NODE_ENV == 'prod') { - throw error; - } else { - return error.response; - } + throw error; } } } diff --git a/server/apps/api/src/user/user.controller.ts b/server/apps/api/src/user/user.controller.ts index 47957488..d077262a 100644 --- a/server/apps/api/src/user/user.controller.ts +++ b/server/apps/api/src/user/user.controller.ts @@ -26,13 +26,6 @@ export class UserController { private userService: UserService, ) {} - // @Get() - // getUsers() { - // const createUserDto: CreateUserDto = { id: 'mj', pw: 'mjpw' }; - // this.userService.createUser(createUserDto); - // return 'hello user'; - // } - @Post('following/:id') @UseGuards(JwtAccessGuard) async addFollowing(@Param('id', ObjectIdValidationPipe) id: string, @Req() req: any) { @@ -43,7 +36,6 @@ export class UserController { return responseForm(200, result); } catch (error) { this.logger.error(JSON.stringify(error.response)); - // res.status(400).json(error.response); throw error; } } @@ -97,9 +89,4 @@ export class UserController { throw error; } } - - // @Post() - // createUser(@Body() createUserDto: CreateUserDto) { - // this.usersService.createUser(createUserDto); - // } } From 9357a678058b2c062a193a1769fce06a49596168 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Wed, 23 Nov 2022 23:20:29 +0900 Subject: [PATCH 24/44] =?UTF-8?q?feat:=20=EB=82=B4=EA=B0=80=20=EC=86=8D?= =?UTF-8?q?=ED=95=9C=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EB=B0=9B=EC=95=84=EC=98=A4=EA=B8=B0=20#115?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/api/src/community/community.controller.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 01b4cfba..4e631dfc 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -2,6 +2,7 @@ import { Body, Controller, Delete, + Get, Inject, LoggerService, Param, @@ -89,4 +90,17 @@ export class CommunityController { throw error; } } + + @Get() + @UseGuards(JwtAccessGuard) + async getCommunities(@Req() req: any) { + try { + const _id = req.user._id; + const result = await this.communityService.getCommunities(_id); + return responseForm(200, result); + } catch (error) { + this.logger.error(JSON.stringify(error.response)); + throw error; + } + } } From 8d88b246664eca027e3fa12d5097b2d0954ef1fd Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Thu, 24 Nov 2022 15:45:37 +0900 Subject: [PATCH 25/44] =?UTF-8?q?feat:=20users=20schema=EC=9D=98=20communi?= =?UTF-8?q?ty=20innerschema=20=EC=88=98=EC=A0=95=20#115?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 24 +++++++++--------- .../api/src/community/community.service.ts | 7 +++--- server/dao/repository/user.repository.ts | 10 ++++++++ server/dao/schemas/user.schema.ts | 25 +++++++++++-------- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 4e631dfc..3acbb316 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -91,16 +91,16 @@ export class CommunityController { } } - @Get() - @UseGuards(JwtAccessGuard) - async getCommunities(@Req() req: any) { - try { - const _id = req.user._id; - const result = await this.communityService.getCommunities(_id); - return responseForm(200, result); - } catch (error) { - this.logger.error(JSON.stringify(error.response)); - throw error; - } - } + // @Get() + // @UseGuards(JwtAccessGuard) + // async getCommunities(@Req() req: any) { + // try { + // const _id = req.user._id; + // const result = await this.communityService.getCommunities(_id); + // return responseForm(200, result); + // } catch (error) { + // this.logger.error(JSON.stringify(error.response)); + // throw error; + // } + // } } diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index fff2c7f4..f025a0f7 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -20,10 +20,9 @@ export class CommunityService { ...createCommunityDto, users: [createCommunityDto.managerId], }); - await this.userRepository.appendElementAtArr( - { _id: createCommunityDto.managerId }, - { communities: community._id.toString() }, - ); + const newCommunity = {}; + newCommunity[`communities.${community._id.toString()}`] = { _id: community._id.toString() }; + await this.userRepository.updateObject({ _id: createCommunityDto.managerId }, newCommunity); return community; } diff --git a/server/dao/repository/user.repository.ts b/server/dao/repository/user.repository.ts index 25345714..80b27c65 100644 --- a/server/dao/repository/user.repository.ts +++ b/server/dao/repository/user.repository.ts @@ -33,6 +33,10 @@ export class UserRepository { await this.userModel.updateOne(filter, { $push: appendElement }); } + async updateObject(filter, appendElement) { + await this.userModel.updateOne(filter, { $set: appendElement }); + } + async deleteElementAtArr(filter, removeElement) { await this.userModel.updateOne(filter, { $pullAll: removeElement }); } @@ -46,4 +50,10 @@ export class UserRepository { addArr[attribute] = { $each: appendArr }; return await this.userModel.findByIdAndUpdate(filter, { $addToSet: addArr }, { new: true }); } + + // async set(filter, obj) { + // const user = new User(); + // + // this.userModel.find(filter).communities.set(); + // } } diff --git a/server/dao/schemas/user.schema.ts b/server/dao/schemas/user.schema.ts index b7ec5881..f534c365 100644 --- a/server/dao/schemas/user.schema.ts +++ b/server/dao/schemas/user.schema.ts @@ -1,11 +1,16 @@ -import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Prop, raw, Schema, SchemaFactory } from '@nestjs/mongoose'; import { IsIn, IsString } from 'class-validator'; import mongoose, { Document } from 'mongoose'; import { STATUS } from '@utils/def'; +const channels = { + _id: { type: String }, + lastRead: { type: Date, default: new Date() }, +}; + export type UserDocument = User & Document; -@Schema() +@Schema({ timestamps: true }) export class User { @Prop() name: string; @@ -49,12 +54,6 @@ export class User { @Prop({ default: new Date(), type: mongoose.Schema.Types.Date }) lastLogin: Date; - @Prop({ default: new Date(), type: mongoose.Schema.Types.Date }) - createdAt: Date; - - @Prop({ default: new Date(), type: mongoose.Schema.Types.Date }) - updatedAt: Date; - @Prop({ type: mongoose.Schema.Types.Date }) deletedAt: Date; @@ -66,7 +65,13 @@ export class User { @IsString() followers: string[]; - @Prop() - communities: string[]; + @Prop( + raw({ + type: Map, + of: new mongoose.Schema({ _id: { type: String }, channels: { type: Map, of: Date } }), + }), + ) + communities; //: { type: Map }; } + export const UserSchema = SchemaFactory.createForClass(User); From 46569bc2c29b9e7bcad07a400445d89f4144c626 Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Wed, 23 Nov 2022 16:50:18 +0900 Subject: [PATCH 26/44] =?UTF-8?q?feat:=20channel=20repository=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20channel=20moduel=EC=97=90=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/channel/channel.module.ts | 6 +++++- server/dao/repository/channel.repository.ts | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 server/dao/repository/channel.repository.ts diff --git a/server/apps/api/src/channel/channel.module.ts b/server/apps/api/src/channel/channel.module.ts index fe632c18..89431932 100644 --- a/server/apps/api/src/channel/channel.module.ts +++ b/server/apps/api/src/channel/channel.module.ts @@ -1,9 +1,13 @@ import { Module } from '@nestjs/common'; import { ChannelController } from './channel.controller'; import { ChannelService } from './channel.service'; +import { MongooseModule } from '@nestjs/mongoose'; +import { Community, CommunitySchema } from '@schemas/community.schema'; +import { ChannelRepository } from '@repository/channel.repository'; @Module({ + imports: [MongooseModule.forFeature([{ name: Community.name, schema: CommunitySchema }])], controllers: [ChannelController], - providers: [ChannelService] + providers: [ChannelService, ChannelRepository], }) export class ChannelModule {} diff --git a/server/dao/repository/channel.repository.ts b/server/dao/repository/channel.repository.ts new file mode 100644 index 00000000..d03e7eda --- /dev/null +++ b/server/dao/repository/channel.repository.ts @@ -0,0 +1,10 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { Channel } from 'diagnostics_channel'; +import { ChannelDocument } from '@schemas/channel.schema'; +import { Model } from 'mongoose'; + +@Injectable() +export class ChannelRepository { + constructor(@InjectModel(Channel.name) private communityModel: Model) {} +} From d1dc82c2f4d939614e94b3e4fb09ff13e9d931f6 Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Wed, 23 Nov 2022 21:05:34 +0900 Subject: [PATCH 27/44] =?UTF-8?q?feat:=20create-channel.dto=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/channel/dto/create-channel.dto.ts | 37 +++++++++++++++++++ server/apps/api/src/channel/dto/index.ts | 1 + 2 files changed, 38 insertions(+) create mode 100644 server/apps/api/src/channel/dto/create-channel.dto.ts create mode 100644 server/apps/api/src/channel/dto/index.ts diff --git a/server/apps/api/src/channel/dto/create-channel.dto.ts b/server/apps/api/src/channel/dto/create-channel.dto.ts new file mode 100644 index 00000000..95d020d5 --- /dev/null +++ b/server/apps/api/src/channel/dto/create-channel.dto.ts @@ -0,0 +1,37 @@ +import { IsBoolean, IsNotEmpty, IsOptional, IsString, Length } from 'class-validator'; +import { Transform } from 'class-transformer'; + +export class CreateChannelDto { + @IsString() + @IsNotEmpty() + communityId: string; + + @IsString() + @Length(2, 20) + @IsNotEmpty() + name: string; + + @IsString() + @IsOptional() + managerId: string; + + @IsString() + @IsOptional() + description: string; + + @IsString() + @IsOptional() + profileUrl: string; + + @IsString() + @IsNotEmpty() + type: 'Channel' | 'DM'; + + @IsBoolean() + @IsNotEmpty() + @Transform(({ value }) => value === 'true') + isPrivate: boolean; + + @IsOptional() + users: string[]; +} diff --git a/server/apps/api/src/channel/dto/index.ts b/server/apps/api/src/channel/dto/index.ts new file mode 100644 index 00000000..a21d4e9f --- /dev/null +++ b/server/apps/api/src/channel/dto/index.ts @@ -0,0 +1 @@ +export * from './create-channel.dto'; From a69ef30fb9ca16cae804b952fc9e1975fd157c2f Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Wed, 23 Nov 2022 21:07:35 +0900 Subject: [PATCH 28/44] =?UTF-8?q?fix:=20channel.schema=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - name: unique 옵션 제거 - communityId: unique 옵션 제거 - 같은 커뮤니티에서 이름이 같은 채널이 생기는 것은 service 레이어에서 예외처리 --- server/dao/schemas/channel.schema.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/dao/schemas/channel.schema.ts b/server/dao/schemas/channel.schema.ts index 13e19274..8894aacc 100644 --- a/server/dao/schemas/channel.schema.ts +++ b/server/dao/schemas/channel.schema.ts @@ -9,7 +9,6 @@ export type ChannelDocument = Channel & Document; export class Channel { @Prop({ required: true, - unique: true, }) @IsString() @IsNotEmpty() @@ -18,7 +17,6 @@ export class Channel { @Prop({ required: true, - unique: true, }) @IsString() communityId: string; From 60dae8d36b5b445bec2511d024674cb902f0e422 Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Thu, 24 Nov 2022 01:48:16 +0900 Subject: [PATCH 29/44] =?UTF-8?q?feat:=20=EC=B1=84=EB=84=90=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 생성시, managerId user정보에 communities 업데이트 필요 --- .../api/src/channel/channel.controller.ts | 29 +++++++++++++++++-- server/apps/api/src/channel/channel.module.ts | 15 ++++++++-- .../apps/api/src/channel/channel.service.ts | 29 +++++++++++++++++-- .../api/src/community/community.module.ts | 1 + server/dao/repository/channel.repository.ts | 14 +++++++-- server/dao/schemas/channel.schema.ts | 7 +++-- 6 files changed, 82 insertions(+), 13 deletions(-) diff --git a/server/apps/api/src/channel/channel.controller.ts b/server/apps/api/src/channel/channel.controller.ts index fff4d422..6fa995b6 100644 --- a/server/apps/api/src/channel/channel.controller.ts +++ b/server/apps/api/src/channel/channel.controller.ts @@ -1,4 +1,27 @@ -import { Controller } from '@nestjs/common'; +import { Body, Controller, Inject, LoggerService, Post, Req, UseGuards } from '@nestjs/common'; +import { ChannelService } from '@api/src/channel/channel.service'; +import { JwtAccessGuard } from '@api/src/auth/guard'; +import { CreateChannelDto } from '@api/src/channel/dto'; +import { responseForm } from '@utils/responseForm'; +import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; -@Controller('channel') -export class ChannelController {} +@Controller('api/channel') +export class ChannelController { + constructor( + @Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService, + private channelService: ChannelService, + ) {} + + @Post() + @UseGuards(JwtAccessGuard) + async createChannel(@Body() createChannelDto: CreateChannelDto, @Req() req: any) { + const _id = req.user._id; + try { + await this.channelService.createChannel({ ...createChannelDto, managerId: _id }); + return responseForm(200, { message: '채널 생성 성공!' }); + } catch (error) { + this.logger.error(JSON.stringify(error.response)); + throw error; + } + } +} diff --git a/server/apps/api/src/channel/channel.module.ts b/server/apps/api/src/channel/channel.module.ts index 89431932..6dd53985 100644 --- a/server/apps/api/src/channel/channel.module.ts +++ b/server/apps/api/src/channel/channel.module.ts @@ -2,12 +2,21 @@ import { Module } from '@nestjs/common'; import { ChannelController } from './channel.controller'; import { ChannelService } from './channel.service'; import { MongooseModule } from '@nestjs/mongoose'; -import { Community, CommunitySchema } from '@schemas/community.schema'; import { ChannelRepository } from '@repository/channel.repository'; +import { ChannelSchema } from '@schemas/channel.schema'; +import { Channel } from 'diagnostics_channel'; +import { CommunityRepository } from '@repository/community.repository'; +import { CommunityModule } from '@community/community.module'; +import { UserRepository } from '@repository/user.repository'; +import { UserModule } from '@user/user.module'; @Module({ - imports: [MongooseModule.forFeature([{ name: Community.name, schema: CommunitySchema }])], + imports: [ + MongooseModule.forFeature([{ name: Channel.name, schema: ChannelSchema }]), + CommunityModule, + UserModule, + ], controllers: [ChannelController], - providers: [ChannelService, ChannelRepository], + providers: [ChannelService, ChannelRepository, CommunityRepository, UserRepository], }) export class ChannelModule {} diff --git a/server/apps/api/src/channel/channel.service.ts b/server/apps/api/src/channel/channel.service.ts index fc8cd3a7..6d9ab62d 100644 --- a/server/apps/api/src/channel/channel.service.ts +++ b/server/apps/api/src/channel/channel.service.ts @@ -1,4 +1,29 @@ -import { Injectable } from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; +import { ChannelRepository } from '@repository/channel.repository'; +import { CreateChannelDto } from '@api/src/channel/dto'; +import { CommunityRepository } from '@repository/community.repository'; +import { UserRepository } from '@repository/user.repository'; @Injectable() -export class ChannelService {} +export class ChannelService { + constructor( + private readonly channelRepository: ChannelRepository, + private readonly communityRepository: CommunityRepository, + private readonly userRepository: UserRepository, + ) {} + async createChannel(createChannelDto: CreateChannelDto) { + const community = await this.communityRepository.findById(createChannelDto.communityId); + if (community === null) { + throw new BadRequestException('커뮤니티가 존재하지 않음'); + } + if (createChannelDto.name in community.channels) { + throw new BadRequestException('중복된 이름의 채널이 같은 커뮤니티에 있습니다.'); + } + const channel = await this.channelRepository.create({ + ...createChannelDto, + users: [createChannelDto.managerId], + }); + await this.communityRepository.addArrAtArr({ id: community.id }, 'channels', [channel._id]); + // // TODO: 유저 도큐먼트에 채널 추가 + } +} diff --git a/server/apps/api/src/community/community.module.ts b/server/apps/api/src/community/community.module.ts index e1949041..474dda22 100644 --- a/server/apps/api/src/community/community.module.ts +++ b/server/apps/api/src/community/community.module.ts @@ -14,5 +14,6 @@ import { UserModule } from '@user/user.module'; ], controllers: [CommunityController], providers: [CommunityService, CommunityRepository, UserRepository], + exports: [MongooseModule], }) export class CommunityModule {} diff --git a/server/dao/repository/channel.repository.ts b/server/dao/repository/channel.repository.ts index d03e7eda..fd182f90 100644 --- a/server/dao/repository/channel.repository.ts +++ b/server/dao/repository/channel.repository.ts @@ -1,10 +1,18 @@ import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; -import { Channel } from 'diagnostics_channel'; -import { ChannelDocument } from '@schemas/channel.schema'; import { Model } from 'mongoose'; +import { Channel, ChannelDocument } from '@schemas/channel.schema'; +import { CreateChannelDto } from '@api/src/channel/dto'; @Injectable() export class ChannelRepository { - constructor(@InjectModel(Channel.name) private communityModel: Model) {} + constructor(@InjectModel(Channel.name) private channelModel: Model) {} + + async create(createChannelDto: CreateChannelDto) { + return await this.channelModel.create(createChannelDto); + } + + async findOne(condition: any) { + return await this.channelModel.findOne(condition); + } } diff --git a/server/dao/schemas/channel.schema.ts b/server/dao/schemas/channel.schema.ts index 8894aacc..5f87951b 100644 --- a/server/dao/schemas/channel.schema.ts +++ b/server/dao/schemas/channel.schema.ts @@ -1,11 +1,11 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; -import { Document } from 'mongoose'; +import mongoose, { Document } from 'mongoose'; import { CHANNEL_TYPE } from '@utils/def'; import { IsBoolean, IsIn, IsNotEmpty, IsString, Length } from 'class-validator'; export type ChannelDocument = Channel & Document; -@Schema() +@Schema({ timestamps: true }) export class Channel { @Prop({ required: true, @@ -52,5 +52,8 @@ export class Channel { @Prop() @IsString() chatLists: string[]; + + @Prop({ type: mongoose.Schema.Types.Date }) + deletedAt: Date; } export const ChannelSchema = SchemaFactory.createForClass(Channel); From dab6911353e3d95391d442b8b017c23e2bf45bbe Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Thu, 24 Nov 2022 17:30:37 +0900 Subject: [PATCH 30/44] =?UTF-8?q?feat:=20=EC=B1=84=EB=84=90=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C,=20=EC=9C=A0=EC=A0=80=20=EB=8F=84?= =?UTF-8?q?=ED=81=90=EB=A8=BC=ED=8A=B8=EC=97=90=20=EC=B1=84=EB=84=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/channel/channel.service.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/apps/api/src/channel/channel.service.ts b/server/apps/api/src/channel/channel.service.ts index 6d9ab62d..62ec502b 100644 --- a/server/apps/api/src/channel/channel.service.ts +++ b/server/apps/api/src/channel/channel.service.ts @@ -23,7 +23,8 @@ export class ChannelService { ...createChannelDto, users: [createChannelDto.managerId], }); - await this.communityRepository.addArrAtArr({ id: community.id }, 'channels', [channel._id]); - // // TODO: 유저 도큐먼트에 채널 추가 + const newChannel = {}; + newChannel[`communities.${community._id.toString()}.channels.${channel._id}`] = new Date(); + await this.userRepository.updateObject({ _id: createChannelDto.managerId }, newChannel); } } From 5d6188d9666609ac14ed3e9b43da673d1fea3a0a Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Thu, 24 Nov 2022 17:34:21 +0900 Subject: [PATCH 31/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EB=AA=A9=EB=A1=9D=EC=97=90=20=EC=B1=84=EB=84=90=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=B0=8F=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/channel/channel.service.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server/apps/api/src/channel/channel.service.ts b/server/apps/api/src/channel/channel.service.ts index 62ec502b..483c4d92 100644 --- a/server/apps/api/src/channel/channel.service.ts +++ b/server/apps/api/src/channel/channel.service.ts @@ -11,7 +11,9 @@ export class ChannelService { private readonly communityRepository: CommunityRepository, private readonly userRepository: UserRepository, ) {} + async createChannel(createChannelDto: CreateChannelDto) { + // 자신이 속한 커뮤니티 찾기 const community = await this.communityRepository.findById(createChannelDto.communityId); if (community === null) { throw new BadRequestException('커뮤니티가 존재하지 않음'); @@ -19,12 +21,19 @@ export class ChannelService { if (createChannelDto.name in community.channels) { throw new BadRequestException('중복된 이름의 채널이 같은 커뮤니티에 있습니다.'); } + + // 채널 생성 const channel = await this.channelRepository.create({ ...createChannelDto, users: [createChannelDto.managerId], }); const newChannel = {}; newChannel[`communities.${community._id.toString()}.channels.${channel._id}`] = new Date(); + + // 커뮤니티 목록에 채널 업데이트 + await this.communityRepository.addArrAtArr({ id: community.id }, 'channels', [channel._id]); + + // 유저 목록에 자신이 속한 채널 업데이트 await this.userRepository.updateObject({ _id: createChannelDto.managerId }, newChannel); } } From 325e8a9cdaf9151c3882a49513795bb3fd382e26 Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Thu, 24 Nov 2022 18:00:05 +0900 Subject: [PATCH 32/44] =?UTF-8?q?fix:=20=EC=97=90=EB=9F=AC=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/api/src/channel/channel.service.ts | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/server/apps/api/src/channel/channel.service.ts b/server/apps/api/src/channel/channel.service.ts index 483c4d92..378728ff 100644 --- a/server/apps/api/src/channel/channel.service.ts +++ b/server/apps/api/src/channel/channel.service.ts @@ -14,26 +14,26 @@ export class ChannelService { async createChannel(createChannelDto: CreateChannelDto) { // 자신이 속한 커뮤니티 찾기 - const community = await this.communityRepository.findById(createChannelDto.communityId); - if (community === null) { - throw new BadRequestException('커뮤니티가 존재하지 않음'); - } - if (createChannelDto.name in community.channels) { - throw new BadRequestException('중복된 이름의 채널이 같은 커뮤니티에 있습니다.'); - } + try { + const community = await this.communityRepository.findById(createChannelDto.communityId); - // 채널 생성 - const channel = await this.channelRepository.create({ - ...createChannelDto, - users: [createChannelDto.managerId], - }); - const newChannel = {}; - newChannel[`communities.${community._id.toString()}.channels.${channel._id}`] = new Date(); + // 채널 생성 + const channel = await this.channelRepository.create({ + ...createChannelDto, + users: [createChannelDto.managerId], + }); - // 커뮤니티 목록에 채널 업데이트 - await this.communityRepository.addArrAtArr({ id: community.id }, 'channels', [channel._id]); + // 커뮤니티 목록에 채널 업데이트 + await this.communityRepository.addArrAtArr({ _id: community.id }, 'channels', [ + channel._id.toString(), + ]); - // 유저 목록에 자신이 속한 채널 업데이트 - await this.userRepository.updateObject({ _id: createChannelDto.managerId }, newChannel); + // 유저 목록에 자신이 속한 채널 업데이트 + const newChannel = {}; + newChannel[`communities.${community._id.toString()}.channels.${channel._id}`] = new Date(); + await this.userRepository.updateObject({ _id: createChannelDto.managerId }, newChannel); + } catch (error) { + throw new BadRequestException('채널 생성 중 오류 발생!'); + } } } From 969486dcdbf57b1e5a8316ace8bfc70ae6b216ae Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Fri, 25 Nov 2022 01:43:34 +0900 Subject: [PATCH 33/44] =?UTF-8?q?fix:=20channel.schema=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - manager: unique 속성 삭제 (사용자는 여러 채널의 관리자가 될 수 있다.) --- server/dao/schemas/channel.schema.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/server/dao/schemas/channel.schema.ts b/server/dao/schemas/channel.schema.ts index 5f87951b..5d77e202 100644 --- a/server/dao/schemas/channel.schema.ts +++ b/server/dao/schemas/channel.schema.ts @@ -23,7 +23,6 @@ export class Channel { @Prop({ required: true, - unique: true, }) @IsString() @IsNotEmpty() From b2eea183824ff79f96c506fcfafc53b2aef6d17b Mon Sep 17 00:00:00 2001 From: soomanbaek Date: Fri, 25 Nov 2022 01:47:50 +0900 Subject: [PATCH 34/44] =?UTF-8?q?refactor:=20User=EC=BB=AC=EB=A0=89?= =?UTF-8?q?=EC=85=98=20Community=ED=95=84=EB=93=9C=EC=97=90=20=EC=B1=84?= =?UTF-8?q?=EB=84=90=20=EC=B6=94=EA=B0=80=ED=95=B4=EC=A3=BC=EB=8A=94=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=EC=9D=84=20=EB=A7=8C=EB=93=9C=EB=8A=94=20?= =?UTF-8?q?=EA=B2=83=EC=9D=84=20=EB=AA=A8=EB=93=88=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/channel/channel.service.ts | 4 ++-- server/utils/addObjectForm.ts | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 server/utils/addObjectForm.ts diff --git a/server/apps/api/src/channel/channel.service.ts b/server/apps/api/src/channel/channel.service.ts index 378728ff..dd1dadc6 100644 --- a/server/apps/api/src/channel/channel.service.ts +++ b/server/apps/api/src/channel/channel.service.ts @@ -3,6 +3,7 @@ import { ChannelRepository } from '@repository/channel.repository'; import { CreateChannelDto } from '@api/src/channel/dto'; import { CommunityRepository } from '@repository/community.repository'; import { UserRepository } from '@repository/user.repository'; +import { addChannelToUserForm } from '@utils/addObjectForm'; @Injectable() export class ChannelService { @@ -29,8 +30,7 @@ export class ChannelService { ]); // 유저 목록에 자신이 속한 채널 업데이트 - const newChannel = {}; - newChannel[`communities.${community._id.toString()}.channels.${channel._id}`] = new Date(); + const newChannel = addChannelToUserForm(community._id, channel._id); await this.userRepository.updateObject({ _id: createChannelDto.managerId }, newChannel); } catch (error) { throw new BadRequestException('채널 생성 중 오류 발생!'); diff --git a/server/utils/addObjectForm.ts b/server/utils/addObjectForm.ts new file mode 100644 index 00000000..1514c0ed --- /dev/null +++ b/server/utils/addObjectForm.ts @@ -0,0 +1,6 @@ +export function addChannelToUserForm(communityId, channelId) { + const newChannel = {}; + newChannel[`communities.${communityId.toString()}.channels.${channelId.toString()}`] = new Date(); + + return newChannel; +} From 3131d038944269b71b965be3d308703e53356b46 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 01:29:58 +0900 Subject: [PATCH 35/44] =?UTF-8?q?refactor:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...o-community.dto.ts => append-participants-to-community.dto.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename server/apps/api/src/community/dto/{append-particitants-to-community.dto.ts => append-participants-to-community.dto.ts} (100%) diff --git a/server/apps/api/src/community/dto/append-particitants-to-community.dto.ts b/server/apps/api/src/community/dto/append-participants-to-community.dto.ts similarity index 100% rename from server/apps/api/src/community/dto/append-particitants-to-community.dto.ts rename to server/apps/api/src/community/dto/append-participants-to-community.dto.ts From 185e8d2853040725c17874661f66d3fa182020fd Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 01:30:49 +0900 Subject: [PATCH 36/44] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=8A=A4=ED=82=A4=EB=A7=88=20=EC=A3=BC=EC=84=9D=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/dao/schemas/user.schema.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/server/dao/schemas/user.schema.ts b/server/dao/schemas/user.schema.ts index f534c365..9c0597f3 100644 --- a/server/dao/schemas/user.schema.ts +++ b/server/dao/schemas/user.schema.ts @@ -3,11 +3,6 @@ import { IsIn, IsString } from 'class-validator'; import mongoose, { Document } from 'mongoose'; import { STATUS } from '@utils/def'; -const channels = { - _id: { type: String }, - lastRead: { type: Date, default: new Date() }, -}; - export type UserDocument = User & Document; @Schema({ timestamps: true }) @@ -71,7 +66,7 @@ export class User { of: new mongoose.Schema({ _id: { type: String }, channels: { type: Map, of: Date } }), }), ) - communities; //: { type: Map }; + communities; } export const UserSchema = SchemaFactory.createForClass(User); From eeee5a79420afe4811cca2286874a74cb7723bb9 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 01:31:07 +0900 Subject: [PATCH 37/44] =?UTF-8?q?refactor:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/community/dto/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/apps/api/src/community/dto/index.ts b/server/apps/api/src/community/dto/index.ts index 751dd193..a50668c8 100644 --- a/server/apps/api/src/community/dto/index.ts +++ b/server/apps/api/src/community/dto/index.ts @@ -1,4 +1,4 @@ -export * from './append-particitants-to-community.dto'; +export * from './append-participants-to-community.dto'; export * from './create-community.dto'; export * from './modify-community.dto'; export * from './delete-community.dto'; From 0c65e48c855fbe1a8da3871ccf46ba0085e8f98a Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 01:33:21 +0900 Subject: [PATCH 38/44] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20controller=20layer=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=20=EA=B0=92=20=EB=B3=80=EA=B2=BD=20#95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/community/community.controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 3acbb316..bfa59d28 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -53,11 +53,11 @@ export class CommunityController { ) { try { const _id = req.user._id; - const result = await this.communityService.appendParticipantsToCommunity({ + await this.communityService.appendParticipantsToCommunity({ ...appendUsersToCommunityDto, requestUser_id: _id, }); - return responseForm(200, result); + return responseForm(200, { message: '커뮤니티 사용자 추가 완료' }); } catch (error) { this.logger.error(JSON.stringify(error.response)); throw error; From b732d655eda8ec68c9178e4d3ff702be51e3acee Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 01:34:52 +0900 Subject: [PATCH 39/44] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20document=EC=97=90=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=8B=9C=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20#86,=20#95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/api/src/community/community.service.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index f025a0f7..6b92ae9e 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -20,13 +20,14 @@ export class CommunityService { ...createCommunityDto, users: [createCommunityDto.managerId], }); - const newCommunity = {}; - newCommunity[`communities.${community._id.toString()}`] = { _id: community._id.toString() }; + const newCommunity = this.makeCommunityObj(community._id.toString()); await this.userRepository.updateObject({ _id: createCommunityDto.managerId }, newCommunity); return community; } async appendParticipantsToCommunity(appendUsersToCommunityDto: AppendUsersToCommunityDto) { + const communityId = appendUsersToCommunityDto.community_id; + const newCommunity = this.makeCommunityObj(communityId); await Promise.all( appendUsersToCommunityDto.users.map(async (user_id) => { const user = await this.userRepository.findById(user_id); @@ -110,4 +111,13 @@ export class CommunityService { }, ); } + + makeCommunityObj(community_id: string) { + const newCommunity = {}; + newCommunity[`communities.${community_id}`] = { + _id: community_id, + channels: {}, + }; + return newCommunity; + } } From 5aeae6bceaadf9ba17d5236ed8e7d8c8a86ff292 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 01:36:58 +0900 Subject: [PATCH 40/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20=EC=86=8D=ED=95=9C=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EC=B6=94=EA=B0=80=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이미 커뮤니티 속해있는지 검증 - 사용자 검증 후 사용자 document update - 사용자 document 내부 커뮤니티 schema 변경에 대한 수정 --- .../api/src/community/community.service.ts | 24 ++++++++++++------- server/dao/repository/community.repository.ts | 5 ++-- server/dao/repository/user.repository.ts | 6 ++++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 6b92ae9e..7e68fd05 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -29,35 +29,41 @@ export class CommunityService { const communityId = appendUsersToCommunityDto.community_id; const newCommunity = this.makeCommunityObj(communityId); await Promise.all( + // 사용자 document 검증 (올바른 사용자인지, 해당 사용자가 이미 커뮤니티에 참여하고 있는건 아닌지) appendUsersToCommunityDto.users.map(async (user_id) => { const user = await this.userRepository.findById(user_id); if (!user) { throw new BadRequestException( `커뮤니티에 추가를 요청한 사용자 _id(${user_id})가 올바르지 않습니다.`, ); + } else if ( + (user.communities ?? false) && + Array.from(user.communities.keys()).includes(communityId) + ) { + throw new BadRequestException(`이미 커뮤니티에 추가된 사용자 입니다.`); } - await this.userRepository.addArrAtArr(user_id, 'communities', [ - appendUsersToCommunityDto.community_id, - ]); + }), + ); + await Promise.all( + // 사용자 document 검증이 끝난 후 update + appendUsersToCommunityDto.users.map(async (user_id) => { + await this.userRepository.updateObject({ _id: user_id }, newCommunity); }), ); const community = await this.communityRepository.addArrAtArr( - appendUsersToCommunityDto.community_id, + { _id: appendUsersToCommunityDto.community_id }, 'users', appendUsersToCommunityDto.users, ); if (!community) { await Promise.all( + // 사용자 document에서 다시 삭제 appendUsersToCommunityDto.users.map((user_id) => { - this.userRepository.deleteElementAtArr( - { _id: user_id }, - { communities: [appendUsersToCommunityDto.community_id] }, - ); + this.userRepository.deleteObject({ _id: user_id }, newCommunity); }), ); throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.'); } - return { message: '커뮤니티 사용자 추가 완료' }; } async modifyCommunity(modifyCommunityDto: ModifyCommunityDto) { diff --git a/server/dao/repository/community.repository.ts b/server/dao/repository/community.repository.ts index 683299c2..5376e0f5 100644 --- a/server/dao/repository/community.repository.ts +++ b/server/dao/repository/community.repository.ts @@ -17,10 +17,11 @@ export class CommunityRepository { return await this.communityModel.findById(_id); } - async addArrAtArr(_id, attribute, appendArr) { + async addArrAtArr(filter, attribute, appendArr) { const addArr = {}; addArr[attribute] = { $each: appendArr }; - return await this.communityModel.findByIdAndUpdate(_id, { $addToSet: addArr }, { new: true }); + return await this.communityModel.findOneAndUpdate(filter, { $addToSet: addArr }, { new: true }); + // console.log('pass'); } async findOne(condition: any) { diff --git a/server/dao/repository/user.repository.ts b/server/dao/repository/user.repository.ts index 80b27c65..66e7536d 100644 --- a/server/dao/repository/user.repository.ts +++ b/server/dao/repository/user.repository.ts @@ -34,7 +34,11 @@ export class UserRepository { } async updateObject(filter, appendElement) { - await this.userModel.updateOne(filter, { $set: appendElement }); + return await this.userModel.updateOne(filter, { $set: appendElement }); + } + + async deleteObject(filter, appendElement) { + await this.userModel.updateOne(filter, { $unset: appendElement }); } async deleteElementAtArr(filter, removeElement) { From 431b5f601953738244276f9a9a49ab6d9fa5e95b Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 02:12:17 +0900 Subject: [PATCH 41/44] =?UTF-8?q?feat:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EC=88=98=EC=A0=95=20=EC=9A=94=EC=B2=AD=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=EC=9D=98=20=EA=B6=8C=ED=95=9C=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20#95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/api/src/community/community.controller.ts | 9 ++++----- server/apps/api/src/community/community.service.ts | 14 +++++++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index bfa59d28..36ce17a1 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -52,11 +52,10 @@ export class CommunityController { @Req() req: any, ) { try { - const _id = req.user._id; - await this.communityService.appendParticipantsToCommunity({ - ...appendUsersToCommunityDto, - requestUser_id: _id, - }); + await this.communityService.appendParticipantsToCommunity( + req.user, + appendUsersToCommunityDto, + ); return responseForm(200, { message: '커뮤니티 사용자 추가 완료' }); } catch (error) { this.logger.error(JSON.stringify(error.response)); diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 7e68fd05..ca3770ec 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -7,6 +7,7 @@ import { ModifyCommunityDto, DeleteCommunityDto, } from './dto'; +import { IsUserInCommunity } from '@community/helper/checkUserIsInCommunity'; @Injectable() export class CommunityService { @@ -25,8 +26,14 @@ export class CommunityService { return community; } - async appendParticipantsToCommunity(appendUsersToCommunityDto: AppendUsersToCommunityDto) { + async appendParticipantsToCommunity( + reqUser, + appendUsersToCommunityDto: AppendUsersToCommunityDto, + ) { const communityId = appendUsersToCommunityDto.community_id; + if (!IsUserInCommunity(reqUser, communityId)) { + throw new BadRequestException(`커뮤니티에 속하지 않는 사용자는 요청할 수 없습니다.`); + } const newCommunity = this.makeCommunityObj(communityId); await Promise.all( // 사용자 document 검증 (올바른 사용자인지, 해당 사용자가 이미 커뮤니티에 참여하고 있는건 아닌지) @@ -36,10 +43,7 @@ export class CommunityService { throw new BadRequestException( `커뮤니티에 추가를 요청한 사용자 _id(${user_id})가 올바르지 않습니다.`, ); - } else if ( - (user.communities ?? false) && - Array.from(user.communities.keys()).includes(communityId) - ) { + } else if (IsUserInCommunity(user, communityId)) { throw new BadRequestException(`이미 커뮤니티에 추가된 사용자 입니다.`); } }), From f3d5a2ebbf25f5aebb84cdcdb74e90fbc7637175 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 02:19:49 +0900 Subject: [PATCH 42/44] =?UTF-8?q?refactor:=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=95=A8=EC=88=98=ED=99=94=20#95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/api/src/community/community.service.ts | 15 +++------------ .../community/helper/checkUserIsInCommunity.ts | 2 ++ server/apps/api/src/community/helper/index.ts | 2 ++ .../api/src/community/helper/makeCommunityObj.ts | 8 ++++++++ 4 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 server/apps/api/src/community/helper/checkUserIsInCommunity.ts create mode 100644 server/apps/api/src/community/helper/index.ts create mode 100644 server/apps/api/src/community/helper/makeCommunityObj.ts diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index ca3770ec..5ca93c80 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -7,7 +7,7 @@ import { ModifyCommunityDto, DeleteCommunityDto, } from './dto'; -import { IsUserInCommunity } from '@community/helper/checkUserIsInCommunity'; +import { IsUserInCommunity, makeCommunityObj } from '@community/helper'; @Injectable() export class CommunityService { @@ -21,7 +21,7 @@ export class CommunityService { ...createCommunityDto, users: [createCommunityDto.managerId], }); - const newCommunity = this.makeCommunityObj(community._id.toString()); + const newCommunity = makeCommunityObj(community._id.toString()); await this.userRepository.updateObject({ _id: createCommunityDto.managerId }, newCommunity); return community; } @@ -34,7 +34,7 @@ export class CommunityService { if (!IsUserInCommunity(reqUser, communityId)) { throw new BadRequestException(`커뮤니티에 속하지 않는 사용자는 요청할 수 없습니다.`); } - const newCommunity = this.makeCommunityObj(communityId); + const newCommunity = makeCommunityObj(communityId); await Promise.all( // 사용자 document 검증 (올바른 사용자인지, 해당 사용자가 이미 커뮤니티에 참여하고 있는건 아닌지) appendUsersToCommunityDto.users.map(async (user_id) => { @@ -121,13 +121,4 @@ export class CommunityService { }, ); } - - makeCommunityObj(community_id: string) { - const newCommunity = {}; - newCommunity[`communities.${community_id}`] = { - _id: community_id, - channels: {}, - }; - return newCommunity; - } } diff --git a/server/apps/api/src/community/helper/checkUserIsInCommunity.ts b/server/apps/api/src/community/helper/checkUserIsInCommunity.ts new file mode 100644 index 00000000..eb279d47 --- /dev/null +++ b/server/apps/api/src/community/helper/checkUserIsInCommunity.ts @@ -0,0 +1,2 @@ +export const IsUserInCommunity = (user, communityId) => + (user.communities ?? false) && Array.from(user.communities.keys()).includes(communityId); diff --git a/server/apps/api/src/community/helper/index.ts b/server/apps/api/src/community/helper/index.ts new file mode 100644 index 00000000..cd9c8465 --- /dev/null +++ b/server/apps/api/src/community/helper/index.ts @@ -0,0 +1,2 @@ +export * from './checkUserIsInCommunity'; +export * from './makeCommunityObj'; diff --git a/server/apps/api/src/community/helper/makeCommunityObj.ts b/server/apps/api/src/community/helper/makeCommunityObj.ts new file mode 100644 index 00000000..108db276 --- /dev/null +++ b/server/apps/api/src/community/helper/makeCommunityObj.ts @@ -0,0 +1,8 @@ +export const makeCommunityObj = (community_id: string) => { + const newCommunity = {}; + newCommunity[`communities.${community_id}`] = { + _id: community_id, + channels: {}, + }; + return newCommunity; +}; From 74dc0919c993c7fda2885654cfbc6986971d3428 Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 03:32:20 +0900 Subject: [PATCH 43/44] =?UTF-8?q?feat:=20=EC=9E=90=EC=8B=A0=EC=9D=98=20?= =?UTF-8?q?=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20=EB=B0=9B=EC=95=84?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20controller=20layer=20#115?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/src/community/community.controller.ts | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/server/apps/api/src/community/community.controller.ts b/server/apps/api/src/community/community.controller.ts index 36ce17a1..7fc975fc 100644 --- a/server/apps/api/src/community/community.controller.ts +++ b/server/apps/api/src/community/community.controller.ts @@ -29,6 +29,18 @@ export class CommunityController { private communityService: CommunityService, ) {} + @Get() + @UseGuards(JwtAccessGuard) + async getCommunities(@Req() req: any) { + try { + const result = await this.communityService.getCommunities(req.user._doc); + return responseForm(200, result); + } catch (error) { + this.logger.error(JSON.stringify(error.response)); + throw error; + } + } + @Post() @UseGuards(JwtAccessGuard) async crateCommunity(@Body() createCommunityDto: CreateCommunityDto, @Req() req: any) { @@ -69,7 +81,7 @@ export class CommunityController { try { const _id = req.user._id; await this.communityService.modifyCommunity({ ...modifyCommunityDto, managerId: _id }); - return responseForm(200, {}); + return responseForm(200, { message: '커뮤니티 정보 수정 완료' }); } catch (error) { this.logger.error(JSON.stringify(error.response)); throw error; @@ -89,17 +101,4 @@ export class CommunityController { throw error; } } - - // @Get() - // @UseGuards(JwtAccessGuard) - // async getCommunities(@Req() req: any) { - // try { - // const _id = req.user._id; - // const result = await this.communityService.getCommunities(_id); - // return responseForm(200, result); - // } catch (error) { - // this.logger.error(JSON.stringify(error.response)); - // throw error; - // } - // } } From d13a577db0f8bf59b19a7f7cf2e9d5e524be3dfd Mon Sep 17 00:00:00 2001 From: NaayoungKwon Date: Fri, 25 Nov 2022 03:35:37 +0900 Subject: [PATCH 44/44] =?UTF-8?q?feat:=20=EC=9E=90=EC=8B=A0=EC=9D=98=20?= =?UTF-8?q?=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20=EB=B0=9B=EC=95=84?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20service=20layer=201=EC=B0=A8=20#115?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 사용자 document에서 커뮤니티 정보를 받아옴 - 커뮤니티 id 별로 실제로 존재하는지 검증 - 사용자 document의 채널들이 각 커뮤니티에 속한 채널인지 확인 - 채널 별 유효한 채널인지 검증 - 최근 접근 시간과 마지막 message 전송 시간 비교 logic 구현 --- .../api/src/community/community.service.ts | 40 +++++++++++++++++++ .../api/src/user/dto/community-in-user.dto.ts | 4 ++ 2 files changed, 44 insertions(+) create mode 100644 server/apps/api/src/user/dto/community-in-user.dto.ts diff --git a/server/apps/api/src/community/community.service.ts b/server/apps/api/src/community/community.service.ts index 5ca93c80..1e0fc2d0 100644 --- a/server/apps/api/src/community/community.service.ts +++ b/server/apps/api/src/community/community.service.ts @@ -8,6 +8,7 @@ import { DeleteCommunityDto, } from './dto'; import { IsUserInCommunity, makeCommunityObj } from '@community/helper'; +import { communityInUser } from '@user/dto/community-in-user.dto'; @Injectable() export class CommunityService { @@ -16,6 +17,45 @@ export class CommunityService { private readonly userRepository: UserRepository, ) {} + async getCommunities(user2) { + const user = await this.userRepository.findById('637f2abb146636e4082885b1'); + const infos = []; + await Promise.all( + Array.from(user.communities.values()).map(async (userCommunity) => { + const { _id, channels } = userCommunity as communityInUser; + const community = await this.communityRepository.findById(_id); + if (!community) { + throw new BadRequestException('해당하는 커뮤니티의 _id가 올바르지 않습니다.'); + } + const result = Array.from(channels.keys()).filter( + (channel_id: string) => !community.channels.includes(channel_id), + ); + if (result.length > 0) { + console.log(result); + throw new BadRequestException('커뮤니티에 없는 비정상적인 채널이 존재합니다.'); + } + const info = {}; + info[_id] = []; + await Promise.all( + Array.from(channels.keys()).map(async (channelId) => { + const lastRead = channels.get(channelId); + console.log(lastRead); + // TODO: soft delete이면 조건 다시 설정 + // const channel = await this.channelRepository.findById(channelId); + // if (!channel) { + // throw new BadRequestException('존재하지 않는 채널입니다.'); + // } + // info[_id][channelId] = lastRead < channel.updatedAt; + // console.log(info[_id]); + }), + ); + console.log(info); + + infos.push(info); + }), + ); + return infos; + } async createCommunity(createCommunityDto: CreateCommunityDto) { const community = await this.communityRepository.create({ ...createCommunityDto, diff --git a/server/apps/api/src/user/dto/community-in-user.dto.ts b/server/apps/api/src/user/dto/community-in-user.dto.ts new file mode 100644 index 00000000..07a69aee --- /dev/null +++ b/server/apps/api/src/user/dto/community-in-user.dto.ts @@ -0,0 +1,4 @@ +export interface communityInUser { + _id: string; + channels?: Map; +}