From e3290e3da46dc8629adb476594840f4a54fd4026 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Mon, 28 Jul 2025 19:47:22 +0900 Subject: [PATCH 1/7] =?UTF-8?q?refactor(Reservation):=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/dto/EntryStatusResponseDto.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/EntryStatusResponseDto.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/EntryStatusResponseDto.java index 4322e197..1b6ad2cc 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/EntryStatusResponseDto.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/EntryStatusResponseDto.java @@ -69,14 +69,5 @@ public static EntryStatusResponseDto fromEntity(Reservation r) { }) .build(); } - - private String buildMessage(ReservationStatus status, String nickname) { - return switch (status) { - case CALLING -> nickname + "님을 호출하였습니다."; - case CONFIRMED -> nickname + "님의 입장이 완료되었습니다."; - case CANCELLED -> nickname + "님의 예약이 취소되었습니다."; - default -> ""; - }; - } } From 53e0ca29be0d3d35d2152d9b25b26c2a325eac67 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Mon, 28 Jul 2025 19:49:33 +0900 Subject: [PATCH 2/7] =?UTF-8?q?refactor(Reservation):=20=EB=A7=A4=ED=95=91?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/dto/WaitingUserResponse.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/WaitingUserResponse.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/WaitingUserResponse.java index 881b68ec..95fbf33a 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/WaitingUserResponse.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/WaitingUserResponse.java @@ -17,7 +17,7 @@ public class WaitingUserResponse { @Schema(description = "예약 ID", example = "16-20240201-0002") - private String reservationId; + private String reservationNumber; @Schema(description = "유저 ID", example = "16") private String userId; @@ -39,7 +39,7 @@ public class WaitingUserResponse { public static WaitingUserResponse fromEntity(Reservation reservation) { return WaitingUserResponse.builder() - .reservationId(reservation.getId().toString()) + .reservationNumber(reservation.getReservationNumber()) .userId(reservation.getUser().getId().toString()) .partySize(reservation.getPartySize()) .userName(reservation.getUser().getNickname()) @@ -50,7 +50,7 @@ public static WaitingUserResponse fromEntity(Reservation reservation) { public static WaitingUserResponse fromRedis(String reservationId, String userId, Integer partySize, String userName, LocalDateTime createdAt, String status, Double score) { return WaitingUserResponse.builder() - .reservationId(reservationId) + .reservationNumber(reservationId) .userId(userId) .partySize(partySize) .userName(userName) From 3971be7ffb2e99a7d1c931203d491376b2c83d12 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Mon, 28 Jul 2025 19:50:27 +0900 Subject: [PATCH 3/7] =?UTF-8?q?refactor(Reservation):=20=EB=A7=8C=EB=A3=8C?= =?UTF-8?q?=20=EC=8B=9C=EA=B0=84=20=ED=98=B8=EC=B6=9C=20=EC=8B=9C=EC=A0=90?= =?UTF-8?q?=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/repository/WaitingRedisRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/repository/WaitingRedisRepository.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/repository/WaitingRedisRepository.java index e21233a2..02e29c82 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/repository/WaitingRedisRepository.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/repository/WaitingRedisRepository.java @@ -16,8 +16,8 @@ @Repository @RequiredArgsConstructor public class WaitingRedisRepository { + private final StringRedisTemplate redisTemplate; - private final Date expireAt = RedisKeyUtils.expireAtNext03(); // 대기열 전체 인원수 조회 public List> getAllWaitingWithScore(Long storeId) { @@ -90,7 +90,7 @@ public void setWaitingCalledAt(Long storeId, String userId, long timestamp) { String key = RedisKeyUtils.buildWaitingCalledAtKeyPrefix() + storeId; redisTemplate.opsForHash().put(key, userId, String.valueOf(timestamp)); - redisTemplate.expireAt(key, expireAt); + redisTemplate.expireAt(key, RedisKeyUtils.expireAtNext03()); } public Long getWaitingCalledAt(Long storeId, String userId) { From 325cec2226adeca84aaba275a87209c0616826a6 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Mon, 28 Jul 2025 19:56:43 +0900 Subject: [PATCH 4/7] =?UTF-8?q?refactor(Reservation):=20=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20=EC=9D=BC=EA=B4=80=EC=84=B1=EC=9E=88?= =?UTF-8?q?=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/service/ReservationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java index c95a6248..6ba78a76 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java @@ -247,7 +247,7 @@ public EntryStatusResponseDto processEntryStatus(Long storeId, String userId, Me throw new IllegalStateException("WAITING 상태에서만 CALLING 가능합니다."); } waitingRedisRepository.setWaitingStatus(storeId, userId, ReservationStatus.CALLING.name()); - waitingRedisRepository.setWaitingCalledAt(storeId, userId, now.toInstant(ZoneOffset.ofHours(9)).toEpochMilli()); + waitingRedisRepository.setWaitingCalledAt(storeId, userId, now.atZone(ZoneId.of("Asia/Seoul")).toInstant().toEpochMilli()); return EntryStatusResponseDto.builder() From c5aabd3afed6c2f67ec3590006a63c39ed07c663 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Mon, 28 Jul 2025 19:58:35 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor(Reservation):=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EB=AC=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ReservationService.java | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java index 6ba78a76..bbb163da 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/service/ReservationService.java @@ -287,28 +287,26 @@ public EntryStatusResponseDto processEntryStatus(Long storeId, String userId, Me Reservation saved = reservationRepository.save(r); return EntryStatusResponseDto.fromEntity(saved); + } else { + // 2) 이미 취소(CANCELLED)된 경우: DB 레코드 찾아 바로 CONFIRMED 로 전환 + // TODO 메서드로 분리 + LocalDateTime start = LocalDate.now().atStartOfDay(); + LocalDateTime end = LocalDate.now().atTime(LocalTime.MAX); + Reservation existing = reservationRepository + .findFirstByStore_StoreIdAndUserIdAndStatusInAndRequestedAtBetweenOrderByRequestedAtDesc( + storeId, + Long.valueOf(userId), + List.of(ReservationStatus.CANCELLED), + start, + end + ).orElseThrow(() -> new IllegalStateException("취소된 예약이 없습니다.")); + + existing.markConfirmed(now); + existing.updateStatus(ReservationStatus.CONFIRMED); + Reservation saved = reservationRepository.save(existing); + return EntryStatusResponseDto.fromEntity(saved); } - // 2) 이미 취소(CANCELLED)된 경우: DB 레코드 찾아 바로 CONFIRMED 로 전환 - // (Redis에는 상태가 남아있지 않으므로 currStatus==null) - { - LocalDateTime start = LocalDate.now().atStartOfDay(); - LocalDateTime end = LocalDate.now().atTime(LocalTime.MAX); - Reservation existing = reservationRepository - .findFirstByStore_StoreIdAndUserIdAndStatusInAndRequestedAtBetweenOrderByRequestedAtDesc( - storeId, - Long.valueOf(userId), - List.of(ReservationStatus.CANCELLED), - start, - end - ).orElseThrow(() -> new IllegalStateException("취소된 예약이 없습니다.")); - - existing.markConfirmed(now); - existing.updateStatus(ReservationStatus.CONFIRMED); - Reservation saved = reservationRepository.save(existing); - return EntryStatusResponseDto.fromEntity(saved); - } - case CANCELLED: if (!(ReservationStatus.WAITING.name().equals(currStatus) || ReservationStatus.CALLING.name().equals(currStatus))) { From f56ac5c0a94d47c935d17bf7dfef7569f0fc6114 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Mon, 28 Jul 2025 20:00:05 +0900 Subject: [PATCH 6/7] =?UTF-8?q?refactor(Reservation):=20SRP=20=EC=9C=84?= =?UTF-8?q?=EB=B0=98=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/WaitingUserRedisRepository.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingUserRedisRepository.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingUserRedisRepository.java index 08fb899b..ccf73412 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingUserRedisRepository.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingUserRedisRepository.java @@ -36,8 +36,8 @@ public String addToWaitingQueue(Long storeId, String userId, Integer partySize, String partyKey = RedisKeyUtils.buildWaitingPartySizeKeyPrefix() + storeId; String statusKey = RedisKeyUtils.buildWaitingStatusKeyPrefix() + storeId; - String seqKey = RedisKeyUtils.buildReservationSeqKey(storeId); - String numberMapKey = RedisKeyUtils.buildReservationNumberKey(storeId); + String seqKey = RedisKeyUtils.buildReservationSeqKey(storeId); + String numberMapKey = RedisKeyUtils.buildReservationNumberKey(storeId); Boolean added = redisTemplate.opsForZSet().addIfAbsent(queueKey, userId, timestamp); String reservationId; @@ -64,7 +64,7 @@ public String addToWaitingQueue(Long storeId, String userId, Integer partySize, redisTemplate.opsForHash().put(partyKey, userId, partySize.toString()); redisTemplate.opsForHash().put(statusKey, userId, "WAITING"); - Duration ttl = setTTL(partyKey, statusKey, userId, partySize); + Duration ttl = calculateTTLUntilNext03AM(); redisTemplate.expire(queueKey, ttl); redisTemplate.expire(partyKey, ttl); @@ -148,7 +148,7 @@ public List getUserWaitingStoreIds(String userId) { // 3) 파이프라인으로 zRank 한 번에 조회 List pipelineResults = redisTemplate.executePipelined( - (RedisCallback) conn -> { + (RedisCallback)conn -> { byte[] uid = redisTemplate.getStringSerializer().serialize(userId); for (String key : zsetKeys) { byte[] rawKey = redisTemplate.getStringSerializer().serialize(key); @@ -191,15 +191,12 @@ public String getReservationId(Long storeId, String userId) { return val != null ? val.toString() : null; } - public Duration setTTL(String partyKey, String statusKey, String userId, Integer partySize) { - // 6) 기존 partySize, status, TTL 설정 - redisTemplate.opsForHash().put(partyKey, userId, partySize.toString()); - redisTemplate.opsForHash().put(statusKey, userId, "WAITING"); - + public Duration calculateTTLUntilNext03AM() { // 6-1) Asia/Seoul 기준으로 오늘 자정(내일 00:00) 구하기 ZoneId zone = ZoneId.of("Asia/Seoul"); - LocalDateTime now = LocalDateTime.now(zone); + LocalDateTime now = LocalDateTime.now(zone); LocalDateTime midnight = now.toLocalDate().plusDays(1).atTime(3, 0); + // 6-2) TTL 남은 초 계산 long secondsUntilMidnight = now.until(midnight, ChronoUnit.SECONDS); From 57ece0f3e65b2b796722c2da796969466e3a7e5e Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Mon, 28 Jul 2025 20:01:11 +0900 Subject: [PATCH 7/7] =?UTF-8?q?refactor(Reservation):=20not=20null=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nowait/domaincorerdb/reservation/entity/Reservation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/entity/Reservation.java b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/entity/Reservation.java index 6857a7a8..2f64fb34 100644 --- a/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/entity/Reservation.java +++ b/nowait-domain/domain-core-rdb/src/main/java/com/nowait/domaincorerdb/reservation/entity/Reservation.java @@ -35,7 +35,7 @@ public class Reservation { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "reservation_number", nullable = false, length = 50) + @Column(name = "reservation_number", nullable = true, length = 50) private String reservationNumber; @ManyToOne(fetch = FetchType.LAZY, optional = false)