Skip to content

Commit

Permalink
feat: swagger 설정 및 api 추가 (#9)
Browse files Browse the repository at this point in the history
* feat: 유저 게임 불러오기 api 추가

* feat: 게임 삭제 api 추가

* feat: 댓글 좋아요 및 좋아요 취소 api 추가

* fix: create-comment dto 수정 및 body 데코레이터 추가

* fix: create-game dto 수정

* fix: ParseIntPipe 추가

* feat: likeCount 추가

* feat: CommentDto 추가

* feat: find comment에likeCount 추가

* chore: swagger ApiProperty 설정 추가

* feat: swagger 설정 및 response dto 추가
  • Loading branch information
Hellol77 authored Sep 24, 2024
1 parent 0e2e6f6 commit 7b02958
Show file tree
Hide file tree
Showing 23 changed files with 460 additions and 44 deletions.
Binary file modified backend/.yarn/install-state.gz
Binary file not shown.
3 changes: 3 additions & 0 deletions backend/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@ import {
UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { Request, Response } from 'express';
import { AuthService } from 'src/auth/auth.service';

@Controller('auth')
@ApiTags('인증 api')
export class AuthController {
private logger = new Logger('GameController');

constructor(private readonly authService: AuthService) {}

@Get('kakao')
@ApiOperation({ summary: '카카오 로그인' })
@UseGuards(AuthGuard('kakao'))
@HttpCode(301)
async kakaoLogin(@Req() req: Request, @Res() res: Response) {
Expand Down
18 changes: 9 additions & 9 deletions backend/src/comment/comment.controller.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import { Controller, Delete, Post, Req, UseGuards } from '@nestjs/common';
import { Body, Controller, Delete, Post, Req, UseGuards } from '@nestjs/common';
import { CommentService } from './comment.service';
import { CreateCommentDto } from 'src/comment/dto/create-comment.dto';
import { Comment } from 'src/comment/comment.entity';
import { AuthGuard } from '@nestjs/passport';
import { Request } from 'express';
import { DeleteCommentDto } from 'src/comment/dto/delete-comment.dto';
import { ApiOperation, ApiTags } from '@nestjs/swagger';

@Controller('comment')
@ApiTags('댓글 api')
export class CommentController {
constructor(private readonly commentService: CommentService) {}

@UseGuards(AuthGuard('jwt'))
@Post()
@ApiOperation({ summary: '아이템에 댓글을 입력합니다.' })
async createComment(
@Req() req: Request,
createCommentDto: CreateCommentDto,
): Promise<Comment> {
@Body() createCommentDto: CreateCommentDto,
): Promise<void> {
const kakaoId = req.user.kakaoId;
return this.commentService.createComment({
...createCommentDto,
user_id: kakaoId,
});
return this.commentService.createComment(kakaoId, createCommentDto);
}

@UseGuards(AuthGuard('jwt'))
@Delete()
@ApiOperation({ summary: '아이템에 댓글을 삭제합니다.' })
async deleteComment(
@Req() req: Request,
deleteCommentDto: DeleteCommentDto,
@Body() deleteCommentDto: DeleteCommentDto,
): Promise<void> {
const kakaoId = req.user.kakaoId;
return this.commentService.deleteComment(kakaoId, deleteCommentDto);
Expand Down
15 changes: 11 additions & 4 deletions backend/src/comment/comment.entity.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import { ApiProperty } from '@nestjs/swagger';
import { Item } from 'src/item/item.entity';
import { Like } from 'src/like/like.entity';
import { User } from 'src/user/user.entity';
import {
Entity,
PrimaryGeneratedColumn,
Expand All @@ -12,6 +8,10 @@ import {
UpdateDateColumn,
JoinColumn,
} from 'typeorm';
import { ApiProperty } from '@nestjs/swagger';
import { Item } from 'src/item/item.entity';
import { Like } from 'src/like/like.entity';
import { User } from 'src/user/user.entity';

@Entity()
export class Comment {
Expand Down Expand Up @@ -65,4 +65,11 @@ export class Comment {
type: () => [Like],
})
likes: Like[];

@Column({ default: 0 })
@ApiProperty({
description: '댓글에 달린 좋아요 수',
example: 10,
})
likeCount: number; // 좋아요 수를 저장하는 필드 추가
}
12 changes: 8 additions & 4 deletions backend/src/comment/comment.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,32 @@ export class CommentService {
'created_at',
'updated_at',
'user',
'likeCount',
],
});
}

async createComment(createCommentDto: CreateCommentDto): Promise<Comment> {
const { user_id, comment_text, item_id } = createCommentDto;
async createComment(
userId: number,
createCommentDto: CreateCommentDto,
): Promise<void> {
const { comment_text, item_id } = createCommentDto;

const comment = new Comment();
const item = new Item();
const user = new User();

item.item_id = item_id;
comment.item = item;
user.user_id = user_id;
user.user_id = userId;

comment.user = user;
comment.comment_text = comment_text;

comment.created_at = new Date();
comment.updated_at = new Date();

return this.commentsRepository.save(comment);
await this.commentsRepository.save(comment);
}

async deleteComment(
Expand Down
10 changes: 10 additions & 0 deletions backend/src/comment/dto/comment.dto.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty } from 'class-validator';

export class CommentDto {
@IsNotEmpty()
@ApiProperty({ description: 'The ID of the comment' })
comment_id: number;

@IsNotEmpty()
@ApiProperty({ description: 'The text of the comment' })
comment_text: string;

@IsNotEmpty()
@ApiProperty({ description: 'The date when the comment was created' })
created_at: Date;

@IsNotEmpty()
@ApiProperty({ description: 'The date when the comment was last updated' })
updated_at: Date;

@IsNotEmpty()
@ApiProperty({ description: 'The user who made the comment', type: String })
user: string;

@IsNotEmpty()
@ApiProperty({ description: 'The number of likes the comment has received' })
likeCount: number;
}
3 changes: 0 additions & 3 deletions backend/src/comment/dto/create-comment.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ export class CreateCommentDto {
@IsNotEmpty()
comment_text: string;

@IsNotEmpty()
user_id: number;

@IsNotEmpty()
item_id: number;
}
3 changes: 0 additions & 3 deletions backend/src/game/dto/create-game.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,4 @@ export class CreateGameDto {

@IsNotEmpty()
secondItemText: string;

@IsNotEmpty()
user_id: number;
}
24 changes: 24 additions & 0 deletions backend/src/game/dto/game.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty } from 'class-validator';

export class GameDto {
@IsNotEmpty()
@ApiProperty({ description: 'The ID of the game' })
game_id: number;

@IsNotEmpty()
@ApiProperty({ description: 'First item text' })
first_item_text: string;

@IsNotEmpty()
@ApiProperty({ description: 'Second item text' })
second_item_text: string;

@IsNotEmpty()
@ApiProperty({ description: 'Created date' })
created_at: Date;

@IsNotEmpty()
@ApiProperty({ description: 'The user who made the game', type: Number })
user_id: number;
}
10 changes: 10 additions & 0 deletions backend/src/game/dto/gameResponse.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ApiProperty } from '@nestjs/swagger';
import { GameDto } from 'src/game/dto/game.dto';

export class GameResponseDto {
@ApiProperty({ type: [GameDto], description: '게임 데이터 목록' })
data: GameDto[];

@ApiProperty({ description: '전체 게임 수', example: 100 })
total: number;
}
57 changes: 51 additions & 6 deletions backend/src/game/game.controller.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,95 @@
import {
Body,
Controller,
Delete,
Get,
Logger,
Param,
ParseIntPipe,
Post,
Query,
Req,
UseGuards,
} from '@nestjs/common';
import { GameService } from './game.service';
import { Game } from 'src/game/game.entity';
import { CreateGameDto } from 'src/game/dto/create-game.dto';
import { AuthGuard } from '@nestjs/passport';
import { Item } from 'src/item/item.entity';
import { Request } from 'express';
import { ApiCreatedResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { GameResponseDto } from 'src/game/dto/gameResponse.dto';
import { ItemsResponseDto } from 'src/item/dto/itemsResponse.dto';
import { GameDto } from 'src/game/dto/game.dto';

@Controller('game')
@ApiTags('게임 api')
export class GameController {
private logger = new Logger('GameController');
constructor(private readonly gameService: GameService) {}

@Get()
@ApiOperation({ summary: '모든 게임들을 불러옵니다.' })
@ApiCreatedResponse({
description: '모든 게임들을 불러옵니다.',
type: GameResponseDto,
})
async findAll(
@Query('page') page: number = 1, // 페이지 번호
@Query('limit') limit: number = 10, // 페이지당 항목 수
): Promise<{ data: Game[]; total: number }> {
): Promise<GameResponseDto> {
this.logger.log('Handling Find All Games request');
const games = await this.gameService.findAll({ page, limit });
const total = await this.gameService.countGames(); // 전체 게임 수 계산
return { data: games, total };
}

@Get(':game_id/items')
async getItemsByGameId(@Param('game_id') game_id: number): Promise<Item[]> {
@ApiOperation({ summary: '게임의 아이템들을 모두 가져옵니다.' })
@ApiCreatedResponse({
description: '게임의 아이템들을 모두 가져옵니다.',
type: ItemsResponseDto,
})
async getItemsByGameId(
@Param('game_id') game_id: number,
): Promise<ItemsResponseDto> {
return this.gameService.findItemsByGameId(game_id);
}

@UseGuards(AuthGuard('jwt'))
@Post()
@ApiOperation({ summary: '자신의 게임을 생성합니다.' })
async createGame(
@Req() req: Request,
@Body() createGameDto: CreateGameDto,
): Promise<Game> {
): Promise<void> {
const kakaoId = req.user.kakaoId;
this.logger.log('Handling create game');
return this.gameService.createGame({ ...createGameDto, user_id: kakaoId });
return this.gameService.createGame(kakaoId, createGameDto);
}

@UseGuards(AuthGuard('jwt'))
@Get('user')
@ApiOperation({ summary: '사용자가 만든 게임들을 가져옵니다.' })
@ApiCreatedResponse({
description: '자신이 만든 게임들을 가져옵니다.',
type: [GameDto],
})
async findGamesByUserId(
@Req() req: Request,
@Query('page') page: number = 1, // 페이지 번호
@Query('limit') limit: number = 10, // 페이지당 항목 수
): Promise<GameDto[]> {
const kakaoId = req.user.kakaoId;
return this.gameService.findGamesByUserId(kakaoId, page, limit);
}

@UseGuards(AuthGuard('jwt'))
@Delete(':game_id')
@ApiOperation({ summary: '자신의 게임을 삭제합니다.' })
async deleteGame(
@Req() req: Request,
@Param('game_id', ParseIntPipe) game_id: number,
): Promise<void> {
const kakaoId = req.user.kakaoId;
return this.gameService.deleteGame(kakaoId, game_id);
}
}
14 changes: 14 additions & 0 deletions backend/src/game/game.entity.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ApiProperty } from '@nestjs/swagger';
import { Item } from 'src/item/item.entity';
import { User } from 'src/user/user.entity';
import {
Expand All @@ -12,15 +13,28 @@ import {
@Entity()
export class Game {
@PrimaryGeneratedColumn()
@ApiProperty({ description: '게임의 id', example: 1 })
game_id: number;

@CreateDateColumn()
@ApiProperty({
description: '게임이 생성된 날짜와 시간',
example: '2024-09-21T10:20:30Z',
})
created_at: Date;

@ManyToOne(() => User, (user) => user.games, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'user_id' }) // 외래 키 이름을 'game_id'로 명시적으로 설정
@ApiProperty({
description: '게임을 만든 사용자',
type: () => User,
})
user: User;

@OneToMany(() => Item, (item) => item.game)
@ApiProperty({
description: '게임에 포함된 아이템들',
type: () => [Item],
})
items: Item[];
}
Loading

0 comments on commit 7b02958

Please sign in to comment.