-
Notifications
You must be signed in to change notification settings - Fork 2
feat: 도어용 게스트 티켓 도어 확인 및 유효성 검증 api - #197 #198
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
Conversation
📝 WalkthroughSummary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. Walkthrough게스트 티켓 도어 확인·유효성 검증 API와 관련 도메인, 컴포넌트, 예외, DTO, 컨트롤러를 추가하고 QR 코드 경로 및 시큐리티 화이트리스트를 갱신했습니다. 또한 일부 예외 상속과 기존 엔티티/레포지토리에 접근자 및 조회 메서드를 추가했습니다. Changes
Sequence DiagramsequenceDiagram
participant Client
participant Controller as GuestController
participant Service as GuestService
participant GuestRetriever
participant EventRetriever
participant Repo as GuestTicketRepository/EventRepository
participant Entity as GuestTicketEntity
participant Updater as GuestUpdater
rect rgb(200,220,255)
note over Client,Controller: 유효성 검증 흐름
Client->>Controller: GET /api/guests/tickets/door/validation/{ticketCode}
Controller->>Service: validateGuestTicket(ticketCode)
Service->>GuestRetriever: findGuestTicketByTicketCode(ticketCode)
GuestRetriever->>Repo: findByGuestTicketCode(ticketCode)
Repo-->>GuestRetriever: GuestTicketEntity
GuestRetriever-->>Service: GuestTicket(domain)
Service->>Service: validateGuestTicketStatus(status)
Service->>EventRetriever: findEventByEventId(eventId)
EventRetriever->>Repo: findEventById(eventId)
Repo-->>EventRetriever: Event
EventRetriever-->>Service: Event
Service-->>Controller: GuestTicketValidateResponse
Controller-->>Client: 200 OK + BaseResponse
end
rect rgb(220,200,255)
note over Client,Controller: 스태프 확인(사용 처리) 흐름
Client->>Controller: POST /api/guests/tickets/door/staff/confirm
Controller->>Service: confirmGuestTicketByStaff(ticketCode, checkCode)
Service->>GuestRetriever: findGuestTicketEntityByTicketCode(ticketCode)
GuestRetriever->>Repo: findByGuestTicketCode(ticketCode)
Repo-->>GuestRetriever: GuestTicketEntity
GuestRetriever-->>Service: GuestTicketEntity
Service->>Service: validateGuestTicketStatus(status)
Service->>EventRetriever: findEventByEventId(eventId)
EventRetriever->>Repo: findEventById(eventId)
Repo-->>EventRetriever: Event
EventRetriever-->>Service: Event
Service->>Service: validateGuestTicketByCheckCode(...)
Service->>Updater: updateGuestTicketStatus(entity, USED)
Updater->>Entity: updateStatus(USED)
Updater-->>Service: void
Service-->>Controller: void
Controller-->>Client: 200 OK + BaseResponse
end
rect rgb(255,240,200)
note over Service: 에러 흐름 예시
Service->>Service: 티켓/이벤트 미발견 → GuestNotFoundException
Service->>Service: 이미 사용된 티켓 → GuestTicketIllegalException
Service->>Service: 체크코드 불일치 → GuestTicketIllegalException
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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: 3
🧹 Nitpick comments (6)
src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/core/domain/entity/GuestTicketEntity.java (1)
10-10: 클래스 레벨@Getter추가 승인, 중복 어노테이션 제거 권장클래스 레벨
@Getter추가로 인해 16번과 27번 라인의 필드 레벨@Getter어노테이션이 중복됩니다. 코드 정리를 위해 해당 필드 레벨 어노테이션 제거를 권장합니다.@Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Getter @Column(name = "guest_ticket_id") private Long guestTicketId; @Column(name = "event_id", nullable = false) private long eventId; @Column(name = "guest_id", nullable = false) private long guestId; @Column(name = "guest_ticket_code", nullable = false) - @Getter private String guestTicketCode;src/main/java/com/permitseoul/permitserver/domain/guest/core/component/GuestUpdater.java (1)
7-12:AdminGuestTicketUpdater와 중복 코드 존재
AdminGuestTicketUpdater와 동일한 구현입니다. 도메인 분리 목적이라면 현재 구조가 적절하나, 두 도메인이 동일한GuestTicketEntity를 공유하므로 공통 컴포넌트로 통합하는 것을 고려해볼 수 있습니다.src/main/java/com/permitseoul/permitserver/domain/guest/api/service/GuestService.java (2)
15-17: 사용하지 않는 import 제거 필요
NotFoundTicketException,TicketNotFoundException,TicketTypeNotfoundException이 import되어 있지만 코드에서 사용되지 않습니다.다음 diff를 적용하여 사용하지 않는 import를 제거하세요:
-import com.permitseoul.permitserver.domain.ticket.api.exception.NotFoundTicketException; -import com.permitseoul.permitserver.domain.ticket.core.exception.TicketNotFoundException; -import com.permitseoul.permitserver.domain.tickettype.core.exception.TicketTypeNotfoundException;
32-44: 읽기 전용 트랜잭션 어노테이션 추가 권장데이터베이스에서 조회만 수행하는 메서드이므로
@Transactional(readOnly = true)를 추가하는 것이 좋습니다. 이는 성능 최적화와 의도를 명확하게 표현하는 데 도움이 됩니다.다음 diff를 적용하세요:
+@Transactional(readOnly = true) public GuestTicketValidateResponse validateGuestTicket(final String ticketCode) {src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java (2)
21-26: 경로 변수 검증 추가 권장
ticketCode경로 변수에 대한 검증이 없습니다. 빈 문자열이나 유효하지 않은 형식의 입력을 방지하기 위해@NotBlank또는 다른 적절한 검증 어노테이션을 추가하는 것을 고려하세요.다음 diff를 적용하세요:
+import jakarta.validation.constraints.NotBlank; + @GetMapping("/tickets/door/validation/{ticketCode}") public ResponseEntity<BaseResponse<?>> validateGuestTicket( - @PathVariable final String ticketCode + @PathVariable @NotBlank(message = "티켓 코드는 필수입니다") final String ticketCode ) {
28-28: 주석 명확성 검토주석에 "스텝"이라고 표기되어 있는데, "스태프"(staff)를 의미하는 것인지 확인이 필요합니다. 메서드 이름은
confirmGuestTicketByStaffAtDoor이므로 일관성을 위해 주석도 "스태프"로 수정하는 것이 좋습니다.-//도어용 게스트 티켓 스텝 확인 api +//도어용 게스트 티켓 스태프 확인 api
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/core/domain/entity/GuestTicketEntity.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/core/repository/GuestTicketRepository.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/admin/util/QrCodeUtil.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/eventimage/EventImageBaseException.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/GuestBaseException.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/GuestExceptionHandler.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/req/GuestTicketConfirmRequest.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/res/GuestTicketValidateResponse.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestApiException.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestNotFoundException.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestTicketIllegalException.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/service/GuestService.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/core/component/GuestRetriever.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/core/component/GuestUpdater.java(1 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/core/domain/GuestTicket.java(1 hunks)src/main/java/com/permitseoul/permitserver/global/config/SecurityConfig.java(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: sjk4618
Repo: PERMIT-SEOUL/permit-server PR: 48
File: src/main/java/com/permitseoul/permitserver/domain/guest/core/domain/entity/GuestEntity.java:31-37
Timestamp: 2025-07-15T09:37:32.765Z
Learning: sjk4618 prefers to implement factory methods or public constructors for entities when they are actually needed, rather than creating them proactively.
🧬 Code graph analysis (10)
src/main/java/com/permitseoul/permitserver/domain/eventimage/EventImageBaseException.java (1)
src/main/java/com/permitseoul/permitserver/global/exception/PermitGlobalException.java (1)
PermitGlobalException(3-4)
src/main/java/com/permitseoul/permitserver/domain/guest/api/GuestExceptionHandler.java (1)
src/main/java/com/permitseoul/permitserver/global/response/ApiResponseUtil.java (1)
ApiResponseUtil(7-29)
src/main/java/com/permitseoul/permitserver/domain/guest/api/service/GuestService.java (7)
src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/core/exception/GuestTicketNotFoundException.java (1)
GuestTicketNotFoundException(3-4)src/main/java/com/permitseoul/permitserver/domain/event/core/exception/EventNotfoundException.java (1)
EventNotfoundException(3-4)src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestNotFoundException.java (1)
GuestNotFoundException(5-9)src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestTicketIllegalException.java (1)
GuestTicketIllegalException(5-9)src/main/java/com/permitseoul/permitserver/domain/ticket/api/exception/NotFoundTicketException.java (1)
NotFoundTicketException(5-9)src/main/java/com/permitseoul/permitserver/domain/ticket/core/exception/TicketNotFoundException.java (1)
TicketNotFoundException(3-4)src/main/java/com/permitseoul/permitserver/domain/tickettype/core/exception/TicketTypeNotfoundException.java (1)
TicketTypeNotfoundException(3-4)
src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java (1)
src/main/java/com/permitseoul/permitserver/global/response/ApiResponseUtil.java (1)
ApiResponseUtil(7-29)
src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestApiException.java (1)
src/main/java/com/permitseoul/permitserver/domain/guest/GuestBaseException.java (1)
GuestBaseException(5-6)
src/main/java/com/permitseoul/permitserver/domain/guest/GuestBaseException.java (1)
src/main/java/com/permitseoul/permitserver/global/exception/PermitGlobalException.java (1)
PermitGlobalException(3-4)
src/main/java/com/permitseoul/permitserver/domain/guest/core/component/GuestUpdater.java (2)
src/main/java/com/permitseoul/permitserver/domain/guest/core/component/GuestRetriever.java (1)
Component(10-22)src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/core/component/AdminGuestTicketUpdater.java (1)
Component(7-13)
src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestTicketIllegalException.java (1)
src/main/java/com/permitseoul/permitserver/domain/ticket/api/exception/IllegalTicketException.java (1)
IllegalTicketException(5-9)
src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/core/domain/entity/GuestTicketEntity.java (1)
src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/api/exception/AdminGuestTicketApiException.java (1)
Getter(8-12)
src/main/java/com/permitseoul/permitserver/domain/guest/core/component/GuestRetriever.java (2)
src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/core/exception/GuestTicketNotFoundException.java (1)
GuestTicketNotFoundException(3-4)src/main/java/com/permitseoul/permitserver/domain/guest/core/component/GuestUpdater.java (1)
Component(7-13)
🔇 Additional comments (16)
src/main/java/com/permitseoul/permitserver/domain/eventimage/EventImageBaseException.java (1)
3-5: LGTM! 글로벌 예외 계층 구조와 일관성 있게 정렬되었습니다.
PermitGlobalException을 상속하도록 변경하여 프로젝트의 예외 처리 패턴과 일관성을 유지하고 있습니다.src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestNotFoundException.java (1)
5-9: LGTM! 표준 예외 패턴을 따르고 있습니다.
GuestApiException을 확장하고ErrorCode를 받는 생성자를 제공하는 구조가 프로젝트의 다른 도메인 예외(예:IllegalTicketException)와 일관성 있게 구현되었습니다.src/main/java/com/permitseoul/permitserver/domain/guest/GuestBaseException.java (1)
5-6: LGTM! 게스트 도메인 예외 계층의 기반을 확립했습니다.
PermitGlobalException을 확장하여 프로젝트의 글로벌 예외 계층 구조와 일관성을 유지하며,GuestApiException의 상위 클래스로 적절히 기능합니다.src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/core/repository/GuestTicketRepository.java (1)
13-13: LGTM! 티켓 코드로 게스트 티켓을 조회하는 메서드가 올바르게 추가되었습니다.
Optional을 반환하여 null 안전성을 보장하며, Spring Data JPA의 파생 쿼리 명명 규칙을 따르고 있습니다.src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestTicketIllegalException.java (1)
5-9: LGTM! 기존 패턴과 일관성 있는 예외 클래스입니다.
IllegalTicketException과 동일한 구조를 따르고 있어 프로젝트의 예외 처리 패턴과 일관성을 유지합니다.src/main/java/com/permitseoul/permitserver/domain/guest/api/exception/GuestApiException.java (1)
8-12: LGTM! 잘 설계된 API 예외 기반 클래스입니다.Lombok을 활용하여 보일러플레이트를 최소화하고,
ErrorCode필드를 통해 구조화된 에러 정보를 전달할 수 있도록 설계되었습니다.GuestBaseException을 확장하여 예외 계층 구조가 명확합니다.src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/req/GuestTicketConfirmRequest.java (1)
5-12: LGTM! 불변 DTO로서 적절하게 구현되었습니다.Java record를 사용하여 불변성을 보장하고,
@NotBlank검증 어노테이션으로 필수 필드를 강제하며, 한국어 검증 메시지가 명확하게 작성되었습니다.src/main/java/com/permitseoul/permitserver/domain/guest/api/GuestExceptionHandler.java (1)
10-16: LGTM!
@RestControllerAdvice의basePackages범위 설정과GuestApiException처리 로직이 적절합니다.ApiResponseUtil.failure()를 통한 표준화된 응답 반환 방식이 기존 코드베이스와 일관성을 유지합니다.src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/res/GuestTicketValidateResponse.java (1)
8-20: LGTM!레코드 구조와
@JsonFormat설정이 적절합니다.of()팩토리 메서드에서 날짜 필드를 null로 반환하는 것이 게스트 티켓의 의도된 동작인지 확인해 주세요.src/main/java/com/permitseoul/permitserver/domain/guest/core/component/GuestRetriever.java (2)
4-4: admin 도메인 예외 사용에 대한 확인 필요
GuestTicketNotFoundException이admin.guestticket.core.exception패키지에서 import됩니다. guest 도메인에서 admin 도메인의 예외를 직접 참조하는 것이 의도된 설계인지 확인이 필요합니다. guest 도메인 전용 예외 사용을 고려해보세요.
15-21: LGTM!엔티티와 도메인 모델을 각각 반환하는 두 메서드 구조가 적절합니다.
orElseThrow를 통한 예외 처리가 일관되게 적용되어 있습니다.src/main/java/com/permitseoul/permitserver/domain/guest/api/service/GuestService.java (2)
34-34: 도메인 객체 사용의 일관성 검토 필요
validateGuestTicket메서드는GuestTicket도메인 객체를 사용하고(Line 34),confirmGuestTicketByStaff메서드는GuestTicketEntity를 사용합니다(Line 49). 업데이트 작업을 위해 엔티티가 필요한 것은 이해되지만, 일관성을 위해 두 메서드 모두 도메인 객체를 사용하고 필요할 때만 엔티티로 변환하는 방식을 고려해보세요.현재 구현이 의도적인 설계인지 확인이 필요합니다.
GuestRetriever에서findGuestTicketByTicketCode와findGuestTicketEntityByTicketCode두 메서드를 모두 제공하는 이유를 검토하세요.Also applies to: 49-49
39-43: 계층별 예외 처리 패턴이 프로젝트 전반에서 일관되게 적용되고 있습니다.코어 계층의 예외를 API 계층의 예외로 변환하는 패턴이 ReservationService, PaymentService, EventService 등 다른 서비스들에서도 동일하게 적용되고 있습니다. GuestService의 예외 처리 방식은 프로젝트의 표준 전략과 일치합니다.
src/main/java/com/permitseoul/permitserver/domain/guest/core/domain/GuestTicket.java (2)
20-29: 팩토리 메서드 구현 적절함엔티티에서 도메인 객체로의 변환을 위한 정적 팩토리 메서드가 잘 구현되어 있습니다. 학습 내역에 따르면, 사용자는 필요할 때 팩토리 메서드를 구현하는 것을 선호하며, 이 구현은 해당 선호도와 일치합니다.
13-15: 필드 타입 차이는 설계 의도가 명확합니다
GuestTicketEntity를 확인한 결과, 타입 차이는 의도적이고 적절합니다:
guestTicketId는@Id @GeneratedValue로 선언되어 있어 자동 생성되므로Long(nullable)이 정확합니다eventId와guestId는@Column(nullable = false)로 명시되어 있어long(primitive)이 적절합니다현재 도메인 모델이 엔티티 설계를 정확하게 반영하고 있으므로 변경이 필요하지 않습니다.
src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java (1)
29-35: POST 엔드포인트 구현 적절함
@Valid어노테이션을 사용하여 요청 본문 검증이 올바르게 구현되어 있고, 서비스 메서드 호출 및 응답 반환이 적절합니다.
| private static final int QR_SIZE = 256; | ||
| private static final String PNG = "PNG"; | ||
| private static final String URL_PATH = "/entry/"; | ||
| private static final String URL_PATH = "/entry/guest"; |
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.
🧩 Analysis chain
🏁 Script executed:
find . -name "QrCodeUtil.java" -type f -exec wc -l {} \;Repository: PERMIT-SEOUL/permit-server
Length of output: 151
🏁 Script executed:
find . -name "QrCodeUtil.java" -type f -exec cat -n {} \;Repository: PERMIT-SEOUL/permit-server
Length of output: 2509
🏁 Script executed:
# More specific search for /entry/ paths in controllers
rg -n --type=java '"/entry' -B 5 -A 5Repository: PERMIT-SEOUL/permit-server
Length of output: 1349
🏁 Script executed:
# Search for any @GetMapping or @PostMapping with path variables
rg -n --type=java '@(Get|Post|Put|Patch|Delete)Mapping' -B 2 -A 5 | grep -E '(Mapping|entry|guest|ticketCode|@)' | head -100Repository: PERMIT-SEOUL/permit-server
Length of output: 15668
🏁 Script executed:
# Search for any route or endpoint that contains "/entry"
rg -n --type=java 'RequestMapping|RestController|Controller' ./src/main/java/com/permitseoul/permitserver/domain/guest/ -B 1 -A 5Repository: PERMIT-SEOUL/permit-server
Length of output: 2622
🏁 Script executed:
# Search for any TODO or FIXME comments related to entry or guest
rg -n 'TODO|FIXME' --type=java | grep -i 'entry\|guest' | head -20Repository: PERMIT-SEOUL/permit-server
Length of output: 52
🏁 Script executed:
# Check git log for recent changes to QrCodeUtil
git log --oneline -20 -- src/main/java/com/permitseoul/permitserver/domain/admin/util/QrCodeUtil.java 2>/dev/null || echo "Git history not available"Repository: PERMIT-SEOUL/permit-server
Length of output: 116
URL 경로에 구분자가 누락되어 QR 코드가 잘못된 URL을 생성합니다.
Line 31에서 baseUrl + URL_PATH + ticketCode로 URL을 구성하므로, 현재 변경사항은 다음과 같은 잘못된 URL을 생성합니다:
- 결과:
https://example.com/entry/guestTICKET123(guest와 티켓코드 사이에/없음) - 예상:
https://example.com/entry/guest/TICKET123
이로 인해 QR 코드를 스캔했을 때 라우팅 실패나 404 에러가 발생합니다. 경로 구분자를 추가하세요:
- private static final String URL_PATH = "/entry/guest";
+ private static final String URL_PATH = "/entry/guest/";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private static final String URL_PATH = "/entry/guest"; | |
| private static final String URL_PATH = "/entry/guest/"; |
🤖 Prompt for AI Agents
In src/main/java/com/permitseoul/permitserver/domain/admin/util/QrCodeUtil.java
around line 26, the constant URL_PATH is missing a trailing slash which causes
URLs like https://example.com/entry/guestTICKET123; change the constant to
include the path separator (e.g. "/entry/guest/") so concatenation baseUrl +
URL_PATH + ticketCode yields /guest/{ticketCode}; also defensively handle
possible double slashes by trimming a trailing slash from baseUrl before
concatenation or by using a proper URL join helper.
| package com.permitseoul.permitserver.domain.guest.api.dto.res; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonFormat; | ||
| import com.permitseoul.permitserver.domain.ticket.api.dto.res.DoorValidateUserTicket; |
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.
사용하지 않는 import 제거 필요
DoorValidateUserTicket import가 사용되지 않습니다. 제거해 주세요.
import com.fasterxml.jackson.annotation.JsonFormat;
-import com.permitseoul.permitserver.domain.ticket.api.dto.res.DoorValidateUserTicket;
import java.time.LocalDateTime;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import com.permitseoul.permitserver.domain.ticket.api.dto.res.DoorValidateUserTicket; | |
| import com.fasterxml.jackson.annotation.JsonFormat; | |
| import java.time.LocalDateTime; |
🤖 Prompt for AI Agents
src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/res/GuestTicketValidateResponse.java
lines 4-4: the import of
com.permitseoul.permitserver.domain.ticket.api.dto.res.DoorValidateUserTicket is
unused; remove this import statement from the file and run a build/IDE
organize-imports to ensure no other unused imports remain.
| "/api/tickets/door/validation/*", | ||
| "/api/notion/**" | ||
| "/api/notion/**", | ||
| "api/guests/**" |
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.
치명적: 경로 패턴에 선행 슬래시(/)가 누락되었습니다.
Line 43의 "api/guests/**" 패턴에 선행 슬래시가 없어 Spring Security의 requestMatchers가 올바르게 매칭하지 못합니다. 이로 인해 게스트 API 엔드포인트가 화이트리스트에 추가되지 않아 인증이 필요하게 되며, 이 PR의 핵심 기능이 작동하지 않습니다.
다음 diff를 적용하여 수정하세요:
- "api/guests/**"
+ "/api/guests/**"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "api/guests/**" | |
| "/api/guests/**" |
🤖 Prompt for AI Agents
In src/main/java/com/permitseoul/permitserver/global/config/SecurityConfig.java
around line 43, the path pattern "api/guests/**" is missing a leading slash so
Spring Security requestMatchers won't match; update the pattern to include the
leading slash ("/api/guests/**") so the guest API endpoints are correctly
whitelisted by the security configuration.
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: 1
♻️ Duplicate comments (1)
src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/res/GuestTicketValidateResponse.java (1)
3-7: 미사용 import 정리 필요 (DoorValidateUserTicket는 이전 코멘트와 동일 이슈)
현재JsonFormat,DoorValidateUserTicket,LocalDateTime가 이 파일에서 사용되지 않습니다. IDE organize imports(또는 빌드 도구의 import 정리)로 제거해 주세요.
🧹 Nitpick comments (1)
src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/res/GuestTicketValidateResponse.java (1)
8-14:"Guest Ticket"하드코딩 문자열은 상수로 승격 권장
응답 스펙이 고정이더라도, 명칭 변경/i18n 대비를 위해 상수로 빼두는 편이 안전합니다(필요하면eventNamenull 가드도 함께).public record GuestTicketValidateResponse( String eventName, String ticketName ) { + private static final String GUEST_TICKET_NAME = "Guest Ticket"; + public static GuestTicketValidateResponse of(final String eventName) { - return new GuestTicketValidateResponse(eventName, "Guest Ticket"); + return new GuestTicketValidateResponse(eventName, GUEST_TICKET_NAME); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/main/java/com/permitseoul/permitserver/domain/admin/timetable/base/api/dto/res/TimetableInfoResponse.java(3 hunks)src/main/java/com/permitseoul/permitserver/domain/admin/timetable/base/api/service/AdminTimetableService.java(3 hunks)src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/res/GuestTicketValidateResponse.java(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: sjk4618
Repo: PERMIT-SEOUL/permit-server PR: 48
File: src/main/java/com/permitseoul/permitserver/domain/guest/core/domain/entity/GuestEntity.java:31-37
Timestamp: 2025-07-15T09:37:32.765Z
Learning: sjk4618 prefers to implement factory methods or public constructors for entities when they are actually needed, rather than creating them proactively.
🔇 Additional comments (2)
src/main/java/com/permitseoul/permitserver/domain/admin/timetable/base/api/dto/res/TimetableInfoResponse.java (1)
4-4: 응답 DTO에eventId필드 추가를 확인했습니다.인코딩된
eventId가 응답의 첫 번째 필드로 추가되었습니다. 구현은 올바르게 되어 있으나, 레코드 클래스의 필드 순서가 변경되면 직렬화된 JSON 응답의 필드 순서도 변경될 수 있습니다.API 응답 형식이 변경되므로, 프론트엔드 팀이나 API 소비자에게 이 변경사항을 공지했는지 확인하세요.
Also applies to: 14-15, 24-24
src/main/java/com/permitseoul/permitserver/domain/admin/timetable/base/api/service/AdminTimetableService.java (1)
23-23: 타입 호환성은 Java의 자동 박싱으로 처리됩니다.
eventId는long타입(기본 타입)이고SecureUrlUtil.encode(final Long id)는Long타입(래퍼 클래스)을 받습니다. 그러나 Java의 자동 박싱 기능으로 인해long이 자동으로Long으로 변환되므로 타입 호환성 문제는 없습니다.
| } | ||
|
|
||
| return TimetableInfoResponse.of( | ||
| secureUrlUtil.encode(eventId), |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for getTimetableInfo method definition and usages
rg -n --type java 'getTimetableInfo' -B 2 -A 10Repository: PERMIT-SEOUL/permit-server
Length of output: 4130
🏁 Script executed:
#!/bin/bash
# Find TimetableInfoResponse class definition
fd -t f 'TimetableInfoResponse.java'Repository: PERMIT-SEOUL/permit-server
Length of output: 179
🏁 Script executed:
#!/bin/bash
# Look at the AdminTimetableService file around line 99 to understand context
sed -n '85,115p' src/main/java/com/permitseoul/permitserver/domain/admin/timetable/base/api/service/AdminTimetableService.javaRepository: PERMIT-SEOUL/permit-server
Length of output: 1467
🏁 Script executed:
#!/bin/bash
# Examine TimetableInfoResponse class
cat src/main/java/com/permitseoul/permitserver/domain/admin/timetable/base/api/dto/res/TimetableInfoResponse.javaRepository: PERMIT-SEOUL/permit-server
Length of output: 1598
🏁 Script executed:
#!/bin/bash
# Check git history to see if eventId field was recently added
cd src/main/java/com/permitseoul/permitserver/domain/admin/timetable/base/api/dto/res && \
git log --oneline -20 -- TimetableInfoResponse.java 2>/dev/null || echo "Git history not available"Repository: PERMIT-SEOUL/permit-server
Length of output: 117
API 응답 구조 변경 사항을 검토하세요.
TimetableInfoResponse에 eventId 필드가 새로 추가되었으며, 이로 인해 기존 API 응답 구조가 변경되었습니다. 이 변경사항은 API 응답 스키마를 변경하므로, 클라이언트(프론트엔드, 외부 시스템 등)의 JSON 직렬화/역직렬화 로직에 영향을 미칠 수 있습니다. 버전 관리나 하위 호환성 유지 방안을 검토하세요.
🔥Pull requests
⛳️ 작업한 브랜치
👷 작업한 내용
🚨 참고 사항