Skip to content

Commit

Permalink
Merge pull request #209 from boostcampwm-2022/feat/recruit-crud
Browse files Browse the repository at this point in the history
feat: 모집글 삭제, 참여 취소 API 구현
  • Loading branch information
pushedrumex authored Dec 8, 2022
2 parents 328a781 + 5150e92 commit 4334a5a
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class HttpRequestBodyInterceptor implements NestInterceptor {
try {
accessToken = accessToken.split("Bearer")[1].trim();
const { userIdx } = this.jwtService.verifyAccessToken(accessToken);
if (request.method === "GET") {
if (request.method === "GET" || request.method === "DELETE") {
request.params.userId = userIdx;
}
if (request.method === "POST") {
Expand Down
5 changes: 4 additions & 1 deletion server/src/common/repositories/user_recruit.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ export class UserRecruitRepository extends Repository<UserRecruit> {
return false;
}
public async countCurrentPpl(recruitId: number) {
return await this.countBy({ recruitId });
return this.countBy({ recruitId });
}
public createUserRecruit(userRecruitEntity: UserRecruit) {
this.save(userRecruitEntity);
}
public deleteUserRecruit(userRecruitEntity: UserRecruit) {
this.delete(userRecruitEntity);
}
}
21 changes: 21 additions & 0 deletions server/src/recruit/dto/request/delete-recruit.request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Expose, Type } from "class-transformer";
import { IsNumber } from "class-validator";

export class DeleteRecruitRequestDto {
@Type(() => Number)
@IsNumber()
@Expose({ name: "id" })
private recruitId: number;

@Type(() => Number)
@IsNumber()
private userId: number;

getRecruitId() {
return this.recruitId;
}

getUserId() {
return this.userId;
}
}
26 changes: 26 additions & 0 deletions server/src/recruit/dto/request/unjoin-recruit.request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Expose, Type } from "class-transformer";
import { IsNumber } from "class-validator";
import { UserRecruit } from "../../../common/entities/user_recruit.entity";

export class UnjoinRecruitRequestDto {
@Type(() => Number)
@IsNumber()
@Expose({ name: "id" })
private recruitId: number;

@Type(() => Number)
@IsNumber()
private userId: number;

getRecruitId() {
return this.recruitId;
}

getUserId() {
return this.userId;
}

toEntity() {
return UserRecruit.of(this.userId, this.recruitId);
}
}
54 changes: 44 additions & 10 deletions server/src/recruit/recruit.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Body, Controller, Get, Post, Query, Param } from "@nestjs/common";
import { Body, Controller, Get, Post, Query, Param, Delete } from "@nestjs/common";
import { CreateRecruitRequestDto } from "./dto/request/create-recruit.request";
import { GetRecruitsRequestDto } from "./dto/request/get-recruits.request";
import { JoinRecruitRequestDto } from "./dto/request/join-recruit.request";
Expand All @@ -9,6 +9,8 @@ import { ResponseEntity } from "../common/response/response.entity";
import { GetRecruitsResponseDto } from "./dto/response/get-recruits.response";
import { GetRecruitResponseDto } from "./dto/response/get-recruit.response";
import { GetRecruitRequestDto } from "./dto/request/get-recruit.request";
import { DeleteRecruitRequestDto } from "./dto/request/delete-recruit.request";
import { UnjoinRecruitRequestDto } from "./dto/request/unjoin-recruit.request";

@Controller("recruit")
@ApiTags("모집글 관리")
Expand All @@ -31,28 +33,60 @@ export class RecruitController {
return ResponseEntity.CREATED_WITH_DATA(createRecruitResponseDto);
}

@ApiOperation({ summary: "모집 취소", description: "모집을 취소한다" })
@Delete(":id")
async delete(@Param() deleteRecruitRequestDto: DeleteRecruitRequestDto) {
if (!(await this.recruitService.isExistingRecruit(deleteRecruitRequestDto.getRecruitId()))) {
return ResponseEntity.NOT_FOUND("존재하지 않는 게시글입니다");
}
if (
!(await this.recruitService.isAuthorOfRecruit(
deleteRecruitRequestDto.getRecruitId(),
deleteRecruitRequestDto.getUserId(),
))
) {
return ResponseEntity.LOCKED("자신의 게시글만 삭제할 수 있습니다");
}
this.recruitService.delete(deleteRecruitRequestDto);
return ResponseEntity.OK();
}

@ApiOperation({ summary: "모집 참가", description: "모집글에 참여한다" })
@Post("join")
async register(@Body() joinRecruitDto: JoinRecruitRequestDto) {
const recruitId = joinRecruitDto.getRecruitId();
const userId = joinRecruitDto.getUserId();

if (!(await this.recruitService.isExistingRecruit(recruitId))) {
async register(@Body() joinRecruitRequestDto: JoinRecruitRequestDto) {
if (!(await this.recruitService.isExistingRecruit(joinRecruitRequestDto.getRecruitId()))) {
return ResponseEntity.NOT_FOUND("존재하지 않는 게시글입니다");
}
if (await this.recruitService.isAuthorOfRecruit(recruitId, userId)) {
if (
await this.recruitService.isAuthorOfRecruit(
joinRecruitRequestDto.getRecruitId(),
joinRecruitRequestDto.getUserId(),
)
) {
return ResponseEntity.LOCKED("자신의 게시글에 참가할 수 없습니다");
}
if (await this.recruitService.isParticipating(recruitId, userId)) {
if (
await this.recruitService.isParticipating(
joinRecruitRequestDto.getRecruitId(),
joinRecruitRequestDto.getUserId(),
)
) {
return ResponseEntity.LOCKED("이미 참여중인 게시글입니다");
}
if (!(await this.recruitService.isVacancy(recruitId))) {
if (!(await this.recruitService.isVacancy(joinRecruitRequestDto.getRecruitId()))) {
return ResponseEntity.LOCKED("모집 상한에 도달했습니다");
}
this.recruitService.join(joinRecruitDto);
this.recruitService.join(joinRecruitRequestDto);
return ResponseEntity.CREATED();
}

@ApiOperation({ summary: "모집 참여 취소", description: "모집 참여를 취소한다" })
@Delete(":id/join")
async unregister(@Param() unjoinRecruitRequestDto: UnjoinRecruitRequestDto) {
this.recruitService.unjoin(unjoinRecruitRequestDto);
return ResponseEntity.OK();
}

@ApiOperation({ summary: "모집 상세", description: "모집 상세내용을 가져온다" })
@Get(":id")
async getOne(@Param() getRecruitRequestDto: GetRecruitRequestDto) {
Expand Down
25 changes: 21 additions & 4 deletions server/src/recruit/recruit.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { DataSource } from "typeorm";
import { plainToInstance } from "class-transformer";
import { JoinRecruitRequestDto } from "./dto/request/join-recruit.request";
import { Recruit } from "../common/entities/recruit.entity";
import { DeleteRecruitRequestDto } from "./dto/request/delete-recruit.request";
import { UserRecruit } from "src/common/entities/user_recruit.entity";
import { UnjoinRecruitRequestDto } from "./dto/request/unjoin-recruit.request";
@Injectable()
export class RecruitService {
constructor(
Expand All @@ -16,13 +19,13 @@ export class RecruitService {
private dataSource: DataSource,
) {}

async create(createRecruitDto: CreateRecruitRequestDto) {
async create(createRecruitRequestDto: CreateRecruitRequestDto) {
const queryRunner = this.dataSource.createQueryRunner();
let recruitEntity: Recruit;

await queryRunner.connect();
await queryRunner.manager.transaction(async (manager) => {
recruitEntity = await manager.save(createRecruitDto.toEntity());
recruitEntity = await manager.save(createRecruitRequestDto.toEntity());
const userRecruitDto = plainToInstance(JoinRecruitRequestDto, {
userId: recruitEntity.userId,
recruitId: recruitEntity.id,
Expand All @@ -32,6 +35,16 @@ export class RecruitService {
return recruitEntity;
}

async delete(deleteRecruitRequestDto: DeleteRecruitRequestDto) {
const queryRunner = this.dataSource.createQueryRunner();

await queryRunner.connect();
await queryRunner.manager.transaction(async (manager) => {
const recruitEntity = await this.recruitRepository.findOneById(deleteRecruitRequestDto.getRecruitId());
await manager.remove(recruitEntity);
await manager.delete(UserRecruit, { recruitId: deleteRecruitRequestDto.getRecruitId() });
});
}
async getMany(queryParams: GetRecruitsRequestDto) {
if (queryParams.getQuery() === "") {
return [];
Expand Down Expand Up @@ -114,7 +127,11 @@ export class RecruitService {
return recruitEntity.userId === userId;
}

join(createUserRecruitDto: JoinRecruitRequestDto) {
this.userRecruitRepository.createUserRecruit(createUserRecruitDto.toEntity());
join(joinRecruitRequestDto: JoinRecruitRequestDto) {
this.userRecruitRepository.createUserRecruit(joinRecruitRequestDto.toEntity());
}

unjoin(unjoinRecruitRequestDto: UnjoinRecruitRequestDto) {
this.userRecruitRepository.deleteUserRecruit(unjoinRecruitRequestDto.toEntity());
}
}

0 comments on commit 4334a5a

Please sign in to comment.