Skip to content

Commit

Permalink
페널티 목록 조회 API 구현 (#51)
Browse files Browse the repository at this point in the history
* Docs: 스웨거 설명 수정
- 페널티 사유 -> 페널티 수준
 #39

* Feat: 페널티 목록 조회 API
- 페널티 목록 조회 API
 #39

* Feat: 페널티 목록 조회 API 테스트 코드 작성
- 페널티 목록 조회 서비스 테스트 코드 작성
- 페널티 목록 조회 레포지토리 테스트 코드 작성
 #39

* Docs: 페널티 목록 조회 API 스웨거 수정
- 페널티 목록 조회 스웨거 수정
 #39
  • Loading branch information
joeun-01 authored Jul 31, 2024
1 parent 2efa235 commit d04cfc3
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 15 deletions.
8 changes: 0 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
.sql
.DS_Store

*.sql
.DS_Store
._.DS_Store
**/.DS_Store
**/._.DS_Store

*.sql
.DS_Store
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import kea.enter.enterbe.api.penalty.controller.request.PostPenaltyRequest;
import kea.enter.enterbe.api.penalty.controller.response.GetPenaltyListResponse;
import kea.enter.enterbe.api.penalty.service.AdminPenaltyService;
import kea.enter.enterbe.api.penalty.service.AdminPenaltyServiceImpl;
import kea.enter.enterbe.api.penalty.service.dto.GetPenaltyListServiceDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

import static kea.enter.enterbe.global.common.api.CustomResponseCode.SUCCESS;

@Tag(name = "페널티", description = "[관리자] Penalty")
Expand All @@ -33,4 +37,13 @@ public ResponseEntity<String> createPenalty(
adminPenaltyService.createPenalty(postPenaltyRequest.toService(memberId));
return ResponseEntity.ok(SUCCESS.getMessage());
}

/* 페널티 목록 조회 API */
@Operation(summary = "사용자 페널티 목록 조회 API", description = "사용자의 페널티 목록을 조회합니다.")
@GetMapping("/members/{memberId}")
public ResponseEntity<List<GetPenaltyListResponse>> getPenaltyList(@PathVariable Long memberId) {
// TODO: 어드민 권한 검사
List<GetPenaltyListResponse> response = adminPenaltyService.getPenaltyList(GetPenaltyListServiceDto.of(memberId));
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public class PostPenaltyRequest {
@Schema(description = "페널티 사유 (TAKE, RETURN, BROKEN, FUEL, ETC)", example = "FUEL")
private PenaltyReason reason;

@NotNull(message = "페널티 사유를 입력해야 합니다.")
@Schema(description = "페널티 사유 (LOW, MEDIUM, HIGH, BLACKLIST)", example = "LOW")
@NotNull(message = "페널티 수준을 입력해야 합니다.")
@Schema(description = "페널티 수준 (LOW, MEDIUM, HIGH, BLACKLIST)", example = "LOW")
private PenaltyLevel level;

@Size(max = 200)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package kea.enter.enterbe.api.penalty.controller.response;

import io.swagger.v3.oas.annotations.media.Schema;
import kea.enter.enterbe.domain.penalty.entity.PenaltyLevel;
import kea.enter.enterbe.domain.penalty.entity.PenaltyReason;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class GetPenaltyListResponse {
@Schema(description = "페널티 아이디", example = "1")
private Long penaltyId;

@Schema(description = "페널티 생성일", example = "2024-07-31")
private String createdAt;

@Schema(description = "페널티 사유 (TAKE, RETURN, BROKEN, FUEL, ETC)", example = "FUEL")
private PenaltyReason reason;

@Schema(description = "페널티 수준 (LOW, MEDIUM, HIGH, BLACKLIST)", example = "LOW")
private PenaltyLevel level;

@Schema(description = "비고", example = "자동차를 박살냈습니다.")
private String etc;

@Builder
public GetPenaltyListResponse(Long penaltyId, String createdAt, PenaltyReason reason,
PenaltyLevel level, String etc) {
this.penaltyId = penaltyId;
this.createdAt = createdAt;
this.reason = reason;
this.level = level;
this.etc = etc;
}

public static GetPenaltyListResponse of(Long penaltyId, String createdAt, PenaltyReason reason,
PenaltyLevel level, String etc) {
return GetPenaltyListResponse.builder()
.penaltyId(penaltyId)
.createdAt(createdAt)
.reason(reason)
.level(level)
.etc(etc)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package kea.enter.enterbe.api.penalty.service;

import kea.enter.enterbe.api.penalty.controller.response.GetPenaltyListResponse;
import kea.enter.enterbe.api.penalty.service.dto.GetPenaltyListServiceDto;
import kea.enter.enterbe.api.penalty.service.dto.PostPenaltyServiceDto;

import java.util.List;

public interface AdminPenaltyService {
void createPenalty(PostPenaltyServiceDto postPenaltyServiceDto);
List<GetPenaltyListResponse> getPenaltyList(GetPenaltyListServiceDto of);
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
package kea.enter.enterbe.api.penalty.service;

import kea.enter.enterbe.api.penalty.controller.response.GetPenaltyListResponse;
import kea.enter.enterbe.api.penalty.service.dto.GetPenaltyListServiceDto;
import kea.enter.enterbe.api.penalty.service.dto.PostPenaltyServiceDto;
import kea.enter.enterbe.domain.member.entity.Member;
import kea.enter.enterbe.domain.member.entity.MemberState;
import kea.enter.enterbe.domain.member.repository.MemberRepository;
import kea.enter.enterbe.domain.penalty.entity.Penalty;
import kea.enter.enterbe.domain.penalty.entity.PenaltyState;
import kea.enter.enterbe.domain.penalty.repository.PenaltyRepository;
import kea.enter.enterbe.global.common.exception.CustomException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import static kea.enter.enterbe.global.common.exception.ResponseCode.MEMBER_NOT_FOUND;

@Slf4j
Expand All @@ -24,14 +32,37 @@ public class AdminPenaltyServiceImpl implements AdminPenaltyService {

/* 페널티 부여 API */
@Transactional
public void createPenalty(PostPenaltyServiceDto service) {
public void createPenalty(PostPenaltyServiceDto dto) {
// MemberId로 멤버 존재 여부를 검사하고 페널티를 부여한다
Member member = findMemberById(service.getMemberId());
penaltyRepository.save(Penalty.of(member, service.getReason(), service.getLevel(), service.getEtc()));
Member member = findMemberById(dto.getMemberId());
penaltyRepository.save(Penalty.of(member, dto.getReason(), dto.getLevel(), dto.getEtc()));
}

/* 페널티 목록 조회 API */
public List<GetPenaltyListResponse> getPenaltyList(GetPenaltyListServiceDto dto) {
// MemberId로 멤버 존재 여부를 검사하고 페널티를 부여한다
Member member = findMemberById(dto.getMemberId());

// 해당 사용자의 페널티 내역을 조회한다
List<Penalty> penaltyList = penaltyRepository.findAllByMemberIdAndStateOrderByCreatedAt(member.getId(), PenaltyState.ACTIVE);
return penaltyList.stream()
.map(d -> GetPenaltyListResponse.builder()
.penaltyId(d.getId())
.createdAt(localDateTimeToString(d.getCreatedAt()))
.reason(d.getReason())
.level(d.getLevel())
.etc(d.getEtc())
.build()).toList();
}

public Member findMemberById(Long memberId) {
return memberRepository.findByIdAndState(memberId, MemberState.ACTIVE)
.orElseThrow(() -> new CustomException(MEMBER_NOT_FOUND));
}

public String localDateTimeToString(LocalDateTime localDateTime) {
Date date = java.sql.Timestamp.valueOf(localDateTime);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
return format.format(date);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package kea.enter.enterbe.api.penalty.service.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class GetPenaltyListServiceDto {
private Long memberId;

@Builder
public GetPenaltyListServiceDto(Long memberId) {
this.memberId = memberId;
}

public static GetPenaltyListServiceDto of(Long memberId) {
return GetPenaltyListServiceDto.builder()
.memberId(memberId)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public class Penalty extends BaseEntity {
@Column(name = "state", nullable = false)
private PenaltyState state;

public void deletePenalty() {
this.state = PenaltyState.INACTIVE;
}

@Builder
public Penalty(
Member member,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package kea.enter.enterbe.domain.penalty.repository;

import kea.enter.enterbe.domain.penalty.entity.Penalty;
import kea.enter.enterbe.domain.penalty.entity.PenaltyState;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
public interface PenaltyRepository extends JpaRepository<Penalty, Long> {

// 사용자의 페널티 목록을 조회한다
List<Penalty> findAllByMemberIdAndStateOrderByCreatedAt(Long memberId, PenaltyState state);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package kea.enter.enterbe.api.penalty.service;

import kea.enter.enterbe.IntegrationTestSupport;
import kea.enter.enterbe.api.penalty.controller.response.GetPenaltyListResponse;
import kea.enter.enterbe.api.penalty.service.dto.GetPenaltyListServiceDto;
import kea.enter.enterbe.api.penalty.service.dto.PostPenaltyServiceDto;
import kea.enter.enterbe.domain.member.entity.Member;
import kea.enter.enterbe.domain.member.entity.MemberRole;
Expand All @@ -13,6 +15,8 @@
import org.junit.jupiter.api.Test;
import java.util.List;

import static kea.enter.enterbe.domain.penalty.entity.PenaltyLevel.BLACKLIST;
import static kea.enter.enterbe.domain.penalty.entity.PenaltyReason.BROKEN;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;

Expand All @@ -36,8 +40,39 @@ public void postPenalty() throws Exception {
);
}

@DisplayName(value = "사용자의 페널티 목록을 조회한다.")
@Test
public void getPenaltyList() throws Exception {
//given
Member member = memberRepository.save(createMember());
Long memberId = member.getId();

Penalty penalty1 = penaltyRepository.save(createPenalty(member));
Penalty penalty2 = penaltyRepository.save(createPenalty(member));
Penalty penalty3 = penaltyRepository.save(createPenalty(member));
penaltyRepository.saveAll(List.of(penalty1, penalty2, penalty3));

GetPenaltyListServiceDto dto = GetPenaltyListServiceDto.of(memberId);

//when
List<GetPenaltyListResponse> penaltyList = adminPenaltyService.getPenaltyList(dto);

//then
assertThat(penaltyList).hasSize(3)
.extracting("reason", "level")
.containsExactlyInAnyOrder(
tuple(PenaltyReason.BROKEN, PenaltyLevel.BLACKLIST),
tuple(PenaltyReason.BROKEN, PenaltyLevel.BLACKLIST),
tuple(PenaltyReason.BROKEN, PenaltyLevel.BLACKLIST)
);
}

private Member createMember() {
return Member.of("1234", "name", "[email protected]", "password", "licenseId",
"licensePassword", true, true, 1, MemberRole.USER, MemberState.ACTIVE);
}

private Penalty createPenalty(Member member) {
return Penalty.of(member, BROKEN, BLACKLIST, null);
}
}
Loading

0 comments on commit d04cfc3

Please sign in to comment.