Skip to content

Commit aefdbd1

Browse files
authored
Merge pull request #10 from oodd-team/OD-43
대표 게시글 설정/해제 기능
2 parents c4a86af + c7064e1 commit aefdbd1

File tree

3 files changed

+87
-6
lines changed

3 files changed

+87
-6
lines changed

src/post/post.controller.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,21 @@ export class PostController {
149149
return new BaseResponse(true, '게시글이 삭제되었습니다.');
150150
}
151151

152-
@Patch()
152+
@Patch(':postId/is-representative')
153153
@PatchIsRepresentativeSwagger('대표 게시글 지정 API')
154-
patchIsRepresentative() {
155-
// return this.userService.getHello();
154+
async patchIsRepresentative(
155+
@Param('postId') postId: number,
156+
@Req() req: Request,
157+
): Promise<BaseResponse<any>> {
158+
const currentUserId = req.user.userId;
159+
160+
await this.postService.validatePost(postId, currentUserId);
161+
162+
const updatedPost = await this.postService.patchIsRepresentative(
163+
postId,
164+
currentUserId,
165+
);
166+
167+
return new BaseResponse(true, '대표 게시글 설정/해제 성공', updatedPost);
156168
}
157169
}

src/post/post.service.ts

+45
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,51 @@ export class PostService {
324324
return post;
325325
}
326326

327+
// 대표 게시글 설정
328+
async patchIsRepresentative(
329+
postId: number,
330+
currentUserId: number,
331+
): Promise<Post> {
332+
const queryRunner = this.dataSource.createQueryRunner();
333+
334+
await queryRunner.startTransaction();
335+
336+
const post = await this.postRepository.findOne({
337+
where: { id: postId, user: { id: currentUserId }, status: 'activated' },
338+
});
339+
340+
try {
341+
// 대표 게시글 지정
342+
if (!post.isRepresentative) {
343+
// 기존 대표 게시글이 있다면, 그 게시글의 isRepresentative를 false로 변경
344+
await queryRunner.manager.update(
345+
Post,
346+
{
347+
user: { id: currentUserId },
348+
isRepresentative: true,
349+
status: 'activated',
350+
},
351+
{ isRepresentative: false },
352+
);
353+
354+
// 현재 게시글을 대표로 설정
355+
post.isRepresentative = true;
356+
} else {
357+
// 대표 설정 해제
358+
post.isRepresentative = false;
359+
}
360+
361+
const updatedPost = await queryRunner.manager.save(post);
362+
await queryRunner.commitTransaction();
363+
return updatedPost;
364+
} catch (error) {
365+
await queryRunner.rollbackTransaction();
366+
throw InternalServerException('게시글 수정에 실패했습니다.');
367+
} finally {
368+
await queryRunner.release();
369+
}
370+
}
371+
327372
// 게시글 검증 메서드
328373
async validatePost(postId: number, userId?: number): Promise<void> {
329374
const post = await this.postRepository.findOne({

src/post/post.swagger.ts

+27-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
ApiForbiddenResponse,
66
ApiInternalServerErrorResponse,
77
ApiNotFoundResponse,
8-
ApiOperation,
98
ApiUnauthorizedResponse,
109
} from '@nestjs/swagger';
1110
import { BaseSwaggerDecorator } from 'nestjs-swagger-decorator';
@@ -190,6 +189,31 @@ export function DeletePostSwagger(text: string) {
190189
}
191190

192191
// 대표 게시글 지정 API Swagger
193-
export function PatchIsRepresentativeSwagger(apiSummary: string) {
194-
return ApiOperation({ summary: apiSummary });
192+
export function PatchIsRepresentativeSwagger(text: string) {
193+
return BaseSwaggerDecorator(
194+
{ summary: text },
195+
[],
196+
[
197+
ApiCreatedResponse({
198+
description: '대표 게시글 수정 성공',
199+
type: PatchPostDto,
200+
}),
201+
ApiBadRequestResponse({
202+
description: '잘못된 요청입니다.',
203+
type: BaseResponse,
204+
}),
205+
ApiUnauthorizedResponse({
206+
description: '인증되지 않은 사용자입니다.',
207+
type: BaseResponse,
208+
}),
209+
ApiForbiddenResponse({
210+
description: '권한이 없습니다.',
211+
type: BaseResponse,
212+
}),
213+
ApiInternalServerErrorResponse({
214+
description: '서버 오류입니다.',
215+
type: BaseResponse,
216+
}),
217+
],
218+
);
195219
}

0 commit comments

Comments
 (0)