Skip to content

Commit 79a68c4

Browse files
Merge pull request #210 from SSASINSA/refactor/209_staff_code
refactor: 스태프 코드 재발급/조회 권한 변경 (#209)
2 parents 6ed2803 + 7ccc018 commit 79a68c4

6 files changed

Lines changed: 53 additions & 21 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@
188188

189189
## 관리자 행사 스태프 코드 API
190190

191-
행사 담당 관리자(organizerAdmin) 다음 API로 현장 스태프용 6자리 숫자 코드를 관리합니다. 코드는 DB `event.staff_code` 컬럼에 저장되며 만료 시간 없이 유지됩니다.
191+
행사 담당 관리자(organizerAdmin) 또는 ADMIN/SUPER_ADMIN 역할의 관리자는 다음 API로 현장 스태프용 6자리 숫자 코드를 관리합니다. 코드는 DB `event.staff_code` 컬럼에 저장되며 만료 시간 없이 유지됩니다.
192192

193193
- **POST** `/api/v1/admin/events/{eventId}/staff-code`
194194
- 새 6자리 숫자 코드를 발급하고 기존 코드가 있다면 즉시 대체합니다.
@@ -200,9 +200,9 @@
200200
"issuedAt": "2025-02-01T10:15:20Z"
201201
}
202202
```
203-
- organizerAdmin이 아닌 사용자가 호출하면 `E1024`가 반환됩니다.
203+
- MANAGER 역할 사용자는 organizerAdmin 본인일 때만 호출할 수 있으며, 그렇지 않거나 미인증인 경우 `E1024`가 반환됩니다. ADMIN/SUPER_ADMIN은 행사 담당자가 아니어도 호출할 수 있습니다.
204204
- **GET** `/api/v1/admin/events/{eventId}/staff-code`
205-
- 이미 발급된 스태프 코드를 조회합니다.
205+
- 이미 발급된 스태프 코드를 조회합니다. ADMIN/SUPER_ADMIN은 담당자가 아니어도 조회할 수 있으며, MANAGER는 organizerAdmin 본인일 때만 가능합니다.
206206
- 코드가 없다면 `E1025` 에러가 발생합니다.
207207

208208
발급·조회는 모두 관리자 인증 토큰이 필요하며, 응답의 `issuedAt`은 UTC 기준입니다.

src/main/java/com/ssasinsa/wearagain/domain/event/controller/EventAdminController.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ public ResponseEntity<EventStaffCodeResponse> issueStaffCode(
142142
@PathVariable Long eventId,
143143
@AuthenticationPrincipal AdminAuthenticatedUser principal
144144
) {
145-
EventStaffCodeResponse response = eventAdminService.issueStaffCode(eventId, principal.adminId());
145+
EventStaffCodeResponse response = eventAdminService.issueStaffCode(
146+
eventId,
147+
principal.adminId(),
148+
principal.role()
149+
);
146150
return ResponseEntity.ok(response);
147151
}
148152

@@ -152,7 +156,11 @@ public ResponseEntity<EventStaffCodeResponse> getStaffCode(
152156
@PathVariable Long eventId,
153157
@AuthenticationPrincipal AdminAuthenticatedUser principal
154158
) {
155-
EventStaffCodeResponse response = eventAdminService.getStaffCode(eventId, principal.adminId());
159+
EventStaffCodeResponse response = eventAdminService.getStaffCode(
160+
eventId,
161+
principal.adminId(),
162+
principal.role()
163+
);
156164
return ResponseEntity.ok(response);
157165
}
158166

src/main/java/com/ssasinsa/wearagain/domain/event/docs/EventApiDocs.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,9 @@ private EventApiDocs() {
127127
@ApiDoc(
128128
summary = "행사 스태프 코드 발급",
129129
description = """
130-
행사 담당 관리자(organizerAdmin)가 현장 스태프용 6자리 숫자 코드를 발급합니다.
131-
발급 시 기존 코드는 즉시 대체되며, 응답에는 새 코드와 발급 시각이 포함됩니다.
130+
행사 담당 관리자(organizerAdmin) 또는 ADMIN/SUPER_ADMIN 권한의 관리자가
131+
현장 스태프용 6자리 숫자 코드를 발급합니다. 발급 시 기존 코드는 즉시 대체되며,
132+
응답에는 새 코드와 발급 시각이 포함됩니다.
132133
""",
133134
responseSchema = EventStaffCodeResponse.class,
134135
responseExample = EventExamples.ADMIN_EVENT_STAFF_CODE_RESPONSE
@@ -142,8 +143,9 @@ private EventApiDocs() {
142143
@ApiDoc(
143144
summary = "행사 스태프 코드 조회",
144145
description = """
145-
이미 발급된 스태프 코드를 조회합니다.
146-
organizerAdmin 본인만 접근할 수 있으며, 아직 코드가 없다면 404를 반환합니다.
146+
이미 발급된 스태프 코드를 조회합니다. ADMIN/SUPER_ADMIN 권한은 담당자가
147+
아니어도 접근할 수 있으며, MANAGER 권한은 organizerAdmin 본인일 때만 허용됩니다.
148+
아직 코드가 없다면 404를 반환합니다.
147149
""",
148150
responseSchema = EventStaffCodeResponse.class,
149151
responseExample = EventExamples.ADMIN_EVENT_STAFF_CODE_RESPONSE

src/main/java/com/ssasinsa/wearagain/domain/event/service/EventAdminService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ EventAdminListResponse getEvents(
3131

3232
void archiveEvent(Long eventId);
3333

34-
EventStaffCodeResponse issueStaffCode(Long eventId, Long adminId);
34+
EventStaffCodeResponse issueStaffCode(Long eventId, Long adminId, AdminRole role);
3535

36-
EventStaffCodeResponse getStaffCode(Long eventId, Long adminId);
36+
EventStaffCodeResponse getStaffCode(Long eventId, Long adminId, AdminRole role);
3737

3838
EventApprovalRequestPageResponse getPendingApprovalRequests(
3939
int page,

src/main/java/com/ssasinsa/wearagain/domain/event/service/EventAdminServiceImpl.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,10 @@ public void archiveEvent(Long eventId) {
400400

401401
@Override
402402
@Transactional
403-
public EventStaffCodeResponse issueStaffCode(Long eventId, Long adminId) {
403+
public EventStaffCodeResponse issueStaffCode(Long eventId, Long adminId, AdminRole role) {
404404
Event event = eventRepository.findById(eventId)
405405
.orElseThrow(() -> new EventException(EventErrorCode.EVENT_NOT_FOUND));
406-
enforceStaffCodePermission(event, adminId);
406+
enforceStaffCodePermission(event, adminId, role);
407407

408408
String staffCode = generateStaffCode();
409409
LocalDateTime issuedAt = LocalDateTime.now(ZoneOffset.UTC);
@@ -414,10 +414,10 @@ public EventStaffCodeResponse issueStaffCode(Long eventId, Long adminId) {
414414

415415
@Override
416416
@Transactional(readOnly = true)
417-
public EventStaffCodeResponse getStaffCode(Long eventId, Long adminId) {
417+
public EventStaffCodeResponse getStaffCode(Long eventId, Long adminId, AdminRole role) {
418418
Event event = eventRepository.findById(eventId)
419419
.orElseThrow(() -> new EventException(EventErrorCode.EVENT_NOT_FOUND));
420-
enforceStaffCodePermission(event, adminId);
420+
enforceStaffCodePermission(event, adminId, role);
421421

422422
if (!StringUtils.hasText(event.getStaffCode())) {
423423
throw new EventException(EventErrorCode.EVENT_STAFF_CODE_NOT_ISSUED);
@@ -910,10 +910,13 @@ private void resetApprovalRequest(Event event) {
910910
approvalRequest.reopen(organizer);
911911
}
912912

913-
private void enforceStaffCodePermission(Event event, Long adminId) {
914-
if (adminId == null) {
913+
private void enforceStaffCodePermission(Event event, Long adminId, AdminRole role) {
914+
if (adminId == null || role == null) {
915915
throw new EventException(EventErrorCode.EVENT_STAFF_CODE_FORBIDDEN);
916916
}
917+
if (role == AdminRole.ADMIN || role == AdminRole.SUPER_ADMIN) {
918+
return;
919+
}
917920
AdminUser organizer = event.getOrganizerAdmin();
918921
if (organizer == null || organizer.getId() == null || !organizer.getId().equals(adminId)) {
919922
throw new EventException(EventErrorCode.EVENT_STAFF_CODE_FORBIDDEN);

src/test/java/com/ssasinsa/wearagain/domain/event/service/EventAdminServiceImplTest.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ void should_issue_staff_code_when_request_by_organizer() {
260260
when(eventRepository.findWithDetailsById(101L)).thenReturn(java.util.Optional.of(event));
261261
when(eventRepository.findById(101L)).thenReturn(java.util.Optional.of(event));
262262

263-
EventStaffCodeResponse response = eventAdminService.issueStaffCode(101L, 11L);
263+
EventStaffCodeResponse response = eventAdminService.issueStaffCode(101L, 11L, AdminRole.MANAGER);
264264

265265
assertThat(response.eventId()).isEqualTo(101L);
266266
assertThat(response.staffCode()).matches("\\d{6}");
@@ -273,17 +273,26 @@ void should_issue_staff_code_when_request_by_organizer() {
273273
void should_fail_issue_staff_code_when_not_organizer() {
274274
when(eventRepository.findById(101L)).thenReturn(java.util.Optional.of(event));
275275

276-
assertThatThrownBy(() -> eventAdminService.issueStaffCode(101L, 999L))
276+
assertThatThrownBy(() -> eventAdminService.issueStaffCode(101L, 999L, AdminRole.MANAGER))
277277
.isInstanceOf(EventException.class)
278278
.hasFieldOrPropertyWithValue("errorCode", EventErrorCode.EVENT_STAFF_CODE_FORBIDDEN);
279279
}
280280

281+
@Test
282+
void should_allow_admin_roles_to_issue_staff_code_even_when_not_organizer() {
283+
when(eventRepository.findById(101L)).thenReturn(java.util.Optional.of(event));
284+
285+
EventStaffCodeResponse response = eventAdminService.issueStaffCode(101L, 999L, AdminRole.ADMIN);
286+
287+
assertThat(response.staffCode()).matches("\\d{6}");
288+
}
289+
281290
@Test
282291
void should_get_staff_code_when_exists() {
283292
event.updateStaffCode("123456", LocalDateTime.now(ZoneOffset.UTC));
284293
when(eventRepository.findById(101L)).thenReturn(java.util.Optional.of(event));
285294

286-
EventStaffCodeResponse response = eventAdminService.getStaffCode(101L, 11L);
295+
EventStaffCodeResponse response = eventAdminService.getStaffCode(101L, 11L, AdminRole.MANAGER);
287296

288297
assertThat(response.staffCode()).isEqualTo("123456");
289298
assertThat(response.issuedAt()).isNotNull();
@@ -293,11 +302,21 @@ void should_get_staff_code_when_exists() {
293302
void should_fail_get_staff_code_when_not_issued() {
294303
when(eventRepository.findById(101L)).thenReturn(java.util.Optional.of(event));
295304

296-
assertThatThrownBy(() -> eventAdminService.getStaffCode(101L, 11L))
305+
assertThatThrownBy(() -> eventAdminService.getStaffCode(101L, 11L, AdminRole.MANAGER))
297306
.isInstanceOf(EventException.class)
298307
.hasFieldOrPropertyWithValue("errorCode", EventErrorCode.EVENT_STAFF_CODE_NOT_ISSUED);
299308
}
300309

310+
@Test
311+
void should_allow_admin_roles_to_get_staff_code_even_when_not_organizer() {
312+
event.updateStaffCode("654321", LocalDateTime.now(ZoneOffset.UTC));
313+
when(eventRepository.findById(101L)).thenReturn(java.util.Optional.of(event));
314+
315+
EventStaffCodeResponse response = eventAdminService.getStaffCode(101L, 999L, AdminRole.SUPER_ADMIN);
316+
317+
assertThat(response.staffCode()).isEqualTo("654321");
318+
}
319+
301320
@Test
302321
void should_list_events_with_statistics() {
303322
PageImpl<Event> pageResult = new PageImpl<>(List.of(event), PageRequest.of(0, 10), 20);

0 commit comments

Comments
 (0)