Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] 모각코 참가자 관련 로직 구현 및 Swagger 설정 #143

Merged
merged 4 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/backend/src/member/dto/member.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ export class MemberDto {
@ApiProperty({ description: 'Provider ID of the user', example: '123456' })
providerId: string;

@ApiProperty({ description: 'Email address of the user', example: 'user@example.com' })
@ApiProperty({ description: 'Email address of the user', example: 'bcwm.morak@gmail.com' })
email: string;

@ApiProperty({ description: 'Nickname of the user', example: 'john_doe' })
@ApiProperty({ description: 'Nickname of the user', example: 'morak morak' })
nickname: string;

@ApiProperty({ description: "URL of the user's profile picture", example: 'https://example.com/profile.jpg' })
Expand Down
3 changes: 2 additions & 1 deletion app/backend/src/member/member.controller.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Controller, Get, Req, Res, UnauthorizedException } from '@nestjs/common';
import { MemberService } from './member.service';
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Request, Response } from 'express';
import { MemberDto } from './dto/member.dto';

@ApiTags('Member Infomation API')
@Controller('member')
export class MemberController {
constructor(private readonly memberService: MemberService) {}
Expand Down
8 changes: 8 additions & 0 deletions app/backend/src/mogaco/dto/create-mogaco.dto.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import { IsDateString, IsEnum, IsInt, IsNotEmpty, IsOptional } from 'class-validator';
import { MogacoStatus } from './mogaco-status.enum';
import { ApiProperty } from '@nestjs/swagger';

export class CreateMogacoDto {
@ApiProperty({ description: 'Group ID', example: '1' })
@IsNotEmpty()
@IsInt()
groupId: number;

@ApiProperty({ description: 'Title of the Mogaco', example: '사당역 모각코' })
@IsNotEmpty()
title: string;

@ApiProperty({ description: 'Contents of the Mogaco', example: '사당역에서 모각코를 열려고 합니다.' })
@IsNotEmpty()
contents: string;

@ApiProperty({ description: 'Date of the Mogaco', example: '2023-11-25T12:00:00.000Z' })
@IsNotEmpty()
@IsDateString()
date: string;

@ApiProperty({ description: 'Maximum number of participants', example: 5 })
@IsNotEmpty()
maxHumanCount: number;

@ApiProperty({ description: 'Address of the Mogaco', example: '서울특별시 관악구 어디길 22 모락 카페' })
@IsNotEmpty()
address: string;

@ApiProperty({ description: 'Status of the Mogaco', example: '모집 중' })
@IsOptional()
@IsEnum(MogacoStatus, { message: 'Invalid status' })
status?: string;
Expand Down
22 changes: 22 additions & 0 deletions app/backend/src/mogaco/dto/mogaco.dto.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
import { ApiProperty } from '@nestjs/swagger';

export class MogacoDto {
@ApiProperty({ description: 'ID of the Mogaco', example: 1 })
id: bigint;

@ApiProperty({ description: 'Group ID', example: 1 })
groupId: bigint;

@ApiProperty({ description: 'Title of the Mogaco', example: '사당역 모각코' })
title: string;

@ApiProperty({ description: 'Contents of the Mogaco', example: '사당역에서 모각코를 열려고 합니다.' })
contents: string;

@ApiProperty({ description: 'Date of the Mogaco', example: '2023-11-22T12:00:00Z' })
date: Date;

@ApiProperty({ description: 'Maximum number of participants', example: 5 })
maxHumanCount: number;

@ApiProperty({ description: 'Address of the Mogaco', example: '서울특별시 관악구 어디길 22 모락 카페' })
address: string;

@ApiProperty({ description: 'Status of the Mogaco', example: '모집 중' })
status: string;
}

export class StatusDto {
@ApiProperty({ description: 'Status of the Mogaco', example: '모집 마감' })
status: string;
}
40 changes: 40 additions & 0 deletions app/backend/src/mogaco/dto/response-mogaco.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { ApiProperty } from '@nestjs/swagger';
import { MemberDto } from 'src/member/dto/member.dto';

export class MogacoWithMemberDto {
@ApiProperty({ description: 'ID of the Mogaco', example: '3' })
id: string;

@ApiProperty({ description: 'Group ID', example: '1' })
groupId: string;

@ApiProperty({ description: 'Title of the Mogaco', example: '사당역 모각코' })
title: string;

@ApiProperty({ description: 'Contents of the Mogaco', example: '사당역에서 모각코를 열려고 합니다.' })
contents: string;

@ApiProperty({ description: 'Date of the Mogaco', example: '2023-11-25T12:00:00.000Z' })
date: string;

@ApiProperty({ description: 'Maximum number of participants', example: 5 })
maxHumanCount: number;

@ApiProperty({ description: 'Address of the Mogaco', example: '서울특별시 관악구 어디길 22 모락 카페' })
address: string;

@ApiProperty({ description: 'Status of the Mogaco', example: '모집 마감' })
status: string;

@ApiProperty({ description: 'Date of Mogaco creation', example: '2023-11-22T12:16:08.913Z' })
createdAt: string;

@ApiProperty({ description: 'Date of Mogaco update', example: '2023-11-22T12:16:08.913Z' })
updatedAt: string;

@ApiProperty({ description: 'Date of Mogaco deletion', example: null })
deletedAt: string | null;

@ApiProperty({ description: 'Member information', type: MemberDto })
member: MemberDto;
}
18 changes: 18 additions & 0 deletions app/backend/src/mogaco/dto/response-participants.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ApiProperty } from '@nestjs/swagger';

export class ParticipantResponseDto {
@ApiProperty({ description: 'ID of the Member', example: '1' })
id: string;

@ApiProperty({ description: 'Provider ID', example: '117187214221556274884' })
providerId: string;

@ApiProperty({ description: 'Email of the Member', example: '[email protected]' })
email: string;

@ApiProperty({ description: 'Social Type', example: 'google' })
socialType: string;

@ApiProperty({ description: 'Date of Member creation', example: '2023-11-22T04:55:02.988Z' })
createdAt: string;
}
97 changes: 96 additions & 1 deletion app/backend/src/mogaco/mogaco.controller.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,137 @@
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, UseGuards } from '@nestjs/common';
import { MogacoService } from './mogaco.service';
import { Member, Mogaco } from '@prisma/client';
import { CreateMogacoDto, MogacoDto } from './dto';
import { CreateMogacoDto, MogacoDto, StatusDto } from './dto';
import { MogacoStatusValidationPipe } from './pipes/mogaco-status-validation.pipe';
import { MogacoStatus } from './dto/mogaco-status.enum';
import { GetUser } from 'libs/decorators/get-user.decorator';
import { AtGuard } from 'src/auth/guards/at.guard';
import { ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
import { MogacoWithMemberDto } from './dto/response-mogaco.dto';
import { ParticipantResponseDto } from './dto/response-participants.dto';

@ApiTags('Mogaco API')
@Controller('mogaco')
@UseGuards(AtGuard)
export class MogacoController {
constructor(private readonly mogacoService: MogacoService) {}

@Get('/')
@ApiOperation({
summary: '모든 모각코 조회',
description: '존재하는 모든 모각코를 조회합니다.\n 배열로 여러 개를 반환합니다.',
})
@ApiResponse({ status: 200, description: 'Successfully retrieved', type: [MogacoDto] })
@ApiResponse({ status: 401, description: 'Unauthorized' })
async getAllMogaco(): Promise<Mogaco[]> {
return this.mogacoService.getAllMogaco();
}

@Get('/:id')
@ApiOperation({
summary: '특정 게시물 조회',
description: '특정 게시물의 Id 값으로 해당 게시물을 조회합니다.',
})
@ApiParam({ name: 'id', description: '조회할 모각코의 Id' })
@ApiResponse({ status: 200, description: 'Successfully retrieved', type: MogacoDto })
@ApiResponse({ status: 401, description: 'Unauthorized' })
async getMogacoById(@Param('id', ParseIntPipe) id: number): Promise<MogacoDto> {
return this.mogacoService.getMogacoById(id);
}

@Post('/')
@ApiOperation({
summary: '모각코 개설',
description: '새로운 모각코를 개설합니다.',
})
@ApiBody({ type: CreateMogacoDto })
@ApiResponse({ status: 201, description: 'Successfully created', type: MogacoWithMemberDto })
@ApiResponse({ status: 401, description: 'Unauthorized' })
async createMogaco(@Body() createMogacoDto: CreateMogacoDto, @GetUser() member: Member): Promise<Mogaco> {
return this.mogacoService.createMogaco(createMogacoDto, member);
}

@Delete('/:id')
@ApiOperation({
summary: '모각코 삭제',
description: '특정 모각코를 삭제합니다.',
})
@ApiParam({ name: 'id', description: '삭제할 모각코의 Id' })
@ApiResponse({ status: 200, description: 'Successfully deleted' })
@ApiResponse({ status: 401, description: 'Unauthorized' })
@ApiResponse({ status: 403, description: 'Forbidden' })
async deleteMogaco(@Param('id', ParseIntPipe) id: number, @GetUser() member: Member): Promise<void> {
return this.mogacoService.deleteMogaco(id, member);
}

@Patch('/:id/status')
@ApiOperation({
summary: '모각코 상태 업데이트',
description: '특정 모각코의 상태를 업데이트합니다.',
})
@ApiParam({ name: 'id', description: '상태를 업데이트할 모각코의 Id' })
@ApiBody({ type: StatusDto })
@ApiResponse({ status: 200, description: 'Successfully Updated', type: MogacoWithMemberDto })
@ApiResponse({ status: 401, description: 'Unauthorized' })
updateMogacoStatus(
@Param('id', ParseIntPipe) id: number,
@Body('status', MogacoStatusValidationPipe) status: MogacoStatus,
): Promise<Mogaco> {
return this.mogacoService.updateMogacoStatus(id, status);
}

@Patch('/:id')
@ApiOperation({
summary: '모각코 수정',
description: '특정 모각코를 수정합니다.',
})
@ApiParam({ name: 'id', description: '수정할 모각코의 Id' })
@ApiBody({ type: CreateMogacoDto })
@ApiResponse({ status: 200, description: 'Successfully updated', type: MogacoWithMemberDto })
@ApiResponse({ status: 401, description: 'Unauthorized' })
@ApiResponse({ status: 403, description: 'Forbidden' })
async updateMogaco(
@Param('id', ParseIntPipe) id: number,
@Body() updateMogacoDto: CreateMogacoDto,
@GetUser() member: Member,
): Promise<Mogaco> {
return this.mogacoService.updateMogaco(id, updateMogacoDto, member);
}

@Post('/:id/join')
@ApiOperation({
summary: '모각코 참가',
description: '특정 모각코에 참가합니다.',
})
@ApiParam({ name: 'id', description: '참가할 모각코의 Id' })
@ApiResponse({ status: 201, description: 'Successfully join' })
@ApiResponse({ status: 401, description: 'Unauthorized' })
async joinMogaco(@Param('id', ParseIntPipe) id: number, @GetUser() member: Member): Promise<void> {
return this.mogacoService.joinMogaco(id, member);
}

@Get('/:id/participants')
@ApiOperation({
summary: '참가자 목록 조회',
description: '특정 모각코에 참가한 모든 참가자 목록을 조회합니다.',
})
@ApiParam({ name: 'id', description: '참가자 목록을 조회할 모각코의 Id' })
@ApiResponse({ status: 200, description: 'Successfully retrieved', type: [ParticipantResponseDto] })
@ApiResponse({ status: 401, description: 'Unauthorized' })
async getParticipants(@Param('id', ParseIntPipe) id: number): Promise<Member[]> {
return this.mogacoService.getParticipants(id);
}

@Delete('/:id/join')
@ApiOperation({
summary: '모각코 참가 취소',
description: '특정 모각코 참가를 취소합니다.',
})
@ApiParam({ name: 'id', description: '참가를 취소할 모각코의 Id' })
@ApiResponse({ status: 200, description: 'Successfully cancelled join' })
@ApiResponse({ status: 401, description: 'Unauthorized' })
@ApiResponse({ status: 403, description: 'Forbidden' })
async cancelMogacoJoin(@Param('id', ParseIntPipe) id: number, @GetUser() member: Member): Promise<void> {
return this.mogacoService.cancelMogacoJoin(id, member);
}
}
Loading