Skip to content

[FEAT] 부스 예약 : 관리자 승인 및 QR 발급 Saga 구현#25

Merged
dldusgh318 merged 5 commits into
mainfrom
feat/booth-approbal
May 26, 2026
Merged

[FEAT] 부스 예약 : 관리자 승인 및 QR 발급 Saga 구현#25
dldusgh318 merged 5 commits into
mainfrom
feat/booth-approbal

Conversation

@dldusgh318
Copy link
Copy Markdown
Owner

‼️ 관련 이슈

close #7


🔎 개요

부스 예약 Saga에서 관리자 승인 및 QR 발급 흐름을 구현했습니다.
관리자가 승인 대기 예약을 승인하면 예약 상태가 RESERVED로 전환되고, QR 스캔 시 예약 확인 화면으로 이동할 수 있습니다.


📝 작업 내용

Backend

  • 관리자 예약 신청 목록 조회 API 추가

    • GET /api/admin/booth-reservations/pending
  • 관리자 예약 승인 API 추가

    • POST /api/admin/booth-reservations/{reservationId}/approve
    • PENDING_APPROVAL 상태 예약만 승인 가능
    • 승인 후 QR 발급 성공 시 RESERVED 상태로 전환
  • 예약 단건 조회 API 추가

    • GET /api/booth-reservations/{reservationId}
    • QR 스캔 후 예약 확인 화면에서 사용
  • QR 발급 로직 추가

    • QR payload를 예약 확인 URL로 발급
    • 예: http://localhost:3000/booths/reservations/{reservationId}
  • Saga 진행 상태 응답 추가

    • 승인 응답의 sagaLogsAPPROVED, QR_ISSUED 단계 포함

Frontend

  • 관리자 예약 승인 화면 추가

    • /booths/admin/reservations
    • 승인 대기 예약 목록 조회
    • 예약 승인 및 QR 발급
    • 승인 완료 예약의 QR 표시
  • QR 예약 확인 화면 추가

    • /booths/reservations/[reservationId]
    • QR 스캔 후 예약 상태, 신청자, 부스, 테이블 정보 확인
  • 사용자 부스 화면 QR 표시 추가

    • /booths
    • RESERVED 예약에 실제 QR SVG 표시

Test / Docs

  • 관리자 승인 정상 흐름 테스트 추가
  • 승인 대상이 아닌 예약 승인 예외 테스트 추가
  • QR 발급 URL 생성 테스트 추가
  • QR 확인 화면 테스트 추가
  • Backend / Frontend README에 관리자 승인 방식, QR 흐름, 테스트 범위 문서화
  • AI 외부 행위자 처리 회고 메모 추가

👀 변경 사항

  • QR 값은 단순 문자열이 아니라 프론트 예약 확인 URL입니다.

    • 기본값: http://localhost:3000
    • BE 설정 app.frontend-base-url로 변경 가능
  • 관리자 승인 후 최종 예약 상태는 RESERVED입니다.

  • QR 확인 화면은 예약 단건 조회 API를 사용합니다.

    • GET /api/booth-reservations/{reservationId}
  • FE에서 실제 QR SVG 렌더링을 위해 qrcode.react 의존성을 추가했습니다.


📸 스크린샷 (Optional)

스크린샷 2026-05-25 00 51 43 스크린샷 2026-05-25 01 01 37 스크린샷 2026-05-25 01 01 56

@dldusgh318 dldusgh318 added this to the 부스 예약 기능 milestone May 24, 2026
@dldusgh318 dldusgh318 self-assigned this May 24, 2026
@dldusgh318 dldusgh318 added the enhancement New feature or request label May 24, 2026
Comment on lines +5 to +6
BoothReservationApplicationRequest,
BoothReservationApprovalRequest,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

공통으로 사용되는 타입이 아니라 API 호출에서만 사용하는 타입이라면, 기존 파일명들과의 일관성을 위해 api 폴더 내 booths.api.types.ts 파일로 분리하여 관리해두어도 좋을 것 같습니다!

@RestController
@RequestMapping("/api/admin/booth-reservations")
@RequiredArgsConstructor
public class AdminBoothReservationController {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

로그인 기능이 머지된 만큼, 어드민 계정에 대한 권한 분리와 페이지 접근 제한 기능도 함께 필요할 것 같습니다!
현재는 누구나 어드민 페이지에서 승인 및 QR 발급이 가능한 상태인데, 특정 계정에 관리자 권한(role)을 부여하고 해당 계정으로만 접근 가능하도록 처리하면 좋을 것 같아요!

예를 들어 회원가입/로그인 시 관리자 타입을 구분해서 저장하고, 프론트엔드에서는 proxy.ts를 사용해 관리자 권한이 있는 사용자만 /booths/admin/reservations 경로에 접근 가능하도록 제한하는 방식으로 구현하면 좋을 것 같습니다!

Comment on lines +47 to +51
LocalDateTime now = LocalDateTime.now();
reservation.approve(now);

String qrCode = qrCodeIssuer.issue(reservation);
reservation.reserve(qrCode, now);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

QR 발급 전에 reservation.approve(now)로 상태를 먼저 APPROVED로 변경하고 있어, QR 발급 과정에서 예외가 발생했을 때 상태 정합성이 깨질 수 있을 것 같습니다.

특히 현재 InMemoryBoothReservationDataSource가 예약 객체 참조를 그대로 반환하는 구조라면, update() 호출 전이라도 reservation.approve(now)에서 원본 객체의 상태가 APPROVED로 변경될 수 있습니다.
이후 qrCodeIssuer.issue(reservation)에서 예외가 발생하면 실제 예약 완료는 되지 않았지만 상태만 APPROVED로 남을 가능성이 있습니다.

따라서 QR 발급이 성공한 이후에 reserve()를 통해 한 번에 RESERVED 상태로 전환하거나, QR 발급 실패 시 PENDING_APPROVAL 상태로 롤백하는 보상 처리가 필요해 보입니다 !

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

발급 실패 이후 보상처리는, 다음 이슈&pr에서 처리할 예정입니다
이외의 코멘트들은 반영해두겠습니다!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

넹 확인했습니다~

</span>
{reservation.qrCode ? (
<span className="text-brand-mint-soft mt-2 block font-mono text-xs">
{reservation.qrCode}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

긴 QR URL이 flex 영역 안에서 줄바꿈되지 않아 카드 폭을 밀어내고 있습니다! 텍스트 컨테이너에 min-w-0, QR 문자열에 break-all을 주면 상태 배지 영역을 침범하지 않을 수 있을 것 같아요!

@dldusgh318 dldusgh318 force-pushed the feat/booth-approbal branch from 97e8ac9 to 5478efd Compare May 26, 2026 06:34
@dldusgh318 dldusgh318 merged commit cb6f598 into main May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 부스 예약 : 관리자 승인 및 QR 발급 Saga 구현

2 participants