001. Domain Specification Document
# LEGACY NOTICE
- ??: Superseded
- Superseded By: ADR-DS-010, ADR-DS-012, ADR-DS-064, ADR-DS-060~065
- ??: ? ?? ?? ?? ?? ?? ??, ?? ?? ?? ADR ?? ????.
0. 문서 목적
이 문서는 다음을 명확히 정의한다:
핵심 도메인 객체
상태 정의
상태 전이 규칙
계산 규칙
예외 처리 규칙
동시성 원칙
이 문서는 기능 설명 문서가 아니다.
이 문서는 시스템의 행동을 고정하는 문서다.
1. 핵심 도메인 객체
1.1 User
속성
userId
createdAt
status (active | limited | suspended)
penaltyLevel
activeReservationId (nullable)
제약
- 동시에 activeReservation은 1개만 허용
1.2 Merchant
속성
merchantId
subscriptionPlan
subscriptionStatus (active | past_due | canceled)
createdAt
1.3 Slot
슬롯은 “시간 기회”다.
상품이 아니다.
속성
slotId
merchantId
startAt
endAt
totalQuantity
remainingQuantity
benefitText
createdAt
status (issued | closed)
상태 설명
issued
→ 사용 가능 상태
closed
→ 시간 종료 또는 수동 종료
1.4 Reservation
속성
reservationId
slotId
userId
status
reserved
redeemed
expired
cancelled
reservedAt
expiresAt
redeemedAt (nullable)
1.5 Penalty
속성
userId
level (0,1,2,3)
activeUntil
reserveExpiresMinutesOverride (nullable)
2. 상태 정의
2.1 Slot 상태
| 상태 | 의미 |
|---|---|
| issued | 시간 범위 내, 발행 상태 |
| closed | 시간 종료 또는 수량 소진 |
2.2 Reservation 상태
| 상태 | 의미 |
|---|---|
| reserved | 15분 임시 확보 |
| redeemed | 사용 완료 |
| expired | 유효시간 초과 자동 해제 |
| cancelled | 사용자/정책 취소 |
3. 상태 전이 규칙
3.1 Reservation 전이
issued (slot) → reserved
reserved → redeemed
reserved → expired
reserved → cancelled
금지 전이:
expired → any
expired → redeemed
redeemed → any
cancelled → any
3.2 만료 규칙
조건:
if now > expiresAt AND status == reserved
→ expired
만료는 서버 기준 시간으로 처리한다.
4. 수량 차감 규칙
수량 차감은 다음 조건에서만 수행한다:
if reservation.status transitions to redeemed
AND slot.remainingQuantity > 0
→ remainingQuantity -= 1
reserved 상태에서는 수량 차감 금지
동시성 규칙:
트랜잭션 내에서 remainingQuantity > 0 확인
차감과 상태 변경을 원자적으로 수행
5. 발행 제한 계산 규칙
5.1 “월 20회” 정의
슬롯 1개 생성 = 1회
수량 10개여도 1회
5.2 동일 조건 재발행 정의
다음이 모두 동일하면 동일 조건으로 간주:
merchantId 동일
startAt 동일 시간대 범위
benefitText 동일
업종 동일
재발행 최소 간격:
Basic: 4시간
Pro: 2시간
Premium: 1시간
6. 확보 규칙
6.1 activeReservation 제한
if user.activeReservation exists AND status == reserved
→ 신규 reserved 생성 불가
6.2 제재 적용
if penalty.activeUntil > now
→ reserved 생성 불가
if penalty.reserveExpiresMinutesOverride exists
→ expiresAt = reservedAt + overrideMinutes
7. 사용 확정 규칙
조건:
reservation.status == reserved
now <= expiresAt
distance(userLocation, merchantLocation) <= USAGE_VERIFY_RADIUS
locationAccuracy <= MAX_ALLOWED_ACCURACY
성공 시:
reservation.status → redeemed
slot.remainingQuantity -= 1
8. 동시성 원칙
모든 상태 변경은 서버에서 수행
수량 차감은 트랜잭션
클라이언트는 상태를 “제안”할 수 있으나 “확정”하지 못한다
9. 예외 처리 원칙
만료 직전 사용 확정 시 서버 기준 우선
네트워크 실패 시 상태 재조회
중복 요청은 idempotent 처리
10. 구조적 불변 조건 (Invariants)
다음은 항상 참이어야 한다:
remainingQuantity ≥ 0
하나의 reservation은 동시에 두 상태를 가질 수 없다
redeemed 수 ≤ totalQuantity
redeemed 이후에는 expired가 발생할 수 없다
user.activeReservation은 1개 이하
이 문서는 1차 버전이다.
다음 단계는 이 문서를 더 단단하게 만드는 것이다:
상태 전이 표를 수학적으로 더 엄격히 만들기
시간 경계 조건(동일 초 단위 등) 정의
테스트 케이스 목록으로 변환
이제 묻겠다.
이 수준에서 더 깊이 파고들까?
아니면 발행 제한 수학부터 더 정밀하게 정의할까?