Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature : owner 웨이팅 조회 API 구현 #75

Merged
merged 21 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d041146
rename : 패키지 구조 변경
hyun2371 Jan 7, 2024
a6a50b2
style : dto명 변경
hyun2371 Jan 7, 2024
e647fdc
refactor : waitingRepository 리팩토링
hyun2371 Jan 8, 2024
6ab5e4e
feat : waitingRepository 함수 추가 및 테스트
hyun2371 Jan 8, 2024
edab978
feat : waitingLineRepository 기능 추가
hyun2371 Jan 8, 2024
e1017f0
feat : waitingLineRepository 추가된 기능 테스트
hyun2371 Jan 8, 2024
d0694f5
feat : owner 관련 DTO 추가
hyun2371 Jan 8, 2024
f494bcd
feat : dto 엔티티 매핑 함수 추가
hyun2371 Jan 8, 2024
46ace9b
feat : owner waiting 조회 서비스 로직 작성
hyun2371 Jan 8, 2024
7c4962f
feat : 기존 서비스 테스트 검증 누락된 부분 추가
hyun2371 Jan 8, 2024
2ca04c6
feat : owner 웨이팅 조회 서비스 테스트
hyun2371 Jan 8, 2024
2f5829b
feat : owner 웨이팅 조회 controller 메서드 추가
hyun2371 Jan 8, 2024
7afb52a
feat: owner 웨이팅 조회 통합 테스트 작성
hyun2371 Jan 8, 2024
f18dbdc
refactor : 코드 리포멧팅
hyun2371 Jan 8, 2024
c2eb81e
fix : ci 테스트 실패 오류 해결
hyun2371 Jan 8, 2024
5cdfadc
feat : basicWaitingLine 저장소 테스트 불필요한 로직 삭제 및 검증 메서드 추가
hyun2371 Jan 8, 2024
ec30c7c
refactor : 상태 변경 함수 메서드명 변경 및 불필요한 검증로직 삭제
hyun2371 Jan 8, 2024
08da5a3
refactor : 테스트 fixture reflectionUtil 대신 상태 함수 사용
hyun2371 Jan 8, 2024
5344cf7
feat : owner waiting 조회 단위 테스트 검증 로직 추가
hyun2371 Jan 8, 2024
c747742
refactor : redis rank 오름차순으로 정렬해 반환하는 로직 리팩토링
hyun2371 Jan 8, 2024
0939180
refactor : 코드 리포멧팅
hyun2371 Jan 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum ErrorCode {
INTERNAL_SERVER_ERROR("내부 서버 오류입니다."),

ALREADY_EXIST_OWNER("이미 존재하는 점주입니다"),
NOT_EXIST_OWNER("해당 아이디의 점주가 존재하지 않습니다."),
BAD_REQUEST_EMAIL_OR_PASSWORD("이메일 혹은 비밀번호를 확인해주세요"),
BAD_REQUEST_INPUT_GENDER_TYPE("성별 타입을 양식대로 입력해주세요");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.prgrms.catchtable.waiting.controller;

import com.prgrms.catchtable.waiting.dto.CreateWaitingRequest;
import com.prgrms.catchtable.waiting.dto.WaitingResponse;
import com.prgrms.catchtable.waiting.dto.request.CreateWaitingRequest;
import com.prgrms.catchtable.waiting.dto.response.MemberWaitingResponse;
import com.prgrms.catchtable.waiting.service.MemberWaitingService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,29 +23,32 @@ public class MemberWaitingController {
private final MemberWaitingService memberWaitingService;

@PostMapping("/{shopId}/{memberId}")
public ResponseEntity<WaitingResponse> createWaiting(@PathVariable("shopId") Long shopId,
public ResponseEntity<MemberWaitingResponse> createWaiting(@PathVariable("shopId") Long shopId,
@PathVariable("memberId") Long memberId,
@Valid @RequestBody CreateWaitingRequest request) {
WaitingResponse response = memberWaitingService.createWaiting(shopId, memberId, request);
MemberWaitingResponse response = memberWaitingService.createWaiting(shopId, memberId,
request);
return ResponseEntity.ok(response);
}

@PatchMapping("/{memberId}")
public ResponseEntity<WaitingResponse> postponeWaiting(
public ResponseEntity<MemberWaitingResponse> postponeWaiting(
@PathVariable("memberId") Long memberId) {
WaitingResponse response = memberWaitingService.postponeWaiting(memberId);
MemberWaitingResponse response = memberWaitingService.postponeWaiting(memberId);
return ResponseEntity.ok(response);
}

@DeleteMapping("/{memberId}")
public ResponseEntity<WaitingResponse> cancelWaiting(@PathVariable("memberId") Long memberId) {
WaitingResponse response = memberWaitingService.cancelWaiting(memberId);
public ResponseEntity<MemberWaitingResponse> cancelWaiting(
@PathVariable("memberId") Long memberId) {
MemberWaitingResponse response = memberWaitingService.cancelWaiting(memberId);
return ResponseEntity.ok(response);
}

@GetMapping("/{memberId}")
public ResponseEntity<WaitingResponse> getWaiting(@PathVariable("memberId") Long memberId) {
WaitingResponse response = memberWaitingService.getWaiting(memberId);
public ResponseEntity<MemberWaitingResponse> getWaiting(
@PathVariable("memberId") Long memberId) {
MemberWaitingResponse response = memberWaitingService.getWaiting(memberId);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.prgrms.catchtable.waiting.controller;

import com.prgrms.catchtable.waiting.dto.response.OwnerWaitingListResponse;
import com.prgrms.catchtable.waiting.service.OwnerWaitingService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("owner/waitings")
@RestController
public class OwnerWaitingController {

private final OwnerWaitingService ownerWaitingService;

@GetMapping("/{ownerId}")
public ResponseEntity<OwnerWaitingListResponse> getOwnerAllWaiting(
@PathVariable("ownerId") Long ownerId) {
OwnerWaitingListResponse response = ownerWaitingService.getOwnerAllWaiting(ownerId);
return ResponseEntity.ok(response);
}
}
28 changes: 26 additions & 2 deletions src/main/java/com/prgrms/catchtable/waiting/dto/WaitingMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
import com.prgrms.catchtable.member.domain.Member;
import com.prgrms.catchtable.shop.domain.Shop;
import com.prgrms.catchtable.waiting.domain.Waiting;
import com.prgrms.catchtable.waiting.dto.request.CreateWaitingRequest;
import com.prgrms.catchtable.waiting.dto.response.MemberWaitingResponse;
import com.prgrms.catchtable.waiting.dto.response.OwnerWaitingListResponse;
import com.prgrms.catchtable.waiting.dto.response.OwnerWaitingResponse;
import java.util.ArrayList;
import java.util.List;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = PRIVATE)
Expand All @@ -21,8 +27,8 @@ public static Waiting toWaiting(CreateWaitingRequest request, int waitingNumber,
}

// entity -> dto
public static WaitingResponse toWaitingResponse(Waiting waiting, Long rank) {
return WaitingResponse.builder()
public static MemberWaitingResponse toWaitingResponse(Waiting waiting, Long rank) {
return MemberWaitingResponse.builder()
.waitingId(waiting.getId())
.shopId(waiting.getShop().getId())
.shopName(waiting.getShop().getName())
Expand All @@ -33,4 +39,22 @@ public static WaitingResponse toWaitingResponse(Waiting waiting, Long rank) {
.status(waiting.getStatus().getDescription())
.build();
}

public static OwnerWaitingResponse toOwnerWaitingResponse(Waiting waiting, Long rank) {
return OwnerWaitingResponse.builder()
.waitingId(waiting.getId())
.waitingNumber(waiting.getWaitingNumber())
.rank(rank)
.peopleCount(waiting.getPeopleCount())
.build();
}

public static OwnerWaitingListResponse toOwnerWaitingListResponse(List<Waiting> waitings) {
long rank = 1L;
List<OwnerWaitingResponse> list = new ArrayList<>();
for (Waiting waiting : waitings) {
list.add(toOwnerWaitingResponse(waiting, rank++));
}
return new OwnerWaitingListResponse(list);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.prgrms.catchtable.waiting.dto;
package com.prgrms.catchtable.waiting.dto.request;

import jakarta.validation.constraints.Positive;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.prgrms.catchtable.waiting.dto;
package com.prgrms.catchtable.waiting.dto.response;

import lombok.Builder;

@Builder
public record WaitingResponse(
public record MemberWaitingResponse(
Long waitingId,
Long shopId,
String shopName,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.prgrms.catchtable.waiting.dto.response;

import java.util.List;
import lombok.Builder;

@Builder
public record OwnerWaitingListResponse(
List<OwnerWaitingResponse> shopWaitings
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.prgrms.catchtable.waiting.dto.response;

import lombok.Builder;

@Builder
public record OwnerWaitingResponse(
Long waitingId,
int waitingNumber,
Long rank,
int peopleCount
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.prgrms.catchtable.waiting.domain.Waiting;
import com.prgrms.catchtable.waiting.domain.WaitingStatus;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -20,4 +21,10 @@ public interface WaitingRepository extends JpaRepository<Waiting, Long> {
+ "where w.member = :member and w.status = :status")
Optional<Waiting> findByMemberAndStatusWithShop(@Param("member") Member member,
@Param("status") WaitingStatus status);

@Query("select w from Waiting w where w.id in :ids")
List<Waiting> findByIds(@Param("ids") List<Long> ids);

@Query("select w from Waiting w join fetch w.member where w.id = :id")
Optional<Waiting> findWaitingWithMember(@Param("id") Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.prgrms.catchtable.common.exception.custom.BadRequestCustomException;
import com.prgrms.catchtable.common.exception.custom.NotFoundCustomException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
Expand All @@ -33,6 +34,11 @@ public void entry(Long shopId, Long waitingId) {
waitingLine.remove();
}

public List<Long> getShopWaitingIdsInOrder(Long shopId) {
Queue<Long> waitingLine = waitingLines.get(shopId);
return waitingLine.stream().toList();
}

public void cancel(Long shopId, Long waitingId) {
Queue<Long> waitingLine = waitingLines.get(shopId);
validateIfWaitingExists(waitingLine, waitingId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import com.prgrms.catchtable.common.exception.custom.BadRequestCustomException;
import com.prgrms.catchtable.common.exception.custom.NotFoundCustomException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -41,6 +43,18 @@ public <K, V> Object execute(RedisOperations<K, V> operations)
});
}

public List<Long> getShopWaitingIdsInOrder(Long shopId) {
List<String> stringList = redisTemplate.opsForList().range("s" + shopId, 0, -1);
if (stringList == null) {
hyun2371 marked this conversation as resolved.
Show resolved Hide resolved
throw new BadRequestCustomException(WAITING_DOES_NOT_EXIST);
}
List<Long> longList = new ArrayList<>(stringList.stream()
.map(Long::parseLong)
.toList());
Collections.reverse(longList);
Copy link
Member

@dlswns2480 dlswns2480 Jan 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pr에 rank순으로 정렬해서 가져온다했는데 그게 이 부분인가요?? 정렬은 안 보이고 reverse()만 보여서요.. 몰라서 질문드립니다!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵! 리스트에 데이터 삽입 시 왼쪽으로 계속 삽입되기 때문에 rank가 큰 순으로 waitingId가 정렬되어 있습니다.
이를 reverse()로 rank가 작은 순으로 정렬해 반환하는 로직입니다. ex: [3L, 2L, 1L] -> [1L, 2L, 3L]

return longList;
}

public void entry(Long shopId, Long waitingId) {
validateIfWaitingExists(shopId, waitingId);
redisTemplate.execute(new SessionCallback<>() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.prgrms.catchtable.waiting.repository.waitingline;

import java.util.List;

public interface WaitingLineRepository {

void save(Long shopId, Long waitingId);
Expand All @@ -14,5 +16,7 @@ public interface WaitingLineRepository {

Long getWaitingLineSize(Long shopId);

List<Long> getShopWaitingIdsInOrder(Long shopId);

void printWaitingLine(Long shopId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import com.prgrms.catchtable.shop.domain.Shop;
import com.prgrms.catchtable.shop.repository.ShopRepository;
import com.prgrms.catchtable.waiting.domain.Waiting;
import com.prgrms.catchtable.waiting.dto.CreateWaitingRequest;
import com.prgrms.catchtable.waiting.dto.WaitingResponse;
import com.prgrms.catchtable.waiting.dto.request.CreateWaitingRequest;
import com.prgrms.catchtable.waiting.dto.response.MemberWaitingResponse;
import com.prgrms.catchtable.waiting.repository.WaitingRepository;
import com.prgrms.catchtable.waiting.repository.waitingline.WaitingLineRepository;
import java.time.LocalDate;
Expand All @@ -39,7 +39,7 @@ public class MemberWaitingService {
private final ShopRepository shopRepository;
private final WaitingLineRepository waitingLineRepository;

public WaitingResponse createWaiting(Long shopId, Long memberId,
public MemberWaitingResponse createWaiting(Long shopId, Long memberId,
CreateWaitingRequest request) {
// 연관 엔티티 조회
Member member = getMemberEntity(memberId);
Expand All @@ -63,7 +63,7 @@ public WaitingResponse createWaiting(Long shopId, Long memberId,
}

@Transactional
public WaitingResponse postponeWaiting(Long memberId) {
public MemberWaitingResponse postponeWaiting(Long memberId) {
Member member = getMemberEntity(memberId);
Waiting waiting = getWaitingEntityInProgress(member);

Expand All @@ -77,7 +77,7 @@ public WaitingResponse postponeWaiting(Long memberId) {
}

@Transactional
public WaitingResponse cancelWaiting(Long memberId) {
public MemberWaitingResponse cancelWaiting(Long memberId) {
Member member = getMemberEntity(memberId);
Waiting waiting = getWaitingEntityInProgress(member);

Expand All @@ -89,7 +89,7 @@ public WaitingResponse cancelWaiting(Long memberId) {
}

@Transactional(readOnly = true)
public WaitingResponse getWaiting(Long memberId) {
public MemberWaitingResponse getWaiting(Long memberId) {
Member member = getMemberEntity(memberId);
Waiting waiting = getWaitingEntityInProgress(member);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.prgrms.catchtable.waiting.service;

import static com.prgrms.catchtable.common.exception.ErrorCode.NOT_EXIST_OWNER;
import static com.prgrms.catchtable.waiting.dto.WaitingMapper.toOwnerWaitingListResponse;

import com.prgrms.catchtable.common.exception.custom.BadRequestCustomException;
import com.prgrms.catchtable.owner.domain.Owner;
import com.prgrms.catchtable.owner.repository.OwnerRepository;
import com.prgrms.catchtable.waiting.domain.Waiting;
import com.prgrms.catchtable.waiting.dto.response.OwnerWaitingListResponse;
import com.prgrms.catchtable.waiting.repository.WaitingRepository;
import com.prgrms.catchtable.waiting.repository.waitingline.WaitingLineRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Service
public class OwnerWaitingService {

private final WaitingRepository waitingRepository;
private final WaitingLineRepository waitingLineRepository;
private final OwnerRepository ownerRepository;

@Transactional(readOnly = true)
public OwnerWaitingListResponse getOwnerAllWaiting(Long ownerId) {
Owner owner = ownerRepository.findById(ownerId)
.orElseThrow(() -> new BadRequestCustomException(NOT_EXIST_OWNER));
List<Long> waitingIds = waitingLineRepository.getShopWaitingIdsInOrder(
owner.getShop().getId());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 쿼리가 한방 더 나갈거같아요..!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

owner.getShop().getId() 부분 말씀하시는건가요? 현재 임시로만 ownerId를 받는거라서 fetch join은 구현하지 않았습니다!

List<Waiting> waitings = waitingRepository.findByIds(waitingIds);
return toOwnerWaitingListResponse(waitings);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.prgrms.catchtable.owner.fixture;

import static com.prgrms.catchtable.member.domain.Gender.MALE;

import com.prgrms.catchtable.common.data.shop.ShopData;
import com.prgrms.catchtable.member.domain.Gender;
import com.prgrms.catchtable.owner.domain.Owner;
import com.prgrms.catchtable.owner.dto.request.JoinOwnerRequest;
import com.prgrms.catchtable.owner.dto.request.LoginOwnerRequest;
import com.prgrms.catchtable.shop.domain.Shop;
import java.time.LocalDate;
import org.springframework.test.util.ReflectionTestUtils;

import static com.prgrms.catchtable.member.domain.Gender.MALE;


public class OwnerFixture {

Expand All @@ -29,7 +28,21 @@ public static Owner getOwner(String email, String password) {
return owner;
}

public static JoinOwnerRequest getJoinOwnerRequest(String email, String password){
public static Owner getOwner(Shop shop) {
Owner owner = Owner.builder()
.name("ownerA")
.email("email")
.password("password")
.phoneNumber("010-3462-2480")
.gender(MALE)
.dateBirth(LocalDate.of(2000, 9, 13))
.build();
ReflectionTestUtils.setField(shop, "id", 1L);
owner.insertShop(shop);
return owner;
}

public static JoinOwnerRequest getJoinOwnerRequest(String email, String password) {
return JoinOwnerRequest.builder()
.name("ownerA")
.email(email)
Expand All @@ -40,7 +53,7 @@ public static JoinOwnerRequest getJoinOwnerRequest(String email, String password
.build();
}

public static LoginOwnerRequest getLoginOwnerRequest(String email, String password){
public static LoginOwnerRequest getLoginOwnerRequest(String email, String password) {
return LoginOwnerRequest.builder()
.email(email)
.password(password)
Expand Down
Loading