Skip to main content

Documentation Index

Fetch the complete documentation index at: https://api-docs.vpms.io/llms.txt

Use this file to discover all available pages before exploring further.

개요

기존 ARI(Rate / Period / Package / Inclusion) 4개 도메인을 폐기하고, 글로벌 PMS 표준에 맞춰 RatePlan(설정) + DailyRate(일별 판매가 snapshot) + Restriction(판매 통제) 구조로 재설계했습니다. 설계 결정은 ADR-0001, ADR-0002 참고. 핵심 개념:
  • RatePlan: 요금제 설정. defaultAmount + pricingRules(요일/시즌 가산치) 가 “레시피”.
  • DailyRate: 특정 (ratePlanId, roomTypeId, stayDate)확정 최종 판매가 snapshot. 단순 override 가 아니라 예약 엔진·OTA 에 노출되는 영속 값.
  • Master-Derived: parentRatePlanId + derivationRule 로 파생 요금제.
  • Restriction: 날짜별 CTA/CTD/StopSell/LOS 통제.
  • RematerializationProposal: 규칙 변경 시 기존 snapshot 을 자동 덮어쓰지 않고 사용자 승인 후 재물질화.

Queries

getRatePlanList

특정 숙박 시설의 요금제 목록 조회.
query GetRatePlans($accommodationId: ID!) {
  getRatePlanList(accommodationId: $accommodationId, isActive: true) {
    id
    code
    name
    type
    baseOccupancy
    defaultAmount
    currency
    pricingRules
    parentRatePlanId
  }
}

getRatePlan

단일 요금제 상세 (occupancyPrices / inclusions / channelMappings / roomTypes 포함).
query GetRatePlan($id: ID!) {
  getRatePlan(id: $id) {
    id
    code
    name
    defaultAmount
    pricingRules
    occupancyPrices { occupancy amount pricingMode }
    inclusions { inclusion { name } quantity chargeOverride }
    channelMappings { channel { name } externalCode adjustmentOp adjustmentValue }
    roomTypes { id name }
  }
}

getDailyRateCalendar

캘린더 그리드 조회. 각 셀은 snapshot 존재 여부(hasSnapshot)와 해석 경로(resolutionSource)를 반환.
query Calendar($ratePlanId: ID!, $roomTypeId: ID!, $start: Date!, $end: Date!) {
  getDailyRateCalendar(
    ratePlanId: $ratePlanId
    roomTypeId: $roomTypeId
    startDate: $start
    endDate: $end
  ) {
    stayDate
    amount
    currency
    resolutionSource   # daily_rate_snapshot | derived_from_parent | default_with_rules
    hasSnapshot
    ratePlanChain
  }
}

resolveDailyRate

단일 날짜·점유 인원 기준 해석 가격을 반환. occupancy 변경 시뮬레이션에 사용.

getRatePlanRestrictions

날짜 범위의 restriction 목록 (CTA/CTD/StopSell/MinLOS/MaxLOS).

getInclusionList

시설 별 inclusion(부가서비스) 카탈로그.

getRematerializationProposal

규칙 변경 후 생성된 영향 범위 분석 결과 조회. 사용자에게 “재물질화 진행/폐기” 선택 UI 에 사용.

Mutations

createRatePlan / updateRatePlan / deleteRatePlan

요금제 CRUD. update 의 defaultAmount / pricingRules / derivationRule 변경 시 기존 미래 DailyRate snapshot 을 자동 변경하지 않는다 (ADR-0001 §2.2.2). 대신 RematerializationProposal 이 자동 생성되며 사용자가 별도로 승인해야 적용된다.

DailyRate set / clear

  • setDailyRate(input): 단일 (roomTypeId, stayDate) 셀 가격 확정.
  • setDailyRateBulk(input): 범위 × roomType[] 일괄 설정. amount / amountDelta / amountPercentDelta 택 1. overrideExisting: false 면 빈 날짜만 채움.
  • clearDailyRate(...): 단일 snapshot 삭제 → 규칙 계산값 복귀.
  • clearDailyRateBulk(...): 범위 일괄 삭제. 시즌 reset 등 사용.

Restriction set / clear

  • setRatePlanRestriction(input): 단일 날짜.
  • setRatePlanRestrictionBulk(input): 범위 × roomType[] 일괄 설정.
  • clearRatePlanRestriction(...) / clearRatePlanRestrictionBulk(...).

RatePlan 하위 엔티티 전량 교체 (wizard 단계 지원)

  • setRatePlanOccupancyPrices(ratePlanId, prices[]) — wizard step 3.
  • setRatePlanInclusions(ratePlanId, inclusions[]) — wizard step 5.
  • setRatePlanChannelMappings(ratePlanId, mappings[]). 모두 기존 항목 전량 제거 후 입력으로 교체하는 idempotent 작업.

Inclusion CRUD

createInclusion / updateInclusion / deleteInclusion. postingTypeper_stay / per_night / per_person / per_person_per_night.

RateSeason CRUD

명명된 시즌 엔티티. 여러 RatePlan 이 공유 가능. startDate/endDate 명시 또는 iCalendar rrule (RFC 5545) 으로 반복 정의. createRateSeason / updateRateSeason / deleteRateSeason.

Rematerialization Proposal

  • applyRematerializationProposal(id): 영향 범위 cell 을 새 규칙 기준 재계산해 갱신. source = rematerialized, 단일 contextId 로 audit batch.
  • discardRematerializationProposal(id): 폐기.

Audit

모든 사용자 mutation 은 @vpms-cluster/audit 라이브러리를 통해 audit-svc 로 발행된다. core-svc 에는 audit 테이블이 없으며 audit-svc 가 source of truth. 추가로 변경 가능 엔티티에 lastModifiedBy / updatedAt / lastModifiedReason 보조 필드를 두어 “마지막으로 누가 만졌나” 만 빠르게 조회한다 (전체 이력은 audit-svc 에서 조회).

Resolution 우선순위

resolveDailyRate / getDailyRateCalendar 의 가격 해석 순서 (ADR-0001 §2.2.1):
  1. DailyRate(ratePlanId, roomTypeId, stayDate) row 존재 → 그 값.
  2. parentRatePlanId + derivationRule 적용. 부모 가격 × 규칙.
  3. defaultAmount + pricingRules 계산. 요일/시즌 multiplier 결합.
  4. occupancy != baseOccupancyRatePlanOccupancyPrice 적용.
  5. 통화 반올림 normalize (KRW/JPY 등은 정수 절사).

캐시 정책

  • Redis Hash: rate:{ratePlanId}:{roomTypeId}:{YYYYMM} (field=day, value=amount).
  • TTL: 1h. 쓰기 직후 자동 invalidate.
  • Redis 미가용 시 캐시 미스로 취급 (오류 아님). DB 직조회로 fallback.

관련 ADR