Skip to content

Commit 161eee6

Browse files
committed
2 parents 717bd2e + 4cee3ce commit 161eee6

File tree

4 files changed

+112
-4
lines changed

4 files changed

+112
-4
lines changed
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsInt, IsString, IsIn } from 'class-validator';
3+
4+
export class PatchMatchingRequestDto {
5+
@ApiProperty({ example: 1, description: '매칭 ID' })
6+
@IsInt()
7+
matchingId: number;
8+
9+
@ApiProperty({ example: 1, description: '신청한 유저 아이디' })
10+
@IsInt()
11+
requesterId: number;
12+
13+
@ApiProperty({ example: 2, description: '매칭 상대 유저 아이디' })
14+
@IsInt()
15+
targetId: number;
16+
17+
@ApiProperty({
18+
example: 'accept',
19+
enum: ['accept', 'reject'],
20+
description: '수락 또는 거절',
21+
})
22+
@IsString()
23+
@IsIn(['accept', 'reject'])
24+
action: 'accept' | 'reject';
25+
}

src/matching/matching.controller.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ import { UserService } from 'src/user/user.service';
2121
import { Request } from 'express';
2222
import {
2323
DataNotFoundException,
24+
InternalServerException,
2425
UnauthorizedException,
2526
} from 'src/common/exception/service.exception';
2627
import { BaseResponse } from 'src/common/response/dto';
2728
import { PostMatchingResponse } from './dto/matching.response';
2829
import { AuthGuard } from 'src/auth/guards/jwt.auth.guard';
30+
import { PatchMatchingRequestDto } from './dto/Patch-matching.request';
2931

3032
@ApiBearerAuth('Authorization')
3133
@Controller('matching')
@@ -58,9 +60,25 @@ export class MatchingController {
5860
}
5961

6062
@Patch()
63+
@UseGuards(AuthGuard)
6164
@PatchMatchingRequestStatusSwagger('매칭 요청 수락 및 거절 API')
62-
patchMatchingRequestStatus() {
63-
// return this.userService.getHello();
65+
async patchMatchingRequestStatus(
66+
@Req() req: Request,
67+
@Body() body: PatchMatchingRequestDto,
68+
): Promise<BaseResponse<any>> {
69+
if (req.user.id !== body.targetId) {
70+
throw UnauthorizedException('권한이 없습니다.');
71+
}
72+
73+
if (
74+
(await this.matchingService.getMatchingById(body.matchingId))
75+
.requestStatus !== 'pending'
76+
) {
77+
throw InternalServerException('이미 처리된 요청입니다.');
78+
}
79+
80+
await this.matchingService.patchMatchingRequestStatus(body);
81+
return new BaseResponse(true, '매칭 상태 변경 성공');
6482
}
6583

6684
@Patch()

src/matching/matching.service.ts

+45-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ import { CreateMatchingReqeust } from './dto/matching.request';
33
import { DataSource, Repository } from 'typeorm';
44
import { Matching } from 'src/common/entities/matching.entity';
55
import { ChatRoomService } from '../chat-room/chat-room.service';
6-
import { InternalServerException } from 'src/common/exception/service.exception';
6+
import {
7+
DataNotFoundException,
8+
InternalServerException,
9+
} from 'src/common/exception/service.exception';
710
import { ChatMessageService } from 'src/chat-message/chat-message.service';
811
import { ChatRoom } from 'src/common/entities/chat-room.entity';
912
import { InjectRepository } from '@nestjs/typeorm';
13+
import { PatchMatchingRequestDto } from './dto/Patch-matching.request';
1014

1115
@Injectable()
1216
export class MatchingService {
@@ -50,4 +54,44 @@ export class MatchingService {
5054
await queryRunner.release();
5155
}
5256
}
57+
58+
async patchMatchingRequestStatus(
59+
body: PatchMatchingRequestDto,
60+
): Promise<Matching> {
61+
const queryRunner = this.dataSource.createQueryRunner();
62+
await queryRunner.connect();
63+
await queryRunner.startTransaction();
64+
65+
const matching = await this.getMatchingById(body.matchingId);
66+
67+
try {
68+
if (body.action === 'accept') {
69+
matching.requestStatus = 'accepted';
70+
matching.acceptedAt = new Date();
71+
} else if (body.action === 'reject') {
72+
matching.requestStatus = 'rejected';
73+
matching.rejectedAt = new Date();
74+
}
75+
76+
await queryRunner.manager.save(matching);
77+
await queryRunner.commitTransaction();
78+
79+
return matching;
80+
} catch (error) {
81+
await queryRunner.rollbackTransaction();
82+
throw InternalServerException(error.message);
83+
} finally {
84+
await queryRunner.release();
85+
}
86+
}
87+
88+
async getMatchingById(matchingId: number): Promise<Matching> {
89+
const matching = await this.matchingRepository.findOne({
90+
where: { id: matchingId },
91+
});
92+
if (!matching) {
93+
throw DataNotFoundException('해당 매칭 요청을 찾을 수 없습니다.');
94+
}
95+
return matching;
96+
}
5397
}

src/matching/matching.swagger.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
ApiAcceptedResponse,
23
ApiBadRequestResponse,
34
ApiInternalServerErrorResponse,
45
ApiNotFoundResponse,
@@ -35,7 +36,27 @@ export function CreateMatchingSwagger(apiSummary: string) {
3536

3637
// 매칭 생성 상태값 변경 API Swagger
3738
export function PatchMatchingRequestStatusSwagger(apiSummary: string) {
38-
return ApiOperation({ summary: apiSummary });
39+
return BaseSwaggerDecorator(
40+
{ summary: apiSummary },
41+
[
42+
{
43+
statusCode: 200,
44+
responseOptions: [
45+
{
46+
model: BaseResponse,
47+
exampleTitle: '성공',
48+
exampleDescription: '성공했을 때 값',
49+
},
50+
],
51+
baseResponseDto: BaseResponse,
52+
},
53+
],
54+
[
55+
ApiBadRequestResponse({ description: 'Bad Request' }),
56+
ApiNotFoundResponse({ description: '해당 유저가 존재하지 않습니다.' }),
57+
ApiInternalServerErrorResponse({ description: 'Internal Server Error' }),
58+
],
59+
);
3960
}
4061

4162
// 매칭 리스트 조회 API Swagger

0 commit comments

Comments
 (0)