-
Notifications
You must be signed in to change notification settings - Fork 0
feat(Order,Reservation): redis 적용 #122
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
The head ref may contain hidden characters: "feature/#121-\uC0AC\uC6A9\uC790\uC8FC\uC810\uC608\uC57D\uAE30\uB2A5\uAC1C\uC120"
Conversation
- 사용자 주문 조회 응답 구조 변경 - redis 기반 사용자 예약 생성 기능 구현
## Walkthrough
이 변경 사항은 Redis 기반 대기열(웨이팅) 기능을 예약 시스템에 추가하며, 주문 항목을 상태별로 그룹화하여 반환하는 API 구조를 도입합니다. 또한, 닉네임 중복 검증 로직 제거, Redis 의존성 및 유틸리티 추가, 관련 DTO/Repository/Service/Controller를 확장 및 신설하는 작업이 포함되어 있습니다.
## Changes
| 파일/경로 요약 | 변경 내용 요약 |
|---|---|
| .../MenuImageService.java | 불필요한 공백 라인 제거(기능 변화 없음) |
| .../UserService.java | 닉네임 중복 검사 메서드 및 호출 제거 |
| .../build.gradle | Redis 연동을 위한 domain-redis 모듈 및 spring-boot-starter-data-redis 의존성 추가 |
| .../order/controller/OrderController.java | 주문 항목 조회 API의 반환 타입을 상태별 그룹화된 DTO로 변경 및 서비스 메서드 호출 변경 |
| .../order/dto/OrderItemGroupByStatusResponseDto.java | 주문 상태별 그룹화 응답 DTO 신설 |
| .../order/dto/OrderItemListGetResponseDto.java | fromEntity 메서드에서 status 필드 세팅 제거 |
| .../order/service/OrderService.java | 주문 항목 조회 메서드를 상태별 그룹화 반환 방식으로 리팩터링 및 메서드명 변경 |
| .../reservation/controller/ReservationController.java | Redis 기반 대기열 등록을 위한 신규 POST 엔드포인트(/reservations/create/redis/{storeId}) 추가 |
| .../reservation/dto/WaitingResponseDto.java | 대기열 응답용 DTO 신설(rank, reserved, partySize 포함) |
| .../reservation/repository/WaitingRedisRepository.java | Redis 기반 대기열 관리 리포지토리 신설(추가, 조회, 삭제 등 메서드 포함) |
| .../reservation/service/ReservationService.java | Redis 대기열 등록/조회/취소 기능 추가 및 WaitingRedisRepository 의존성 주입 |
| .../domaincoreredis/common/util/RedisKeyUtils.java | 대기열 관련 Redis 키 프리픽스 상수 및 getter 메서드 추가 |
## Sequence Diagram(s)
```mermaid
sequenceDiagram
participant Client
participant ReservationController
participant ReservationService
participant WaitingRedisRepository
participant Redis
Client->>ReservationController: POST /reservations/create/redis/{storeId}
ReservationController->>ReservationService: registerWaiting(storeId, user, requestDto)
ReservationService->>WaitingRedisRepository: getRank(storeId, userId)
WaitingRedisRepository->>Redis: ZRANK waiting:{storeId} {userId}
WaitingRedisRepository-->>ReservationService: rank/null
alt 신규 등록
ReservationService->>WaitingRedisRepository: addToWaitingQueue(storeId, userId, partySize, timestamp)
WaitingRedisRepository->>Redis: ZADD, HSET
WaitingRedisRepository-->>ReservationService: true/false
ReservationService->>WaitingRedisRepository: getRank(storeId, userId)
WaitingRedisRepository->>Redis: ZRANK
WaitingRedisRepository-->>ReservationService: rank
ReservationService-->>ReservationController: WaitingResponseDto(rank, false, partySize)
else 이미 등록됨
ReservationService-->>ReservationController: throw IllegalArgumentException
end
ReservationController-->>Client: HTTP 201 + WaitingResponseDtosequenceDiagram
participant Client
participant OrderController
participant OrderService
Client->>OrderController: GET /order-items
OrderController->>OrderService: getOrderItemsGroupByStatus(storeId, tableId, sessionId)
OrderService->>OrderService: 주문/주문항목 조회 및 상태별 그룹화
OrderService-->>OrderController: List<OrderItemGroupByStatusResponseDto>
OrderController-->>Client: HTTP 200 + 그룹화된 주문 항목 리스트
Possibly related PRs
Suggested labels
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (1)
nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java (1)
37-66: 아키텍처 관점에서 이중 저장소 전략에 대한 고려사항현재 구현에서 데이터베이스 기반 예약 시스템과 Redis 기반 대기열 시스템이 공존하고 있습니다. 다음 사항들을 고려해보세요:
- 데이터 일관성: 두 저장소 간 데이터 동기화 전략이 필요합니다.
- 비즈니스 로직 분리: 예약 생성 로직이 두 곳에 분산되어 있어 유지보수가 복잡할 수 있습니다.
- 장애 처리: Redis 장애 시 대기열 시스템의 fallback 전략이 필요합니다.
다음과 같은 개선 방안을 제안합니다:
- 통합 인터페이스: 예약 생성의 진입점을 하나로 통합하여 내부적으로 저장소를 선택하도록 구현
- 이벤트 기반 동기화: 도메인 이벤트를 활용하여 두 저장소 간 데이터 동기화
- Circuit Breaker 패턴: Redis 장애 시 데이터베이스로 fallback하는 메커니즘 구현
이런 구조적 개선을 통해 시스템의 안정성과 유지보수성을 향상시킬 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/menu/service/MenuImageService.java(0 hunks)nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/user/serivce/UserService.java(0 hunks)nowait-app-user-api/build.gradle(2 hunks)nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/controller/OrderController.java(2 hunks)nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/dto/OrderItemGroupByStatusResponseDto.java(1 hunks)nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/dto/OrderItemListGetResponseDto.java(0 hunks)nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java(2 hunks)nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/controller/ReservationController.java(2 hunks)nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/dto/WaitingResponseDto.java(1 hunks)nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingRedisRepository.java(1 hunks)nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java(2 hunks)nowait-domain/domain-redis/src/main/java/com/nowait/domaincoreredis/common/util/RedisKeyUtils.java(2 hunks)
💤 Files with no reviewable changes (3)
- nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/menu/service/MenuImageService.java
- nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/user/serivce/UserService.java
- nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/dto/OrderItemListGetResponseDto.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/dto/OrderItemGroupByStatusResponseDto.java (1)
nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/dto/OrderItemListGetResponseDto.java (1)
Getter(12-32)
🔇 Additional comments (12)
nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/dto/OrderItemGroupByStatusResponseDto.java (1)
16-19: 구현이 깔끔하고 목적에 부합합니다.상태별로 주문 항목을 그룹화하는 DTO 구조가 명확하고 간결합니다. Lombok 어노테이션을 적절히 사용하여 보일러플레이트 코드를 줄였습니다.
nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/controller/OrderController.java (2)
16-16: 새로운 DTO 임포트가 적절합니다.
OrderItemGroupByStatusResponseDto임포트가 새로운 그룹화 기능에 맞게 추가되었습니다.
62-62: 서비스 메서드 호출이 새로운 그룹화 기능에 맞게 업데이트되었습니다.
getOrderItemsGroupByStatus메서드 호출로 변경되어 상태별 그룹화된 응답을 반환하도록 개선되었습니다.nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/service/OrderService.java (3)
17-17: 새로운 DTO 임포트가 적절합니다.
OrderItemGroupByStatusResponseDto임포트가 새로운 그룹화 기능에 맞게 추가되었습니다.
97-97: 메서드명 변경이 기능을 명확히 나타냅니다.
getOrderItemsGroupByStatus로 메서드명이 변경되어 상태별 그룹화 기능을 명확히 표현합니다.
107-112: 그룹화 로직이 효율적으로 구현되었습니다.
Map.entrySet().stream()을 사용하여 상태별로 그룹화된 데이터를OrderItemGroupByStatusResponseDto리스트로 변환하는 로직이 깔끔하게 구현되었습니다.nowait-app-user-api/build.gradle (1)
25-25: Redis 의존성 추가가 적절합니다.Redis 통합을 위한 의존성들이 올바르게 추가되었습니다. 도메인 모듈과 Spring Boot Redis 스타터가 적절히 포함되어 있습니다.
Also applies to: 52-53
nowait-domain/domain-redis/src/main/java/com/nowait/domaincoreredis/common/util/RedisKeyUtils.java (1)
16-18: 대기열 Redis 키 유틸리티가 잘 구현되었습니다.새로운 Redis 키 상수들이 기존 패턴을 따르고 있으며, 명확한 네이밍 컨벤션을 사용하고 있습니다. Redis 키 구조가 적절하게 설계되어 있습니다.
Also applies to: 41-42
nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/dto/WaitingResponseDto.java (1)
1-12: 잘 설계된 응답 DTO입니다.불변 필드와 적절한 Lombok 어노테이션을 사용하여 깔끔하게 구현되었습니다.
reserved필드의 주석이 명확하게 의미를 설명하고 있습니다.nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingRedisRepository.java (1)
17-26: Redis 연결 예외 처리 및 트랜잭션 고려사항을 검토하세요.현재 구현에서 Redis 연결 실패나 부분적 실패에 대한 예외 처리가 없습니다. 또한 sorted set과 hash 업데이트 간의 원자성이 보장되지 않습니다.
다음 사항들을 검토해보세요:
- Redis 연결 실패 시 예외 처리 전략
- 트랜잭션 또는 pipeline 사용 고려
- 부분 실패 시 롤백 전략
Redis 트랜잭션 사용 예시:
public boolean addToWaitingQueue(Long storeId, String userId, Integer partySize, long timestamp) { String queueKey = RedisKeyUtils.buildWaitingKeyPrefix() + storeId; String partyKey = RedisKeyUtils.buildWaitingPartySizeKeyPrefix() + storeId; return redisTemplate.execute(new SessionCallback<Boolean>() { @Override public Boolean execute(RedisOperations operations) throws DataAccessException { operations.multi(); Boolean added = operations.opsForZSet().addIfAbsent(queueKey, userId, timestamp); if (Boolean.TRUE.equals(added)) { operations.opsForHash().put(partyKey, userId, partySize.toString()); } operations.exec(); return added; } }); }nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java (2)
11-12: 새로운 Redis 관련 import 추가가 적절합니다.Redis 대기열 기능을 위한 필요한 클래스들이 올바르게 import되었습니다.
35-35: Redis 저장소 의존성 주입이 올바르게 구현되었습니다.생성자 주입을 통한 의존성 관리가 Spring 모범 사례를 따르고 있습니다.
| Map<OrderStatus, List<OrderItemListGetResponseDto>> grouped = userOrders.stream() | ||
| .flatMap(order -> order.getOrderItems().stream() | ||
| .map(orderItem -> OrderItemListGetResponseDto.fromEntity(orderItem, order.getStatus()))) | ||
| .collect(Collectors.groupingBy(OrderItemListGetResponseDto::getStatus)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
OrderItemListGetResponseDto.fromEntity 메서드의 status 필드 설정을 확인해야 합니다.
관련 코드 스니펫에 따르면 fromEntity 메서드가 status 파라미터를 받지만 실제로는 status 필드를 설정하지 않는 것으로 보입니다. 이후 104번 줄에서 getStatus()를 호출하면 null이 반환되어 그룹화 로직이 올바르게 작동하지 않을 수 있습니다.
다음 스크립트를 실행하여 fromEntity 메서드 구현을 확인해 주세요:
🏁 Script executed:
#!/bin/bash
# Description: OrderItemListGetResponseDto.fromEntity 메서드의 status 필드 설정 확인
# fromEntity 메서드 구현 확인
ast-grep --pattern 'public static OrderItemListGetResponseDto fromEntity($_, $_) {
$$$
}'Length of output: 93
다음 스크립트로 DTO 클래스 위치와 fromEntity 메서드 구현을 다시 확인해 주세요.
🏁 Script executed:
#!/bin/bash
# 1. OrderItemListGetResponseDto 클래스 파일 위치 확인
echo "=== DTO 클래스 위치 ==="
fd OrderItemListGetResponseDto.java
# 2. 클래스 선언부 확인
echo "=== 클래스 선언부 스니펫 ==="
rg -n "class OrderItemListGetResponseDto" -A 5
# 3. fromEntity 메서드 구현 검색
echo "=== fromEntity 구현 ==="
rg -n "fromEntity" -A 20Length of output: 102188
OrderItemListGetResponseDto.fromEntity에 status가 설정되지 않습니다
fromEntity 메서드가 전달받은 status 파라미터를 빌더에 반영하지 않아, getStatus()가 null을 반환해 그룹화 로직이 올바르게 동작하지 않습니다.
수정이 필요한 위치:
- nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/dto/OrderItemListGetResponseDto.java
fromEntity메서드의 빌더 체인에.status(status)를 추가해야 합니다.
예시 수정(diff):
public static OrderItemListGetResponseDto fromEntity(OrderItem orderItem, OrderStatus status) {
return OrderItemListGetResponseDto.builder()
.orderId(orderItem.getUserOrder().getId())
.menuName(orderItem.getMenu().getName())
.quantity(orderItem.getQuantity())
.price(orderItem.getMenu().getPrice())
+ .status(status)
.build();
}🤖 Prompt for AI Agents
In
nowait-app-user-api/src/main/java/com/nowait/applicationuser/order/dto/OrderItemListGetResponseDto.java
inside the fromEntity method, the passed status parameter is not set on the
builder, causing getStatus() to return null and breaking the grouping logic. Fix
this by adding .status(status) to the builder chain in fromEntity so the status
field is properly initialized.
...i/src/main/java/com/nowait/applicationuser/reservation/controller/ReservationController.java
Show resolved
Hide resolved
.../src/main/java/com/nowait/applicationuser/reservation/repository/WaitingRedisRepository.java
Outdated
Show resolved
Hide resolved
.../src/main/java/com/nowait/applicationuser/reservation/repository/WaitingRedisRepository.java
Show resolved
Hide resolved
...ser-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java
Outdated
Show resolved
Hide resolved
...ser-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java
Show resolved
Hide resolved
...ser-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java
Show resolved
Hide resolved
- 파라미터 유효성 검사 로직 - Store 예약 비활성화 여부 체크 로직
작업 요약
Issue Link
#121
문제점 및 어려움
해결 방안
Reference
Summary by CodeRabbit
신규 기능
버그 수정
기타