Skip to content

Conversation

@sjk4618
Copy link
Member

@sjk4618 sjk4618 commented Jan 4, 2026

🔥Pull requests

⛳️ 작업한 브랜치

👷 작업한 내용

  • staff 권한 추가 및 security config 수정
  • door용 티켓 큐알 카메라 인증 api 구현

🚨 참고 사항

@sjk4618 sjk4618 self-assigned this Jan 4, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 4, 2026

📝 Walkthrough

Summary by CodeRabbit

  • 새로운 기능

    • QR 코드 상단에 이벤트 이름 표시(길면 말줄임 처리)
    • 스태프용 카메라 기반 티켓 확인 API 추가(게스트 및 일반 티켓)
  • 보안

    • 새로운 스태프 역할(STAFF) 추가
    • 스태프 전용 API 엔드포인트에 대한 접근 제어 규칙 추가

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

스태프 권한(STAFF) 추가, 스태프 대상 카메라 기반 티켓 확인 API(게스트·일반) 도입, QR 코드 생성 시 이벤트명 렌더링 기능 추가 및 관련 시큐리티 규칙(/api/staff/**) 적용.

Changes

Cohort / File(s) 변경 사항
QR 코드 이벤트명 렌더링
src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/api/service/AdminGuestTicketService.java, src/main/java/com/permitseoul/permitserver/domain/admin/util/QrCodeUtil.java
QR PNG 생성 흐름에 eventName 인수 추가. QrCodeUtil.generatePng(..., eventName) 도입, 이벤트명을 QR 이미지 상단에 렌더링하는 헬퍼(addEventNameOnTop, ellipsize) 및 텍스트 영역 상수 추가
게스트용 스태프 카메라 인증
src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestStaffController.java, src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/req/GuestTicketConfirmByCameraRequest.java, src/main/java/com/permitseoul/permitserver/domain/guest/api/service/GuestService.java
신규 GuestStaffController 추가 및 POST /api/staff/guests/tickets/door/confirm 엔드포인트 구현. DTO GuestTicketConfirmByCameraRequest 추가. 서비스에 confirmGuestTicketByStaffCamera(ticketCode) 메서드 추가 및 기존 confirmGuestTicketByStaffconfirmGuestTicketByStaffCheckCode로 명칭 변경
일반 티켓용 스태프 카메라 인증
src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketStaffController.java, src/main/java/com/permitseoul/permitserver/domain/ticket/api/dto/req/TicketConfirmByCameraRequest.java, src/main/java/com/permitseoul/permitserver/domain/ticket/api/service/TicketService.java
신규 TicketStaffController 추가 및 POST /api/staff/tickets/door/confirm 엔드포인트 구현. DTO TicketConfirmByCameraRequest 추가. 서비스에 confirmTicketByStaffCamera(ticketCode) 추가 및 confirmTicketByStaffconfirmTicketByStaffCode로 메서드명 변경, 티켓타입 조회/유효기간 검증 로직 분리
인증 및 권한 제어
src/main/java/com/permitseoul/permitserver/domain/user/core/domain/UserRole.java, src/main/java/com/permitseoul/permitserver/global/config/SecurityConfig.java
UserRoleSTAFF 상수 추가. SecurityConfig에 /api/staff/** 패턴을 위한 접근 규칙 추가(ROLE_STAFF 또는 ROLE_ADMIN 필요)
기존 컨트롤러 호출 업데이트
src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java, src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketController.java
기존 컨트롤러에서 호출하던 서비스 메서드명 변경 반영: confirmGuestTicketByStaffconfirmGuestTicketByStaffCheckCode, confirmTicketByStaffconfirmTicketByStaffCode 및 주석/설명 텍스트 일부 갱신

Sequence Diagram

sequenceDiagram
    autonumber
    participant Staff as 스태프(카메라)
    participant Controller as StaffController<br/>(Ticket/Guest)
    participant Service as Service<br/>(Ticket/Guest)
    participant Repo as TicketRepository
    participant TypeRepo as TicketTypeRepository

    Staff->>Controller: POST /api/staff/*/door/confirm { ticketCode }
    Controller->>Service: confirm*ByStaffCamera(ticketCode)
    Service->>Repo: findByCode(ticketCode)
    Repo-->>Service: Ticket / null

    alt 티켓 없음
        Service-->>Controller: NotFoundException
        Controller-->>Staff: 404
    else 티켓 존재
        Service->>TypeRepo: findTicketTypeById(typeId)
        TypeRepo-->>Service: TicketType
        Service->>Service: validateTicketDate(TicketType)
        alt 유효
            Service->>Repo: updateStatus(USED)
            Repo-->>Service: OK
            Service-->>Controller: 완료
            Controller-->>Staff: 200 OK
        else 유효하지 않음
            Service-->>Controller: ValidationError
            Controller-->>Staff: 4xx
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 door용 티켓 큐알 카메라 인증 API 구현 및 스태프 권한 추가라는 주요 변경사항을 명확하게 요약하고 있으며, 변경사항과 직접적으로 관련이 있습니다.
Description check ✅ Passed PR 설명은 staff 권한 추가, security config 수정, door용 티켓 큐알 카메라 인증 API 구현 등 변경사항과 관련된 내용을 포함하고 있습니다.
Linked Issues check ✅ Passed PR은 링크된 이슈 #206의 모든 코딩 요구사항을 충족합니다: door용 티켓 인증 API 구현 (TicketStaffController, GuestStaffController, 요청 DTO 추가), 스태프 권한 추가 (UserRole.STAFF), 보안 설정 적용 (SecurityConfig에 staffURIList 추가).
Out of Scope Changes check ✅ Passed 모든 변경사항이 링크된 이슈 #206의 범위 내에 있습니다: 스태프 권한 및 보안 설정, door용 티켓/게스트 인증 API, 관련 서비스 및 DTO 변경이 모두 명시된 목표와 일치합니다.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73dc525 and dcacc28.

📒 Files selected for processing (1)
  • src/main/java/com/permitseoul/permitserver/domain/ticket/api/dto/req/TicketConfirmByCameraRequest.java
🧰 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 (1)
src/main/java/com/permitseoul/permitserver/domain/ticket/api/dto/req/TicketConfirmByCameraRequest.java (1)

1-9: 이전 리뷰 의견이 반영되어 구현이 올바릅니다.

이전 리뷰에서 지적된 ticketCode 필드의 검증 어노테이션 누락 문제가 해결되었습니다. @NotBlank 어노테이션과 적절한 import 문(jakarta.validation.constraints.NotBlank)이 추가되어 있으며, 한글 에러 메시지도 명확합니다. 컨트롤러의 @Valid와 함께 정상적으로 작동합니다.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/permitseoul/permitserver/domain/ticket/api/service/TicketService.java (1)

127-163: 코드 중복 제거 필요

confirmTicketByStaffCodeconfirmTicketByStaffCamera 메서드가 거의 동일한 로직을 가지고 있습니다. 유일한 차이점은 체크 코드 검증(lines 135-136) 여부뿐입니다. 이는 DRY 원칙을 위반하며 유지보수 부담을 증가시킵니다.

🔎 공통 로직을 추출한 리팩토링 제안
+    private void confirmTicketByStaff(final String ticketCode, final boolean verifyCheckCode, final String checkCodeFromTicket) {
+        try {
+            final TicketEntity ticketEntity = ticketRetriever.findTicketEntityByTicketCode(ticketCode);
+            verifyTicketStatus(ticketEntity.getStatus());
+
+            final TicketType ticketType = findTicketTypeById(ticketEntity.getTicketTypeId());
+            verifyTicketDate(ticketType.getTicketStartAt(), ticketType.getTicketEndAt());
+
+            if (verifyCheckCode) {
+                final Event event = findEventById(ticketEntity.getEventId());
+                verifyTicketCheckCode(event.getTicketCheckCode(), checkCodeFromTicket);
+            }
+
+            ticketUpdater.updateTicketStatus(ticketEntity, TicketStatus.USED);
+        } catch (TicketNotFoundException  e) {
+            throw new NotFoundTicketException(ErrorCode.NOT_FOUND_TICKET);
+        } catch (TicketTypeNotfoundException e) {
+            throw new NotFoundTicketException(ErrorCode.NOT_FOUND_TICKET_TYPE);
+        } catch (EventNotfoundException e) {
+            throw new NotFoundTicketException(ErrorCode.NOT_FOUND_EVENT);
+        }
+    }
+
     @Transactional
     public void confirmTicketByStaffCode(final String ticketCode, final String checkCodeFromTicket) {
-        try {
-            final TicketEntity ticketEntity = ticketRetriever.findTicketEntityByTicketCode(ticketCode);
-            verifyTicketStatus(ticketEntity.getStatus());
-
-            final TicketType ticketType = findTicketTypeById(ticketEntity.getTicketTypeId());
-            verifyTicketDate(ticketType.getTicketStartAt(), ticketType.getTicketEndAt());
-
-            final Event event = findEventById(ticketEntity.getEventId());
-            verifyTicketCheckCode(event.getTicketCheckCode(), checkCodeFromTicket);
-
-            ticketUpdater.updateTicketStatus(ticketEntity, TicketStatus.USED);
-        } catch (TicketNotFoundException  e) {
-            throw new NotFoundTicketException(ErrorCode.NOT_FOUND_TICKET);
-        } catch (TicketTypeNotfoundException e) {
-            throw new NotFoundTicketException(ErrorCode.NOT_FOUND_TICKET_TYPE);
-        } catch (EventNotfoundException e) {
-            throw new NotFoundTicketException(ErrorCode.NOT_FOUND_EVENT);
-        }
+        confirmTicketByStaff(ticketCode, true, checkCodeFromTicket);
     }
 
     @Transactional
     public void confirmTicketByStaffCamera(final String ticketCode) {
-        try {
-            final TicketEntity ticketEntity = ticketRetriever.findTicketEntityByTicketCode(ticketCode);
-            verifyTicketStatus(ticketEntity.getStatus());
-
-            final TicketType ticketType = findTicketTypeById(ticketEntity.getTicketTypeId());
-            verifyTicketDate(ticketType.getTicketStartAt(), ticketType.getTicketEndAt());
-
-            ticketUpdater.updateTicketStatus(ticketEntity, TicketStatus.USED);
-        } catch (TicketNotFoundException  e) {
-            throw new NotFoundTicketException(ErrorCode.NOT_FOUND_TICKET);
-        } catch (TicketTypeNotfoundException e) {
-            throw new NotFoundTicketException(ErrorCode.NOT_FOUND_TICKET_TYPE);
-        }
+        confirmTicketByStaff(ticketCode, false, null);
     }
🧹 Nitpick comments (2)
src/main/java/com/permitseoul/permitserver/domain/admin/util/QrCodeUtil.java (1)

63-96: 폰트 설정 하드코딩 개선 권장

현재 폰트 이름("SansSerif")과 크기(15)가 하드코딩되어 있습니다. 시스템에 해당 폰트가 없을 경우 대체 폰트가 사용되지만, 더 명시적인 폰트 fallback 처리나 설정 가능한 상수로 관리하는 것이 좋습니다.

🔎 제안하는 개선사항

클래스 상단에 폰트 관련 상수를 추가:

+    private static final String FONT_NAME = "SansSerif";
+    private static final int FONT_SIZE = 15;
+    private static final int FONT_STYLE = Font.PLAIN;

그리고 사용처를 다음과 같이 변경:

-            g.setFont(new Font("SansSerif", Font.PLAIN, 15));
+            g.setFont(new Font(FONT_NAME, FONT_STYLE, FONT_SIZE));

추가로, 폰트 가용성 체크를 고려할 수 있습니다:

private static Font getAvailableFont() {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    String[] fonts = ge.getAvailableFontFamilyNames();
    if (Arrays.asList(fonts).contains(FONT_NAME)) {
        return new Font(FONT_NAME, FONT_STYLE, FONT_SIZE);
    }
    return new Font(Font.SANS_SERIF, FONT_STYLE, FONT_SIZE); // fallback
}
src/main/java/com/permitseoul/permitserver/domain/ticket/api/service/TicketService.java (1)

268-272: findTicketTypeAndVerifyTicketDate 메서드는 사용되지 않으므로 제거하세요

이 헬퍼 메서드는 현재 사용되지 않는 데드 코드입니다. 리팩토링 후 132-133줄과 171-172줄에서 개별 호출(findTicketTypeById() + verifyTicketDate())로 변경되었으며, 코드베이스 어디에도 이 메서드를 호출하는 곳이 없습니다. 제거를 권장합니다.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8183706 and 73dc525.

📒 Files selected for processing (12)
  • src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/api/service/AdminGuestTicketService.java
  • src/main/java/com/permitseoul/permitserver/domain/admin/util/QrCodeUtil.java
  • src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java
  • src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestStaffController.java
  • src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/req/GuestTicketConfirmByCameraRequest.java
  • src/main/java/com/permitseoul/permitserver/domain/guest/api/service/GuestService.java
  • src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketController.java
  • src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketStaffController.java
  • src/main/java/com/permitseoul/permitserver/domain/ticket/api/dto/req/TicketConfirmByCameraRequest.java
  • src/main/java/com/permitseoul/permitserver/domain/ticket/api/service/TicketService.java
  • src/main/java/com/permitseoul/permitserver/domain/user/core/domain/UserRole.java
  • src/main/java/com/permitseoul/permitserver/global/config/SecurityConfig.java
🧰 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 (2)
src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketStaffController.java (3)
src/main/java/com/permitseoul/permitserver/global/response/ApiResponseUtil.java (1)
  • ApiResponseUtil (7-29)
src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestStaffController.java (1)
  • RestController (13-28)
src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketController.java (1)
  • RestController (17-55)
src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestStaffController.java (4)
src/main/java/com/permitseoul/permitserver/global/response/ApiResponseUtil.java (1)
  • ApiResponseUtil (7-29)
src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java (1)
  • RestController (14-36)
src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketController.java (1)
  • RestController (17-55)
src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketStaffController.java (1)
  • RestController (16-30)
🔇 Additional comments (14)
src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketController.java (1)

44-44: LGTM!

메서드명 변경을 통해 코드 기반 확인과 카메라 기반 확인을 명확히 구분하고 있습니다.

src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java (1)

33-33: LGTM!

메서드명 변경을 통해 코드 기반 확인과 카메라 기반 확인을 명확히 구분하고 있습니다.

src/main/java/com/permitseoul/permitserver/global/config/SecurityConfig.java (1)

63-65: 스태프 엔드포인트 보안 설정이 올바르게 구성되었습니다.

staffURIList의 /api/staff/** 패턴과 보안 규칙(hasAnyRole(STAFF, ADMIN))이 올바르게 설정되었으며, 권한 규칙의 순서도 적절합니다.

GuestStaffController와 TicketStaffController 모두 /api/staff 기본 경로를 사용하여 /api/staff/** 보안 패턴과 일치하므로, 스태프 엔드포인트 보안이 제대로 구현되었습니다.

src/main/java/com/permitseoul/permitserver/domain/admin/guestticket/api/service/AdminGuestTicketService.java (1)

45-45: QR 코드에 이벤트명 추가 로직이 올바르게 구현되었습니다.

변경사항을 검증한 결과, QrCodeUtil.generatePng 메서드가 eventName 파라미터를 올바르게 처리하고 있습니다:

  • eventName이 null이거나 빈 문자열일 경우 원본 QR 이미지를 반환
  • eventName이 제공될 경우 [ eventName ] 형식으로 QR 코드 상단에 텍스트 영역을 추가하여 렌더링
  • 텍스트 길이가 초과하는 경우 말줄임표로 처리하는 안전한 구현
src/main/java/com/permitseoul/permitserver/domain/guest/api/dto/req/GuestTicketConfirmByCameraRequest.java (1)

5-8: LGTM!

필드 검증이 적절하게 적용되어 있습니다.

src/main/java/com/permitseoul/permitserver/domain/guest/api/service/GuestService.java (2)

60-70: 이벤트 검증 누락 확인 필요

confirmGuestTicketByStaffCheckCode와 달리 이 메서드는 이벤트 존재 여부를 검증하지 않습니다. 카메라 기반 인증에서는 이벤트 검증이 필요 없는지, 아니면 의도적으로 생략된 것인지 확인이 필요합니다.

만약 이벤트가 삭제된 후에도 티켓 사용이 가능해야 한다면 현재 구현이 맞지만, 그렇지 않다면 일관성을 위해 이벤트 검증을 추가하는 것이 좋습니다.


44-44: 메서드명 변경이 완전하게 적용됨

기존 메서드명(confirmGuestTicketByStaff)에 대한 참조가 모두 제거되었고, 새로운 메서드명(confirmGuestTicketByStaffCheckCode)으로 변경되었습니다. 추가 조치가 필요 없습니다.

src/main/java/com/permitseoul/permitserver/domain/admin/util/QrCodeUtil.java (2)

98-110: 텍스트 줄임 로직이 올바르게 구현되었습니다

긴 이벤트명을 적절히 줄여서 표시하는 로직이 정확합니다. FontMetrics를 활용한 너비 계산도 적절합니다.


36-36: 메서드 시그니처 변경이 올바르게 반영됨

generatePng 메서드에 추가된 eventName 매개변수는 유일한 호출처인 AdminGuestTicketService.java (67줄)에서 올바르게 반영되어 있습니다. 추가 업데이트는 필요하지 않습니다.

src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketStaffController.java (1)

16-29: 구현이 올바르게 되어 있습니다

컨트롤러 구조가 GuestStaffController와 일관성 있게 구현되었으며, TicketService.confirmTicketByStaffCamera 메서드도 @Transactional 어노테이션과 함께 올바르게 구현되어 있습니다.

src/main/java/com/permitseoul/permitserver/domain/ticket/api/service/TicketService.java (2)

127-127: 메서드명 변경 승인

코드 기반 확인과 카메라 기반 확인을 명확히 구분하기 위한 적절한 네이밍 개선입니다.


148-163: 카메라 기반 확인 로직 승인

카메라를 통한 QR 스캔 방식의 티켓 확인 로직이 올바르게 구현되었습니다. 체크 코드 검증을 생략하고 티켓 상태와 날짜만 검증하는 것이 적절합니다.

src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestStaffController.java (2)

13-28: 컨트롤러 구조 승인

스프링 MVC 패턴을 올바르게 따르고 있으며, TicketStaffController와 일관된 구조로 구현되었습니다. 요청 검증 및 응답 처리가 적절합니다.


13-20: 보안 설정이 올바르게 구성되어 있습니다.

SecurityConfig에서 /api/staff/** 패턴에 대해 .hasAnyRole(UserRole.STAFF.name(), UserRole.ADMIN.name())로 설정되어 있어, 이 엔드포인트는 URL 기반 접근 제어로 STAFF 또는 ADMIN 역할을 요구하도록 보호되어 있습니다. JWT 인증 필터를 통해 인증도 강제되므로 추가 보안 조치는 필요하지 않습니다.

}

//도어용 게스트 티켓 스텝 확인 api
//도어용 게스트 티켓 스텝 코드 확인 api
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

주석의 용어를 수정하세요.

"스텝"은 "스태프"(staff)의 오타로 보입니다. 일관된 용어 사용을 위해 수정이 필요합니다.

🔎 제안하는 수정
-    //도어용 게스트 티켓 스텝 코드 확인 api
+    //도어용 게스트 티켓 스태프 코드 확인 api
📝 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.

Suggested change
//도어용 게스트 티켓 스텝 코드 확인 api
//도어용 게스트 티켓 스태프 코드 확인 api
🤖 Prompt for AI Agents
In
src/main/java/com/permitseoul/permitserver/domain/guest/api/controller/GuestController.java
around line 28, the comment uses "스텝" which is a typo for "스태프"; update the
comment to use the correct term ("스태프") and ensure the full comment reads
clearly (e.g., "도어용 게스트 티켓 스태프 코드 확인 API") maintaining capitalization/spacing
consistent with project comment style.

}

//도어용 유저 티켓 스텝 확인 api
//도어용 유저 티켓 스텝 코드 확인 api
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

주석의 용어를 수정하세요.

"스텝"은 "스태프"(staff)의 오타로 보입니다. 일관된 용어 사용을 위해 수정이 필요합니다.

🔎 제안하는 수정
-    //도어용 유저 티켓 스텝 코드 확인 api
+    //도어용 유저 티켓 스태프 코드 확인 api
📝 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.

Suggested change
//도어용 유저 티켓 스텝 코드 확인 api
//도어용 유저 티켓 스태프 코드 확인 api
🤖 Prompt for AI Agents
In
src/main/java/com/permitseoul/permitserver/domain/ticket/api/controller/TicketController.java
around line 39, update the comment "//도어용 유저 티켓 스텝 코드 확인 api" to correct the
typo: replace "스텝" with "스태프" (staff) so the comment reads something like "//도어용
유저 티켓 스태프 코드 확인 api" to maintain consistent terminology across the codebase.

USER,
ADMIN,

STAFF
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for UserRole.STAFF usage and role assignment logic
rg -n --type=java 'UserRole\.STAFF|UserRole\.valueOf.*STAFF' -C 2

Repository: PERMIT-SEOUL/permit-server

Length of output: 867


🏁 Script executed:

#!/bin/bash
# Search for role assignment logic in user-related files
rg -n --type=java 'setRole|withRole|role\s*=' --glob='**/user/**/*.java' -C 2

Repository: PERMIT-SEOUL/permit-server

Length of output: 52


🏁 Script executed:

#!/bin/bash
# Look for User entity to understand role field
fd -e java --path '*/user/**' User | head -20 | xargs -I {} sh -c 'echo "=== {} ===" && head -50 {}'

Repository: PERMIT-SEOUL/permit-server

Length of output: 303


🏁 Script executed:

#!/bin/bash
# Search for database migration files
fd -e sql -e yml | grep -i migrat | head -20

Repository: PERMIT-SEOUL/permit-server

Length of output: 52


🏁 Script executed:

#!/bin/bash
# Check SecurityConfig for STAFF role usage
rg -n --type=java -C 5 'STAFF'

Repository: PERMIT-SEOUL/permit-server

Length of output: 2531


🏁 Script executed:

#!/bin/bash
# Find User entity definition
find . -type f -name "User.java" | xargs -I {} sh -c 'echo "=== {} ===" && cat -n {}'

Repository: PERMIT-SEOUL/permit-server

Length of output: 1328


🏁 Script executed:

#!/bin/bash
# Search for role field assignments in entity or service
rg -n --type=java 'role\s*[:=]|@Enumerated' -C 3 | head -100

Repository: PERMIT-SEOUL/permit-server

Length of output: 6738


🏁 Script executed:

#!/bin/bash
# Look for UserRepository and role-related methods
rg -n --type=java 'class.*UserRepository|interface.*UserRepository' -A 20

Repository: PERMIT-SEOUL/permit-server

Length of output: 1542


🏁 Script executed:

#!/bin/bash
# Search for any SQL files or initialization data
find . -type f \( -name "*.sql" -o -name "data.sql" -o -name "*init*.sql" \) -exec echo "=== {} ===" \; -exec cat {} \;

Repository: PERMIT-SEOUL/permit-server

Length of output: 52


🏁 Script executed:

#!/bin/bash
# Search for UserService or service classes handling user creation/updates
rg -n --type=java 'class.*UserService|interface.*UserService' -A 30

Repository: PERMIT-SEOUL/permit-server

Length of output: 3926


🏁 Script executed:

#!/bin/bash
# Search for methods setting userRole in the entire codebase
rg -n --type=java 'setUserRole|userRole\s*=' -C 3

Repository: PERMIT-SEOUL/permit-server

Length of output: 2859


🏁 Script executed:

#!/bin/bash
# Check UserEntity for any builder or constructor that might handle role assignment
cat -n src/main/java/com/permitseoul/permitserver/domain/user/core/domain/entity/UserEntity.java | head -80

Repository: PERMIT-SEOUL/permit-server

Length of output: 2995


🏁 Script executed:

#!/bin/bash
# Search more broadly for migration-related files
find . -type f \( -name "*.sql" -o -name "*.yml" -o -name "*migration*" -o -name "*Flyway*" \) | grep -v node_modules | grep -v ".git"

Repository: PERMIT-SEOUL/permit-server

Length of output: 52


🏁 Script executed:

#!/bin/bash
# Check for any Setter methods or update methods for userRole in UserEntity
rg -n --type=java 'void.*[Uu]pdate|void.*[Ss]et' src/main/java/com/permitseoul/permitserver/domain/user/

Repository: PERMIT-SEOUL/permit-server

Length of output: 411


🏁 Script executed:

#!/bin/bash
# Look for any command or use case classes that might handle role assignment
rg -n --type=java 'class.*Command|class.*UseCase' src/main/java/com/permitseoul/permitserver/domain/user/ -A 5

Repository: PERMIT-SEOUL/permit-server

Length of output: 52


기존 사용자에게 STAFF 역할을 할당하는 메커니즘이 필요합니다.

STAFF 역할이 올바르게 정의되고 SecurityConfig에서 적절히 사용되고 있으며, UserEntity의 스키마도 이미 userRole 필드를 지원합니다. 그러나 신규 사용자 생성 시에만 역할을 설정할 수 있고, 기존 사용자에게 STAFF 역할을 할당하거나 업데이트하는 메서드가 없습니다. UserEntity와 UserService에 역할 업데이트 기능(예: updateUserRole())을 추가하고, 필요하다면 해당 관리 API를 구현해주세요.

🤖 Prompt for AI Agents
In
src/main/java/com/permitseoul/permitserver/domain/user/core/domain/UserRole.java
around line 6, the STAFF enum constant exists but there is no mechanism to
assign or update STAFF for existing users; add a role-update flow: add an
updateUserRole(UserId, UserRole) method in UserService that loads the
UserEntity, validates permission/state, sets the userRole field on the entity
and persists the change (use repository.save or entity manager as appropriate),
and add a corresponding method on UserEntity (e.g., setUserRole(UserRole)) if
missing; finally expose a secured admin API endpoint in the controller to call
UserService.updateUserRole, validate inputs, authorize only permitted roles, and
return the updated user DTO.

@sjk4618 sjk4618 merged commit 2592dcc into dev Jan 4, 2026
2 checks passed
@sjk4618 sjk4618 deleted the feat/#206 branch January 4, 2026 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: door용 티켓 큐알 카메라 인증 api 구현 및 스태프 권한 추가

2 participants