Sprint 6 - 사용 처리_Redeemed_ 최소 구현 _ 내 기록_History_
목표
결제/정산/매장 앱이 없어도, 상태 흐름(issued→reserved→redeemed/expired)을 운영 가능한 형태로 닫는다.
Sprint 6에서는 “redeemed의 완전한 진실”보다 “기록/운영 가능성”이 우선이다.
원칙
redeemed는 사용자 앱에서 임의로 누르지 않는다(부정 사용 위험).
MVP에서도 redeemed를 최종 확정 상태로 운영하며, 데이터 모델과 화면은 동일하게 유지한다.
S6-1 내 기록(History) 화면 데이터 모델 확정
목적
사용자 관점에서 “내가 확보한 것들이 어디로 갔는지”가 보이게 한다.
작업
HistoryItem 타입 정의
reservationId
slotSummary(시간/혜택/매장)
status(reserved/redeemed/expired/cancelled)
reservedAt, expiresAt, redeemedAt
조회 API 계약
- listMyReservations(limit, cursor?, statusFilter?)
완료 조건
HistoryScreen이 이 타입만 의존
상태별로 표시가 안정적으로 분기됨
S6-2 HistoryScreen UI 구현(상태별 섹션 또는 필터)
목적
탐색을 길게 하지 않고, “현재 의미 있는 것”을 먼저 보여준다.
권장 구성(초기)
상단: 진행 중(Reserved/Arrived)
하단: 지난 기록(Expired/Redeemed)
작업
상태별 배지/문구(절제)
항목 클릭 시 SlotDetail 또는 ReservationDetail로 이동(선택)
빈 상태 처리(기록 없음)
완료 조건
reserved가 항상 상단에 보임
expired/redeemed는 기록으로만 존재
S6-3 예약 상세(ReservationDetail) 최소 화면(선택)
목적
지원/운영 대응을 위해 “단일 예약”을 자세히 볼 수 있게 한다.
작업
reservationId 표시(짧은 형태)
상태 타임라인(Reserved → Arrived → Redeemed/Expired)
만료/도착 시각 표시
문제 발생 시 “지원용 정보 복사” 버튼(선택)
완료 조건
- 예약 하나를 열었을 때 상태와 시각이 확인 가능
S6-4 redeemed 전환 방식 결정(MVP 안전버전)
목적
부정 사용을 막으면서도 운영 가능성을 확보한다.
MVP 안전 선택지
A안: “매장 확인 코드(Staff PIN)” 입력으로 redeemed
가맹점마다 PIN 1개 발급(관리자 페이지에서 설정)
사용자가 결제 시 직원에게 보여주고 직원이 PIN을 입력(사용자 앱에서 입력)
PIN은 주기적 변경 가능(Phase 2)
B안: redeemed는 MVP에서 미구현(Arrived까지만)
- 다만 DB/화면은 redeemed 상태를 표시 가능하게 준비
권장
초기에는 B안으로 시작해도 된다(운영은 reserved/expired 흐름만으로도 충분히 검증 가능)
단, “사용 완료”의 개념이 필요하면 A안이 가장 단순
이 스프린트에서는 우선 A/B 중 하나를 선택해 구현한다.
(이미 티켓화는 둘 다 포함하되, 실제 구현은 한 쪽만 진행)
S6-5 (A안 선택 시) redeemed API 계약 및 구현
목적
redeemed 전환도 서버에서 검증한다.
작업
입력
reservationId
merchantPin
검증
reservation.status == reserved
merchantPin 일치
이미 redeemed면 idempotent 처리
출력
- updatedReservation(status=redeemed, redeemedAt)
완료 조건
reserved 상태에서만 redeemed 가능
PIN 틀리면 명확한 실패 reason 반환
중복 호출에도 상태가 깨지지 않음
S6-6 (A안 선택 시) Arrived 화면에 “사용 확인” 진입 추가
목적
사용자에게 “이제 끝내는 단계”가 있음을 제공하되, 소비 유도 형태가 되지 않게 한다.
작업
Arrived 상태 화면에 작은 버튼:
- “사용 확인(직원 요청 시)”
PIN 입력 UI(단순)
성공 시 redeemed 완료 안내 + History로 이동
완료 조건
사용 확인 흐름이 reserved 상태에서만 보임
실패 시 재시도는 가능하되 과도한 안내/강조 없음
S6-7 (B안 선택 시) redeemed 미구현 플래그 및 UI 처리
목적
redeemed가 없어도 UX가 애매해지지 않게 한다.
작업
Arrived 상태 화면에:
- “계산 시 이 화면을 보여주세요(임시)” 같은 최소 안내
서버에서 redeemed 상태가 생기면 History에서 표시만 가능하도록 준비
완료 조건
redeemed가 없어도 사용자는 무엇을 하면 되는지 이해 가능
앱이 “완료 버튼”을 강요하지 않음
S6-8 이벤트 로깅(히스토리/사용)
목적
운영 데이터가 이어지게 한다.
로그 이벤트(최소)
history_view
reservation_detail_view
redeem_attempt (A안일 때)
redeem_success / redeem_fail(reason)
완료 조건
히스토리 조회가 로그로 남음
redeemed가 있으면 성공/실패가 남음
Sprint 6 완료 정의
다음이 가능해야 한다.
사용자는 내 예약 기록(reserved/redeemed/expired/cancelled)을 확인 가능
진행 중 예약이 상단에 보이며, 상태 흐름이 이해 가능
redeemed는
안전한 방식으로 최소 구현(A안) 또는
MVP에선 제외(B안)하되 구조적으로 열어둠