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 1b6ad2cc..5608a458 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 @@ -31,21 +31,12 @@ public class EntryStatusResponseDto { @Schema(description = "대기 등록 시각", example = "2025-07-22T16:00:00") private LocalDateTime createdAt; - @Schema(description = "호출 시각", example = "2025-07-22T16:00:00") - private LocalDateTime calledAt; // 호출 시각 - - @Schema(description = "입장 완료 처리 시각", example = "2025-07-22T16:00:00") - private LocalDateTime confirmedAt; // 완료 시각 - @Schema(description = "웨이팅 취소 시각", example = "2025-07-22T16:00:00") - private LocalDateTime cancelledAt; // 취소 시각 + private LocalDateTime updatedAt; // 취소 시각 @Schema(description = "대기 상태", example = "CALLING") private String status; - @Schema(description = "대기 순번/점수", example = "2.0") - private Double score; - @Schema(description = "호출 메시지", example = "호출 메시지") private String message; @@ -58,9 +49,7 @@ public static EntryStatusResponseDto fromEntity(Reservation r) { .userName(r.getUser().getNickname()) .createdAt(r.getRequestedAt()) .status(r.getStatus().name()) - .calledAt(r.getCalledAt()) - .confirmedAt(r.getConfirmedAt()) - .cancelledAt(r.getCancelledAt()) + .updatedAt(r.getUpdatedAt()) .message(switch (r.getStatus()) { case CALLING -> r.getUser().getNickname() + "님을 호출하였습니다."; case CONFIRMED -> r.getUser().getNickname() + "님의 입장이 완료되었습니다."; 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 bbb163da..3ed9fa8d 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 @@ -99,7 +99,7 @@ public CallGetResponseDto updateReservationStatus(Long reservationId, Reservatio .equals(reservation.getStore().getStoreId())) { throw new ReservationUpdateUnauthorizedException(); } - reservation.updateStatus(requestDto.getStatus()); + reservation.markUpdated(LocalDateTime.now(), requestDto.getStatus()); return CallGetResponseDto.fromEntity(reservation); } @@ -231,14 +231,10 @@ public EntryStatusResponseDto processEntryStatus(Long storeId, String userId, Me String currStatus = waitingRedisRepository.getWaitingStatus(storeId, userId); Double score = redisTemplate.opsForZSet().score(queueKey, userId); Integer partySize = waitingRedisRepository.getWaitingPartySize(storeId, userId); - Long calledMillis = waitingRedisRepository.getWaitingCalledAt(storeId, userId); LocalDateTime requestedAt = score != null ? Instant.ofEpochMilli(score.longValue()).atZone(ZoneId.of("Asia/Seoul")).toLocalDateTime() : LocalDateTime.now(); - LocalDateTime calledAt = calledMillis != null - ? Instant.ofEpochMilli(calledMillis).atZone(ZoneId.of("Asia/Seoul")).toLocalDateTime() - : null; LocalDateTime now = LocalDateTime.now(); switch (newStatus) { @@ -257,8 +253,7 @@ public EntryStatusResponseDto processEntryStatus(Long storeId, String userId, Me .userName(userRepository.getReferenceById(Long.valueOf(userId)).getNickname()) .createdAt(requestedAt) .status("CALLING") - .score(score) - .calledAt(now) + .updatedAt(now) .message("호출되었습니다.") .build(); @@ -276,15 +271,11 @@ public EntryStatusResponseDto processEntryStatus(Long storeId, String userId, Me .user(userRepository.getReferenceById(Long.valueOf(userId))) .partySize(partySize) .requestedAt(requestedAt) + .updatedAt(LocalDateTime.now()) .build(); - // 호출 시각 반영 - r.markCalling(calledAt != null ? calledAt : now); - if (newStatus == ReservationStatus.CONFIRMED) { - r.markConfirmed(now); - } else { - r.markCancelled(now); - } + // 호출 시각 반영 + r.markUpdated(LocalDateTime.now(), ReservationStatus.CONFIRMED); Reservation saved = reservationRepository.save(r); return EntryStatusResponseDto.fromEntity(saved); } else { @@ -301,8 +292,7 @@ public EntryStatusResponseDto processEntryStatus(Long storeId, String userId, Me end ).orElseThrow(() -> new IllegalStateException("취소된 예약이 없습니다.")); - existing.markConfirmed(now); - existing.updateStatus(ReservationStatus.CONFIRMED); + existing.markUpdated(LocalDateTime.now(), ReservationStatus.CONFIRMED); Reservation saved = reservationRepository.save(existing); return EntryStatusResponseDto.fromEntity(saved); } @@ -320,9 +310,10 @@ public EntryStatusResponseDto processEntryStatus(Long storeId, String userId, Me .user(userRepository.getReferenceById(Long.valueOf(userId))) .partySize(partySize) .requestedAt(requestedAt) + .updatedAt(LocalDateTime.now()) .build(); - r.markCalling(calledAt != null ? calledAt : now); - r.markCancelled(now); + + r.markUpdated(LocalDateTime.now(), ReservationStatus.CANCELLED); Reservation saved = reservationRepository.save(r); return EntryStatusResponseDto.fromEntity(saved); 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 ccf73412..6ee8b7f4 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 @@ -96,10 +96,12 @@ public boolean removeWaiting(Long storeId, String userId) { String partyKey = RedisKeyUtils.buildWaitingPartySizeKeyPrefix() + storeId; String statusKey = RedisKeyUtils.buildWaitingStatusKeyPrefix() + storeId; String reservationNumberKey = RedisKeyUtils.buildReservationNumberKey(storeId); + redisTemplate.opsForZSet().remove(key, userId); redisTemplate.opsForHash().delete(partyKey, userId); redisTemplate.opsForHash().delete(statusKey, userId); redisTemplate.opsForHash().delete(reservationNumberKey, userId); + return true; } diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java index 04fc4eab..4b3c3edd 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java @@ -113,11 +113,33 @@ public boolean cancelWaiting(Long storeId, CustomOAuth2User customOAuth2User) { if (storeId == null || userId.trim().isEmpty()) { throw new IllegalArgumentException("Invalid storeId or userId"); } + + String reservationNumber = waitingUserRedisRepository.getReservationId(storeId, userId); + if (reservationNumber == null) { + throw new IllegalArgumentException("Waiting not found"); + } + Integer partySize = waitingUserRedisRepository.getPartySize(storeId, userId); + Long ts = waitingUserRedisRepository.getWaitingTimestamp(storeId, userId); + // 대기열에서 제거 및 결과 반환 boolean removed = waitingUserRedisRepository.removeWaiting(storeId, userId); if (!removed) { throw new IllegalArgumentException("Waiting not found"); } + + Reservation reservation = Reservation.builder() + .reservationNumber(reservationNumber) + .partySize(partySize) + .status(ReservationStatus.CANCELLED) + .store(storeRepository.getReferenceById(storeId)) + .user(userRepository.getReferenceById(Long.parseLong(userId))) + .updatedAt(LocalDateTime.now()) + .requestedAt(ts != null ? LocalDateTime.ofInstant(Instant.ofEpochMilli(ts), ZoneId.of("Asia/Seoul")) + : LocalDateTime.now()) + .build(); + + reservationRepository.save(reservation); + return removed; } 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 2f64fb34..da5ec2bf 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 @@ -49,14 +49,8 @@ public class Reservation { @Column(name = "requested_at", nullable = false) private LocalDateTime requestedAt; - @Column(name = "called_at", nullable = true) - private LocalDateTime calledAt; // 호출 시각 - - @Column(name = "confirmed_at", nullable = true) - private LocalDateTime confirmedAt; // 확정(입장 완료) 시각 - - @Column(name = "cancelled_at", nullable = true) - private LocalDateTime cancelledAt; // 취소 시각 + @Column(name = "updated_at", nullable = true) + private LocalDateTime updatedAt; @Enumerated(EnumType.STRING) @Column(nullable = false) @@ -65,23 +59,8 @@ public class Reservation { @Column(name = "party_size", nullable = false) private Integer partySize; - public void updateStatus(ReservationStatus status) { + public void markUpdated(LocalDateTime ts, ReservationStatus status) { this.status = status; - } - - // 상태 전환 메서드 - public void markCalling(LocalDateTime ts) { - this.status = ReservationStatus.CALLING; - this.calledAt = ts; - } - - public void markConfirmed(LocalDateTime ts) { - this.status = ReservationStatus.CONFIRMED; - this.confirmedAt = ts; - } - - public void markCancelled(LocalDateTime ts) { - this.status = ReservationStatus.CANCELLED; - this.cancelledAt = ts; + this.updatedAt = ts; } }