Skip to content

Commit

Permalink
[BE] 예외 처리 및 스웨거 응답 부분 추가 (#134)
Browse files Browse the repository at this point in the history
* isnotempty 유효성 추가

* UsePipes 추가

* 여정 조회 알고리즘 변경

* 여정 조회 get 요청 추가

* 여정 종료 응답 스웨거 형식 지정, DTO 별도 생성

* 여정 조회 응답 스웨거 작성
  • Loading branch information
vvans authored Nov 30, 2023
1 parent 291bc86 commit 3e5e3a6
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 43 deletions.
77 changes: 70 additions & 7 deletions BE/musicspot/src/journey/controller/journey.controller.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import { Controller, Post, Body } from '@nestjs/common';
import {
Controller,
Post,
Body,
UsePipes,
ValidationPipe,
Get,
Query,
} from '@nestjs/common';
import { JourneyService } from '../service/journey.service';
import { StartJourneyDTO } from '.././dto/journeyStart.dto';
import { ApiCreatedResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import {
ApiBody,
ApiCreatedResponse,
ApiOperation,
ApiQuery,
ApiTags,
} from '@nestjs/swagger';
import { Journey } from '../schema/journey.schema';
import { EndJourneyDTO } from '.././dto/journeyEnd.dto';
import { RecordJourneyDTO } from '.././dto/journeyRecord.dto';
import { CheckJourneyDTO } from '../dto/journeyCheck.dto';
import { EndJourneyResponseDTO } from '../dto/journeyEndResponse.dto';
import { CheckJourneyResponseDTO } from '../dto/journeyCheckResponse.dto';

@Controller('journey')
@ApiTags('journey 관련 API')
Expand All @@ -14,23 +30,24 @@ export class JourneyController {

@ApiOperation({
summary: '여정 시작 API',
description: '여정 기록을 시작합니다..',
description: '여정 기록을 시작합니다.',
})
@ApiCreatedResponse({
description: '생성된 여정 데이터를 반환',
type: Journey,
})
@Post('start')
async create(@Body() startJourneyDTO: StartJourneyDTO) {
async create(@Body() startJourneyDTO: StartJourneyDTO): Promise<Journey> {
return await this.journeyService.create(startJourneyDTO);
}

@ApiOperation({
summary: '여정 종료 API',
description: '여정을 종료합니다.',
})
@ApiCreatedResponse({
description: '현재는 좌표 데이터의 길이를 반환, 추후 참 거짓으로 변경 예정',
type: Journey,
type: EndJourneyResponseDTO,
})
@Post('end')
async end(@Body() endJourneyDTO: EndJourneyDTO) {
Expand All @@ -55,12 +72,58 @@ export class JourneyController {
summary: '여정 조회 API',
description: '해당 범위 내의 여정들을 반환합니다.',
})
@ApiQuery({
name: 'userId',
description: '유저 ID',
required: true,
example: 'yourUserId',
})
@ApiQuery({
name: 'minCoordinate',
description: '최소 좌표',
required: true,
type: Number,
isArray: true,
example: [37.5, 127.0],
})
@ApiQuery({
name: 'maxCoordinate',
description: '최대 좌표',
required: true,
type: Number,
isArray: true,
example: [38.0, 128.0],
})
@ApiCreatedResponse({
description: '범위에 있는 여정의 기록들을 반환',
type: Journey,
type: CheckJourneyResponseDTO,
})
@Get('check')
@UsePipes(ValidationPipe)
async checkGet(
@Query('userId') userId: string,
@Query('minCoordinate') minCoordinate: number[],
@Query('maxCoordinate') maxCoordinate: number[],
) {
const checkJourneyDTO: CheckJourneyDTO = {
userId,
minCoordinate,
maxCoordinate,
};
return await this.journeyService.checkJourney(checkJourneyDTO);
}

@ApiOperation({
summary: '여정 조회 API',
description: '해당 범위 내의 여정들을 반환합니다.',
})
@ApiCreatedResponse({
description: '범위에 있는 여정의 기록들을 반환',
type: CheckJourneyResponseDTO,
})
@Post('check')
async check(@Body() checkJourneyDTO: CheckJourneyDTO) {
@UsePipes(ValidationPipe) //유효성 체크
async checkPost(@Body() checkJourneyDTO: CheckJourneyDTO) {
return await this.journeyService.checkJourney(checkJourneyDTO);
}
}
29 changes: 10 additions & 19 deletions BE/musicspot/src/journey/dto/journeyCheck.dto.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
import {
ArrayMaxSize,
ArrayMinSize,
IsArray,
IsNumber,
IsString,
} from 'class-validator';
import { IsNotEmpty, IsString } from 'class-validator';
import { IsCoordinate } from 'src/common/decorator/coordinate.decorator';

export class CheckJourneyDTO {
@IsNotEmpty()
@ApiProperty({
example: '655efda2fdc81cae36d20650',
description: '유저 id',
Expand All @@ -21,20 +17,15 @@ export class CheckJourneyDTO {
description: '위치 좌표',
required: true,
})
@IsArray()
@ArrayMaxSize(2, { message: 'coordinate has only 2' })
@ArrayMinSize(2, { message: 'coordinate has only 2' })
@IsNumber({}, { each: true })
@IsNotEmpty()
@IsCoordinate({
message: '배열의 각 요소는 양수여야 하고 두 개의 요소만 허용됩니다.',
})
readonly minCoordinate: number[];

@ApiProperty({
example: [37.555946, 126.972384],
description: '위치 좌표',
required: true,
@IsNotEmpty()
@IsCoordinate({
message: '배열의 각 요소는 양수여야 하고 두 개의 요소만 허용됩니다.',
})
@IsArray()
@ArrayMaxSize(2, { message: 'coordinate has only 2' })
@ArrayMinSize(2, { message: 'coordinate has only 2' })
@IsNumber({}, { each: true })
readonly maxCoordinate: number[];
}
30 changes: 30 additions & 0 deletions BE/musicspot/src/journey/dto/journeyCheckResponse.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ApiProperty } from '@nestjs/swagger';

export class JourneyDTO {
@ApiProperty({ description: '여정 ID', example: '65649c91380cafcab8869ed2' })
readonly _id: string;

@ApiProperty({ description: '여정 제목', example: '여정 제목' })
readonly title: string;

@ApiProperty({ description: 'spot 배열', example: [] })
readonly spots: string[];

@ApiProperty({
description: '위치 좌표 배열',
example: [
[37.775, 122.4195],
[37.7752, 122.4197],
[37.7754, 122.4199],
],
})
readonly coordinates: number[][];
}

export class CheckJourneyResponseDTO {
@ApiProperty({
type: [JourneyDTO],
description: '여정 데이터 배열',
})
readonly journeys: JourneyDTO[];
}
5 changes: 5 additions & 0 deletions BE/musicspot/src/journey/dto/journeyEnd.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export class EndJourneyDTO {
@IsDateString()
readonly timestamp: string;

@ApiProperty({
example: '여정 제목',
description: '여정 제목',
required: true,
})
@IsString()
readonly title: string;
}
44 changes: 44 additions & 0 deletions BE/musicspot/src/journey/dto/journeyEndResponse.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsDateString, IsArray, IsNotEmpty } from 'class-validator';
import { IsCoordinate } from '../../common/decorator/coordinate.decorator';
export class EndJourneyResponseDTO {
@ApiProperty({
example: '655efda2fdc81cae36d20650',
description: '여정 id',
required: true,
})
@IsString()
readonly journeyId: string;
@ApiProperty({
example: '여정 제목',
description: '여정 제목',
required: true,
})
@IsString()
readonly title: string;

@IsString({ each: true })
@IsNotEmpty()
@ApiProperty({
example: [
'655efda2fdc81cae36d20650',
'655efd902908e4514ae5ff9b',
'655efd27a08c7995defc8e91',
],
description: 'spot id 배열',
required: true,
})
readonly spots: string[];

@IsArray()
@IsNotEmpty()
@ApiProperty({
example: [
[37.674986, 126.776032],
[37.555946, 126.972384],
],
description: '위치 좌표 배열',
required: true,
})
readonly coordinates: number[][];
}
33 changes: 16 additions & 17 deletions BE/musicspot/src/journey/service/journey.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,22 @@ export class JourneyService {
let journeyList = [];
for (let i = 0; i < journeys.length; i++) {
let journey = await this.journeyModel.findById(journeys[i]).exec();
let minX = Infinity;
let minY = Infinity;
let maxX = -Infinity;
let maxY = -Infinity;
journey.coordinates.forEach(([x, y]) => {
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
});
if (
minX > minCoordinate[0] &&
minY > minCoordinate[1] &&
maxX < maxCoordinate[0] &&
maxY < maxCoordinate[1]
) {
journeyList.push(journey.coordinates);
let chk = true;
for (const [x, y] of journey.coordinates) {
if (
!(
x > minCoordinate[0] &&
y > minCoordinate[1] &&
x < maxCoordinate[0] &&
y < maxCoordinate[1]
)
) {
chk = false;
break;
}
}
if (chk) {
journeyList.push(journey);
}
}
return journeyList;
Expand Down

0 comments on commit 3e5e3a6

Please sign in to comment.