{"openapi":"3.0.0","info":{"title":"FOP API — FMS","description":"FMS (시설 관리) API\n\n## Endpoint Inventory\n\n총 **14** endpoints\n\n### 숙소·객실 설정 (1 endpoints)\n\n| Method | Path | Summary |\n| --- | --- | --- |\n| GET | `/kiosk/fms/accommodations` | FMS — 접근 가능 숙소 디렉터리 (id·name) |\n\n### 키오스크 (13 endpoints)\n\n| Method | Path | Summary |\n| --- | --- | --- |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/cctv-captures/{captureId}/channels/{channelNo}/image` | FMS — CCTV 채널 이미지 프록시 다운로드 |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/kiosk-event-history` | FMS — 숙소 전체 키오스크 변경 이력 조회 (기간·필터·페이지네이션) |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/kiosks` | FMS — 숙소별 키오스크 목록 조회 |\n| POST | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/card-deck/dispense` | FMS — 카드데크 토출 명령 MQTT 발행 |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/card-slots` | FMS — 카드데크 매핑 조회 (객실·키카드번호) |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/cctv-sessions` | FMS — CCTV 캡처가 있는 최근 세션 목록 |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/devices/latest` | FMS — 주변기기별 최신 상태 조회 (이벤트 행 기준) |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/events` | FMS — 키오스크 이벤트 이력 조회 (페이지네이션) |\n| POST | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/receipt/print` | FMS — 최근 완료 체크인 영수증 재출력 |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/session/active` | FMS — 키오스크 활성 체크인 세션(현재 화면 단계) 조회 |\n| POST | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/session/cancel` | FMS — 키오스크 진행 중 체크인 세션 강제 취소 |\n| PUT | `/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/settings` | FMS — 키오스크 설정 변경 (성인인증·점검 등) |\n| GET | `/kiosk/fms/accommodations/{accommodationId}/sessions/{sessionId}/cctv-captures` | FMS — 세션의 CCTV 캡처 목록 (시점별 채널 메타) |","version":"1.0"},"servers":[{"url":"https://dev-api.thehyoosik.cloud","description":"Gateway"}],"paths":{"/kiosk/fms/accommodations":{"get":{"operationId":"FmsAccommodationDirectoryController_list","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"default":20,"type":"number"}},{"name":"groupId","required":false,"in":"query","schema":{"type":"string"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FmsAccommodationDirectoryResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 접근 가능 숙소 디렉터리 (id·name)","tags":["숙소·객실 설정"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks":{"get":{"operationId":"FmsKioskMonitorController_list","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskSummariesResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 숙소별 키오스크 목록 조회","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/card-slots":{"get":{"operationId":"FmsKioskMonitorController_cardSlots","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskCardSlotsResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 카드데크 매핑 조회 (객실·키카드번호)","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/session/active":{"get":{"operationId":"FmsKioskMonitorController_activeSession","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskActiveSessionResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 키오스크 활성 체크인 세션(현재 화면 단계) 조회","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/devices/latest":{"get":{"operationId":"FmsKioskMonitorController_latest","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskDeviceLatestResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 주변기기별 최신 상태 조회 (이벤트 행 기준)","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/events":{"get":{"operationId":"FmsKioskMonitorController_eventsPage","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}},{"name":"take","required":true,"in":"query","schema":{"type":"number"}},{"name":"cursor","required":true,"in":"query","schema":{"type":"string"}},{"name":"deviceKind","required":true,"in":"query","schema":{"type":"string"}},{"name":"eventType","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskDeviceEventsPageDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 키오스크 이벤트 이력 조회 (페이지네이션)","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosk-event-history":{"get":{"operationId":"FmsKioskMonitorController_eventHistory","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"조회 시작일 (YYYY-MM-DD)","schema":{"pattern":"/^\\d{4}-\\d{2}-\\d{2}$/","type":"string"}},{"name":"endDate","required":false,"in":"query","description":"조회 종료일 (YYYY-MM-DD)","schema":{"pattern":"/^\\d{4}-\\d{2}-\\d{2}$/","type":"string"}},{"name":"limit","required":false,"in":"query","description":"페이지당 항목 수 (기본값 50, 최대 1000)","schema":{"minimum":1,"maximum":1000,"default":50,"type":"number"}},{"name":"page","required":false,"in":"query","description":"페이지 번호 (1부터 시작, 기본값 1)","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"kioskId","required":false,"in":"query","description":"특정 키오스크로 필터","schema":{"format":"uuid","type":"string"}},{"name":"deviceKind","required":false,"in":"query","description":"디바이스 종류 필터","schema":{"type":"string","enum":["CARD_DECK","BILL_ACCEPTOR","BILL_DISPENSER","RECEIPT_PRINTER","CARD_TERMINAL","TERMINAL"]}},{"name":"eventTypes","required":false,"in":"query","description":"이벤트 타입 필터 (콤마 구분)","schema":{"example":"SETTINGS_CHANGED,COMMAND_ISSUED","type":"array","items":{"type":"string","enum":["STATUS","ERROR","SCAN","DISPENSED","INSERTED","EJECTED","BILL_INSERTED","BILL_DISPENSED","PAYMENT_APPROVED","PAYMENT_CANCELLED","MODE_CHANGED","COMMAND_ISSUED","COMMAND_ACK","ROUTE_FORCED","SESSION_CANCELLED","SETTINGS_CHANGED","RECEIPT_PRINTED"]}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskEventHistoryListResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 숙소 전체 키오스크 변경 이력 조회 (기간·필터·페이지네이션)","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/settings":{"put":{"operationId":"FmsKioskControlController_updateSettings","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateKioskSettingsBodyDto"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateKioskSettingsResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 키오스크 설정 변경 (성인인증·점검 등)","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/card-deck/dispense":{"post":{"operationId":"FmsKioskControlController_dispenseCard","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskDispenseCardBodyDto"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskIssueCommandResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 카드데크 토출 명령 MQTT 발행","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/receipt/print":{"post":{"operationId":"FmsKioskControlController_printReceipt","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskPrintReceiptResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 최근 완료 체크인 영수증 재출력","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/session/cancel":{"post":{"operationId":"FmsKioskControlController_cancelSession","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KioskIssueCommandResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 키오스크 진행 중 체크인 세션 강제 취소","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/kiosks/{kioskId}/cctv-sessions":{"get":{"operationId":"FmsKioskCctvViewController_listCctvSessions","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"kioskId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CctvSessionListResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — CCTV 캡처가 있는 최근 세션 목록","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/sessions/{sessionId}/cctv-captures":{"get":{"operationId":"FmsKioskCctvViewController_listCaptures","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"sessionId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CctvCaptureListResponseDto"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — 세션의 CCTV 캡처 목록 (시점별 채널 메타)","tags":["키오스크"]}},"/kiosk/fms/accommodations/{accommodationId}/cctv-captures/{captureId}/channels/{channelNo}/image":{"get":{"operationId":"FmsKioskCctvViewController_getChannelImage","parameters":[{"name":"accommodationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"captureId","required":true,"in":"path","schema":{"type":"string"}},{"name":"channelNo","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"CCTV 채널 이미지 바이너리","content":{"image/webp":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"검증 실패 또는 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"인증 필요 또는 토큰 만료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"FMS — CCTV 채널 이미지 프록시 다운로드","tags":["키오스크"]}}},"components":{"schemas":{"AddressDto":{"type":"object","properties":{"roadAddress":{"type":"string","description":"도로명 주소","example":"서울특별시 강남구 테헤란로 123"},"jibunAddress":{"type":"string","nullable":true,"description":"지번 주소. null 을 보내면 기존 값을 비웁니다.","example":"서울특별시 강남구 역삼동 123-45"},"postalCode":{"type":"string","description":"우편번호","example":"06134"},"latitude":{"type":"number","nullable":true,"minimum":-90,"maximum":90,"description":"위도. 지오코딩으로 좌표를 얻지 못했다면 생략하거나 null 을 보냅니다.","example":37.5012},"longitude":{"type":"number","nullable":true,"minimum":-180,"maximum":180,"description":"경도. 지오코딩으로 좌표를 얻지 못했다면 생략하거나 null 을 보냅니다.","example":127.0396}},"required":["roadAddress","postalCode"]},"CreateAccommodationDto":{"type":"object","properties":{"name":{"type":"string","description":"Accommodation name"},"address":{"description":"주소 정보","allOf":[{"$ref":"#/components/schemas/AddressDto"}]},"groupIds":{"description":"Group IDs to associate with","type":"array","items":{"type":"string"}},"rooms":{"type":"object","description":"객실 타입명 → 객실 번호 목록. 앞뒤·연속 공백만 금지하며 한글·공백을 쓸 수 있습니다. 예: {\"일반실\": [\"201\",\"202\"], \"스위트\": [\"본관 608\"]}","example":{"일반실":["201","202","203"],"스위트":["301","302"]}},"createDoorLocks":{"type":"boolean","description":"Whether to create door locks for each room","default":false},"defaultCapacity":{"type":"number","minimum":1,"description":"Default capacity for all room types","default":2},"maxCapacity":{"type":"number","minimum":1,"description":"Max capacity for all room types","default":4}},"required":["name","address","rooms","createDoorLocks"]},"AddressResponseDto":{"type":"object","properties":{"roadAddress":{"type":"string","nullable":true,"description":"도로명 주소"},"jibunAddress":{"type":"string","nullable":true,"description":"지번 주소"},"postalCode":{"type":"string","nullable":true,"description":"우편번호"},"latitude":{"type":"number","nullable":true,"description":"위도"},"longitude":{"type":"number","nullable":true,"description":"경도"}}},"AccommodationResponseDto":{"type":"object","properties":{"id":{"type":"string"},"groupIds":{"description":"Associated group IDs","type":"array","items":{"type":"string"}},"name":{"type":"string"},"address":{"nullable":true,"description":"주소 정보","allOf":[{"$ref":"#/components/schemas/AddressResponseDto"}]},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","groupIds","name","createdAt","updatedAt"]},"RoomTypeResponseDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"defaultCapacity":{"type":"number"},"maxCapacity":{"type":"number"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","name","defaultCapacity","maxCapacity","createdAt"]},"RoomResponseDto":{"type":"object","properties":{"id":{"type":"string"},"roomTypeId":{"type":"string"},"roomTypeName":{"type":"string"},"sectionId":{"type":"string","nullable":true,"description":"소속 구역 ID. null 이면 미배정."},"roomNo":{"type":"string"},"floor":{"type":"number"},"iotGroupId":{"type":"number","nullable":true,"description":"IoT 게이트웨이 그룹 ID"},"iotLocalId":{"type":"number","nullable":true,"description":"IoT 게이트웨이 로컬 ID"},"keyCardNumber":{"type":"number","nullable":true,"description":"객실 키 카드 식별번호"},"memo":{"type":"string","nullable":true,"description":"객실 메모. 사용자가 직접 지우기 전까지 유지되며, 부킹 메모와는 별개입니다."},"heatingTempOnOccupied":{"type":"number","nullable":true,"description":"키 연동 자동 난방: 카드키 삽입 시 목표 온도(℃, 객실별). 설정 일괄/개별 페이지에서 수정."},"heatingTempOnVacant":{"type":"number","nullable":true,"description":"키 연동 자동 난방: 홀더 비움 시 목표 온도(℃, 객실별)."},"createdAt":{"format":"date-time","type":"string"}},"required":["id","roomTypeId","roomNo","floor","createdAt"]},"DoorLockResponseDto":{"type":"object","properties":{"id":{"type":"string"},"roomId":{"type":"string"},"masterPin":{"type":"string","nullable":true,"description":"마스터 비밀번호 (복호화된 값)"},"serialNo":{"type":"number","description":"도어락 펌웨어 일련번호 (RF doorLockId·cardId, QR OTP doorlockId)"},"rfOpenCloseVolume":{"type":"number"},"rfInputVolume":{"type":"number"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","roomId","serialNo","createdAt"]},"CreateAccommodationResponseDto":{"type":"object","properties":{"accommodation":{"$ref":"#/components/schemas/AccommodationResponseDto"},"roomTypes":{"type":"array","items":{"$ref":"#/components/schemas/RoomTypeResponseDto"}},"rooms":{"type":"array","items":{"$ref":"#/components/schemas/RoomResponseDto"}},"doorLocks":{"type":"array","items":{"$ref":"#/components/schemas/DoorLockResponseDto"}}},"required":["accommodation","roomTypes","rooms"]},"AccommodationListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AccommodationResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"AccommodationBoardLayoutResponseDto":{"type":"object","properties":{"accommodationId":{"type":"string"},"classicLayout":{"type":"object","nullable":true},"floorLayout":{"type":"object","nullable":true}},"required":["accommodationId","classicLayout","floorLayout"]},"UpsertAccommodationBoardLayoutDto":{"type":"object","properties":{"classicLayout":{"type":"object","nullable":true,"description":"클래식 보드 타일 배치. 생략하면 기존 값을 유지하고, null 이면 지운다.","example":{"version":1,"groups":[]}},"floorLayout":{"type":"object","nullable":true,"description":"신규 보드 층 배치. 생략하면 기존 값을 유지하고, null 이면 지운다.","example":{"rows":[[3,2],[1]]}}}},"UpdateOperationalRuleDto":{"type":"object","properties":{"businessDayCutoff":{"type":"string","pattern":"TIME_REGEX","description":"Business day cutoff time (HH:mm or HH:mm:ss)","example":"14:00:00"},"inspectionEnabled":{"type":"boolean","description":"객실 점검(점검 대기 요청·완료) 기능 사용 여부. false로 저장하면 숙소 전체 점검 대기가 일괄 해제됩니다."},"autoCheckInEnabled":{"type":"boolean","description":"자동 입실 기능 활성화 여부. 키 삽입 시 자동으로 예약+체크인 처리."},"autoCheckInDayUseStartTime":{"type":"string","nullable":true,"pattern":"TIME_REGEX","description":"자동 입실 - 대실 체크인 시작 시각 (HH:mm 또는 HH:mm:ss)","example":"06:00:00"},"autoCheckInDayUseEndTime":{"type":"string","nullable":true,"pattern":"TIME_REGEX","description":"자동 입실 - 대실 체크인 종료 시각 (HH:mm 또는 HH:mm:ss)","example":"18:00:00"},"autoCheckInDayUseDurationMinutes":{"type":"number","nullable":true,"minimum":1,"maximum":1440,"description":"자동 입실 - 대실 사용시간 (분 단위, 1~1440)","example":180},"autoCheckInOvernightStartTime":{"type":"string","nullable":true,"pattern":"TIME_REGEX","description":"자동 입실 - 숙박 체크인 시작 시각 (HH:mm 또는 HH:mm:ss)","example":"15:00:00"},"autoCheckInOvernightEndTime":{"type":"string","nullable":true,"pattern":"TIME_REGEX","description":"자동 입실 - 숙박 체크인 종료 시각 (HH:mm 또는 HH:mm:ss)","example":"23:59:00"},"autoCheckInOvernightCheckOutTime":{"type":"string","nullable":true,"pattern":"TIME_REGEX","description":"자동 입실 - 숙박 퇴실 시각 (다음날 기준, HH:mm 또는 HH:mm:ss)","example":"11:00:00"},"autoCheckOutEnabled":{"type":"boolean","description":"자동 퇴실 기능 활성화 여부. 키 제거 시 자동으로 체크아웃 처리."},"kioskEarlyCheckInMinutes":{"type":"number","minimum":0,"maximum":1440,"description":"키오스크 예약 체크인에서 예정 체크인 시각보다 N분 일찍부터 체크인을 허용 (0~1440). 0이면 예정 시각부터만 허용.","example":30},"kioskVehicleRegistrationEnabled":{"type":"boolean","description":"키오스크 차량번호 입력 단계 사용 여부. 켜면 워크인 손님이 도보/차량을 직접 고르고 차량이면 차량번호를 입력하며, 예약 손님은 차량 예약인데 번호가 비어 있을 때만 입력 화면이 뜹니다. 끄면 입력 화면 없이 모두 도보로 처리되고 이미 차량으로 등록된 예약은 그대로 유지됩니다."},"qrKeyLmsAutoSendEnabled":{"type":"boolean","description":"체크인 시 QR 도어락 객실에 대해 고객 휴대폰번호로 QR 링크 문자(LMS)를 즉시 자동 발송할지 여부. 끄면 부킹 상세에서 수동으로만 발송합니다."}},"required":["businessDayCutoff"]},"OperationalRuleResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"businessDayCutoff":{"type":"string","description":"Time string HH:mm or HH:mm:ss"},"inspectionEnabled":{"type":"boolean","description":"객실 점검(점검 대기) 기능 사용 여부"},"autoCheckInEnabled":{"type":"boolean","description":"자동 입실 기능 활성화 여부"},"autoCheckInDayUseStartTime":{"type":"string","nullable":true,"description":"자동 입실 - 대실 체크인 시작 시각 (HH:mm:ss)"},"autoCheckInDayUseEndTime":{"type":"string","nullable":true,"description":"자동 입실 - 대실 체크인 종료 시각 (HH:mm:ss)"},"autoCheckInDayUseDurationMinutes":{"type":"number","nullable":true,"description":"자동 입실 - 대실 사용시간 (분)"},"autoCheckInOvernightStartTime":{"type":"string","nullable":true,"description":"자동 입실 - 숙박 체크인 시작 시각 (HH:mm:ss)"},"autoCheckInOvernightEndTime":{"type":"string","nullable":true,"description":"자동 입실 - 숙박 체크인 종료 시각 (HH:mm:ss)"},"autoCheckInOvernightCheckOutTime":{"type":"string","nullable":true,"description":"자동 입실 - 숙박 퇴실 시각 (HH:mm:ss)"},"autoCheckOutEnabled":{"type":"boolean","description":"자동 퇴실 기능 활성화 여부"},"kioskEarlyCheckInMinutes":{"type":"number","description":"키오스크 예약 체크인 조기 허용 분 (scheduledCheckInAt 기준 N분 전부터). 0이면 예정 시각부터만 허용."},"kioskVehicleRegistrationEnabled":{"type":"boolean","description":"키오스크 차량번호 입력 단계 사용 여부. true면 워크인 도보/차량 선택·차량번호 입력, 예약은 차량인데 번호가 없을 때 입력. false면 단계 생략 및 워크인 도보 처리."},"qrKeyLmsAutoSendEnabled":{"type":"boolean","description":"체크인 시 QR 도어락 객실에 QR 링크 문자(LMS)를 즉시 자동 발송할지 여부"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","accommodationId","businessDayCutoff","inspectionEnabled","autoCheckInEnabled","autoCheckOutEnabled","kioskEarlyCheckInMinutes","kioskVehicleRegistrationEnabled","qrKeyLmsAutoSendEnabled","createdAt","updatedAt"]},"UpdateRoomManagementRuleDto":{"type":"object","properties":{"heatingControlEnabled":{"type":"boolean","description":"Enable heating control"},"heatingTempOnOccupied":{"type":"number","nullable":true,"minimum":-10,"maximum":40,"description":"일괄 설정: 카드키(고객·청소) 삽입 시 난방 목표 온도(℃). 포함해 저장하면 이 숙소의 모든 객실 행에 덮어씁니다."},"heatingTempOnVacant":{"type":"number","nullable":true,"minimum":-10,"maximum":40,"description":"일괄 설정: 키 홀더 비움(EMPTY) 시 난방 목표 온도(℃). 포함해 저장하면 모든 객실에 덮어씁니다."},"heatingControlOption":{"type":"string","enum":["KEY_LINKED","ALWAYS_OFF"],"description":"난방 제어 모드. KEY_LINKED: 카드키(GUEST_KEY·HOUSEKEEPING_KEY) 삽입/비움에 연동"},"coolingControlOption":{"type":"string","enum":["KEY_LINKED","ALWAYS_OFF"],"description":"냉방(AC) 제어 모드 (KEY_LINKED / ALWAYS_OFF). KEY_LINKED: RMS가 카드키(GUEST_KEY·HOUSEKEEPING_KEY) 삽입 시 AC ON, EMPTY 시 OFF 로 로컬 제어"},"powerOffPolicy":{"type":"string","enum":["ON_CHECKOUT"],"description":"Power off policy (NONE, ON_CHECKOUT)"}}},"RoomManagementRuleResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"heatingControlEnabled":{"type":"boolean","description":"난방 제어 활성화"},"heatingControlOption":{"type":"string","nullable":true,"description":"난방 제어 모드 (KEY_LINKED / ALWAYS_OFF)"},"coolingControlOption":{"type":"string","nullable":true,"description":"냉방 제어 모드 (KEY_LINKED / ALWAYS_OFF). 기존 acControlOption 컬럼이 의미 명확화를 위해 리네임됨."},"powerOffPolicy":{"type":"string","nullable":true,"description":"Power off policy (NONE, ON_CHECKOUT)"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","accommodationId","heatingControlEnabled","createdAt","updatedAt"]},"RoomSectionResponseDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"구역 이름 (예: 본관, 별관, 1동)"},"sortOrder":{"type":"number","description":"탭 노출 순서"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","name","sortOrder","createdAt"]},"BusinessProfileResponseDto":{"type":"object","properties":{"legalName":{"type":"string","nullable":true},"businessRegistrationNumber":{"type":"string","nullable":true},"representativeName":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"businessType":{"type":"string","nullable":true},"businessCategory":{"type":"string","nullable":true},"receiptAutoPrintEnabled":{"type":"boolean"},"receiptFooterMessage":{"type":"string","nullable":true},"ntsStatus":{"type":"string","nullable":true,"enum":["ACTIVE","SUSPENDED","CLOSED","NOT_REGISTERED"]},"ntsTaxType":{"type":"string","nullable":true,"description":"과세유형 원문"},"ntsClosedDate":{"type":"string","nullable":true,"description":"폐업일자 (YYYY-MM-DD)"},"ntsVerifiedAt":{"type":"string","nullable":true,"description":"국세청 조회 시각 (ISO)"}},"required":["receiptAutoPrintEnabled"]},"AccommodationDetailResponseDto":{"type":"object","properties":{"id":{"type":"string"},"groupIds":{"description":"Associated group IDs","type":"array","items":{"type":"string"}},"name":{"type":"string"},"address":{"nullable":true,"description":"주소 정보","allOf":[{"$ref":"#/components/schemas/AddressResponseDto"}]},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"roomTypes":{"type":"array","items":{"$ref":"#/components/schemas/RoomTypeResponseDto"}},"rooms":{"type":"array","items":{"$ref":"#/components/schemas/RoomResponseDto"}},"roomSections":{"type":"array","items":{"$ref":"#/components/schemas/RoomSectionResponseDto"}},"doorLocks":{"type":"array","items":{"$ref":"#/components/schemas/DoorLockResponseDto"}},"operationalRule":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/OperationalRuleResponseDto"}]},"roomManagementRule":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/RoomManagementRuleResponseDto"}]},"businessProfile":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/BusinessProfileResponseDto"}]}},"required":["id","groupIds","name","createdAt","updatedAt"]},"UpdateAddressDto":{"type":"object","properties":{"roadAddress":{"type":"string","description":"도로명 주소","example":"서울특별시 강남구 테헤란로 123"},"jibunAddress":{"type":"string","nullable":true,"description":"지번 주소. null 을 보내면 기존 값을 비웁니다.","example":"서울특별시 강남구 역삼동 123-45"},"postalCode":{"type":"string","description":"우편번호","example":"06134"},"latitude":{"type":"number","nullable":true,"minimum":-90,"maximum":90,"description":"위도. 지오코딩으로 좌표를 얻지 못했다면 생략하거나 null 을 보냅니다.","example":37.5012},"longitude":{"type":"number","nullable":true,"minimum":-180,"maximum":180,"description":"경도. 지오코딩으로 좌표를 얻지 못했다면 생략하거나 null 을 보냅니다.","example":127.0396}}},"UpdateAccommodationDto":{"type":"object","properties":{"name":{"type":"string","description":"Accommodation name"},"groupIds":{"description":"Group IDs to associate with","type":"array","items":{"type":"string"}},"address":{"description":"주소 정보 (부분 갱신)","allOf":[{"$ref":"#/components/schemas/UpdateAddressDto"}]}}},"ConnectedDeviceIdsResponseDto":{"type":"object","properties":{"connectedDeviceIds":{"type":"array","items":{"type":"string"}}},"required":["connectedDeviceIds"]},"UpsertBusinessProfileDto":{"type":"object","properties":{"legalName":{"type":"string","nullable":true,"maxLength":120,"description":"법적 상호. 미설정 시 영수증에 숙소명으로 폴백","example":"주식회사 효식"},"businessRegistrationNumber":{"type":"string","nullable":true,"pattern":"BIZ_REG_NO_PATTERN","description":"사업자등록번호 (123-45-67890)","example":"123-45-67890"},"representativeName":{"type":"string","nullable":true,"maxLength":60,"description":"대표자명","example":"홍길동"},"phone":{"type":"string","nullable":true,"maxLength":30,"description":"사업장 대표 연락처","example":"02-1234-5678"},"businessType":{"type":"string","nullable":true,"maxLength":60,"description":"업태","example":"숙박업"},"businessCategory":{"type":"string","nullable":true,"maxLength":60,"description":"종목","example":"여관업"},"receiptAutoPrintEnabled":{"type":"boolean","description":"체크인/결제 완료 시 키오스크 영수증 자동 출력 여부"},"receiptFooterMessage":{"type":"string","nullable":true,"maxLength":200,"description":"영수증 하단 안내 문구","example":"이용해 주셔서 감사합니다."}}},"VerifyBusinessRegistrationDto":{"type":"object","properties":{"businessRegistrationNumber":{"type":"string","description":"사업자등록번호","example":"123-45-67890"}},"required":["businessRegistrationNumber"]},"NtsVerificationResponseDto":{"type":"object","properties":{"status":{"type":"string","enum":["ACTIVE","SUSPENDED","CLOSED","NOT_REGISTERED"]},"statusLabel":{"type":"string","example":"계속사업자"},"taxType":{"type":"string","nullable":true,"example":"부가가치세 일반과세자"},"closedDate":{"type":"string","nullable":true,"description":"폐업일자 (YYYY-MM-DD)"},"checkedAt":{"type":"string","description":"조회 시각 (ISO)"}},"required":["status","statusLabel","checkedAt"]},"LegacyEagleAccomItemDto":{"type":"object","properties":{"eagleAccomId":{"type":"string"},"name":{"type":"string"},"roadAddressHint":{"type":"string","description":"이글 주소를 이어 붙인 문자열. 확정 주소 검색의 힌트로만 쓴다."},"roomCount":{"type":"number"},"doorLockCount":{"type":"number"},"kioskCount":{"type":"number"}},"required":["eagleAccomId","name","roadAddressHint"]},"LegacyEagleAccomListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LegacyEagleAccomItemDto"}}},"required":["items"]},"LegacyImportPlanRoomTypeDto":{"type":"object","properties":{"eagleRoomTypeId":{"type":"string"},"name":{"type":"string"},"defaultCapacity":{"type":"number"},"maxCapacity":{"type":"number"}},"required":["eagleRoomTypeId","name","defaultCapacity","maxCapacity"]},"LegacyImportPlanRoomDto":{"type":"object","properties":{"eagleRoomId":{"type":"string"},"roomTypeEagleId":{"type":"string"},"roomNo":{"type":"string"},"floor":{"type":"number"}},"required":["eagleRoomId","roomTypeEagleId","roomNo","floor"]},"LegacyImportRetentionDto":{"type":"object","properties":{"roomSaleSaveDays":{"type":"number","description":"매출·예약 보관 일수"},"roomStateLogSaveDays":{"type":"number","description":"객실 상태 로그 보관 일수"}},"required":["roomSaleSaveDays","roomStateLogSaveDays"]},"LegacyImportWarningDto":{"type":"object","properties":{"scope":{"type":"string","description":"경고를 낸 단계 (core·pricing·booking·roomStatus)"},"eagleId":{"type":"string","description":"레거시 원본 식별자"},"message":{"type":"string"}},"required":["scope","message"]},"LegacyImportPlanResponseDto":{"type":"object","properties":{"eagleAccomId":{"type":"string"},"name":{"type":"string"},"serialNo":{"type":"number","description":"Eagle accom.no — FOP serialNo 로 보존된다."},"roadAddressHint":{"type":"string","description":"이글 주소 조합. 운영자가 주소 검색으로 확정해야 한다."},"postalCodeHint":{"type":"string"},"roomTypes":{"type":"array","items":{"$ref":"#/components/schemas/LegacyImportPlanRoomTypeDto"}},"rooms":{"type":"array","items":{"$ref":"#/components/schemas/LegacyImportPlanRoomDto"}},"doorLockCount":{"type":"number","description":"가져올 도어락 수"},"deviceCount":{"type":"number","description":"가져올 디바이스 수"},"kioskCount":{"type":"number","description":"가져올 키오스크 수"},"retention":{"$ref":"#/components/schemas/LegacyImportRetentionDto"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/LegacyImportWarningDto"}}},"required":["eagleAccomId","name","roadAddressHint","roomTypes","rooms","doorLockCount","deviceCount","kioskCount","retention","warnings"]},"LegacyImportAccommodationDto":{"type":"object","properties":{"eagleAccomId":{"type":"string","maxLength":64,"description":"Eagle accom_id"},"address":{"description":"운영자가 확정한 주소. 이글 주소는 도로명/우편번호가 비어 있는 경우가 많다.","allOf":[{"$ref":"#/components/schemas/AddressDto"}]},"groupIds":{"type":"array","items":{"type":"string"}}},"required":["eagleAccomId","address"]},"LegacyImportDevicePlanDto":{"type":"object","properties":{"type":{"type":"string","enum":["DAEMON","KIOSK"]},"name":{"type":"string"},"eagleDeviceId":{"type":"string","description":"Eagle device_id"}},"required":["type","eagleDeviceId"]},"LegacyImportKioskSettingsPlanDto":{"type":"object","properties":{"eagleKioskId":{"type":"string","description":"Eagle kiosk_id"},"eagleDeviceId":{"type":"string","description":"Eagle device_id"},"adultVerificationEnabled":{"type":"boolean"},"outOfService":{"type":"boolean"}},"required":["eagleKioskId"]},"LegacyImportResponseDto":{"type":"object","properties":{"accommodationId":{"type":"string"},"roomTypeIdMap":{"type":"object","description":"Eagle room_type_id → FOP RoomType UUID","additionalProperties":{"type":"string"}},"roomIdMap":{"type":"object","description":"Eagle room_id → FOP Room UUID","additionalProperties":{"type":"string"}},"accommodationSerialNo":{"type":"number","description":"FOP Accommodation.serialNo (OTP placeId, Eagle accom.no 보존)"},"devicePlan":{"description":"생성해야 할 디바이스 목록. Device 는 Auth 서비스 소유이고 시크릿을 운영자에게 노출해야 해서 클라이언트가 이어서 생성한다.","type":"array","items":{"$ref":"#/components/schemas/LegacyImportDevicePlanDto"}},"kioskSettingsPlan":{"type":"array","items":{"$ref":"#/components/schemas/LegacyImportKioskSettingsPlanDto"}},"warnings":{"description":"버려지거나 뭉개진 값","type":"array","items":{"$ref":"#/components/schemas/LegacyImportWarningDto"}}},"required":["accommodationId","roomTypeIdMap","roomIdMap","accommodationSerialNo","devicePlan","kioskSettingsPlan","warnings"]},"LegacyImportPricingRequestDto":{"type":"object","properties":{"eagleAccomId":{"type":"string","maxLength":64,"description":"Eagle accom_id"},"roomTypeIdMap":{"type":"object","description":"Eagle room_type_id → FOP RoomType UUID (코어 임포트 응답의 roomTypeIdMap)","additionalProperties":{"type":"string"}}},"required":["eagleAccomId","roomTypeIdMap"]},"LegacyImportPricingResultDto":{"type":"object","properties":{"created":{"type":"number","description":"새로 만든 레코드 수"},"skipped":{"type":"number","description":"이미 있어 건너뛴 레코드 수"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/LegacyImportWarningDto"}},"productCount":{"type":"number","description":"생성된 상품 수"},"rateCount":{"type":"number","description":"생성된 요일 요금 행 수"}},"required":["created","skipped","warnings","productCount","rateCount"]},"LegacyImportBookingsRequestDto":{"type":"object","properties":{"eagleAccomId":{"type":"string","maxLength":64,"description":"Eagle accom_id"},"fromMs":{"type":"number","minimum":0,"description":"구간 시작 (epoch ms, 포함)"},"toMs":{"type":"number","minimum":0,"description":"구간 종료 (epoch ms, 포함)"},"roomTypeIdMap":{"type":"object","description":"Eagle room_type_id → FOP RoomType UUID","additionalProperties":{"type":"string"}},"roomIdMap":{"type":"object","description":"Eagle room_id → FOP Room UUID","additionalProperties":{"type":"string"}},"includeUpcomingReservations":{"type":"boolean","description":"미래 예약(`all-by-reserved`)까지 함께 가져올지. 구간과 무관한 전체 조회라 마지막 구간에서 한 번만 true 로 보낸다.","default":false}},"required":["eagleAccomId","fromMs","toMs","roomTypeIdMap","roomIdMap"]},"LegacyImportBookingsResultDto":{"type":"object","properties":{"created":{"type":"number","description":"새로 만든 레코드 수"},"skipped":{"type":"number","description":"이미 있어 건너뛴 레코드 수"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/LegacyImportWarningDto"}},"bookingCount":{"type":"number","description":"매출(체크인 이력) 에서 만든 부킹 수"},"reservationCount":{"type":"number","description":"예약에서 만든 부킹 수"}},"required":["created","skipped","warnings","bookingCount","reservationCount"]},"LegacyImportRoomStatusRequestDto":{"type":"object","properties":{"eagleAccomId":{"type":"string","maxLength":64,"description":"Eagle accom_id"},"fromMs":{"type":"number","minimum":0,"description":"구간 시작 (epoch ms, 포함)"},"toMs":{"type":"number","minimum":0,"description":"구간 종료 (epoch ms, 포함)"},"roomIdMap":{"type":"object","description":"Eagle room_id → FOP Room UUID","additionalProperties":{"type":"string"}},"includeCurrentState":{"type":"boolean","description":"객실 현재 상태 스냅샷까지 반영할지. 마지막 구간에서 한 번만 true 로 보내 최신 상태가 이력 위에 얹히게 한다.","default":false}},"required":["eagleAccomId","fromMs","toMs","roomIdMap"]},"LegacyImportRoomStatusResultDto":{"type":"object","properties":{"created":{"type":"number","description":"새로 만든 레코드 수"},"skipped":{"type":"number","description":"이미 있어 건너뛴 레코드 수"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/LegacyImportWarningDto"}},"historyCount":{"type":"number","description":"기록한 상태 이력 행 수"}},"required":["created","skipped","warnings","historyCount"]},"CreateRoomDto":{"type":"object","properties":{"roomTypeId":{"type":"string","description":"Room type ID"},"sectionId":{"type":"string","nullable":true,"description":"소속 구역 ID (본관/별관 등). 생략하면 미배정."},"roomNo":{"type":"string","description":"객실 번호 (예: 101, B302, 매화(1동)601, 본관 608). 앞뒤·연속 공백과 제어문자는 사용할 수 없습니다.","maxLength":32},"floor":{"type":"number","minimum":0,"maximum":99,"description":"Floor number"},"iotGroupId":{"type":"number","description":"IoT 게이트웨이 그룹 ID"},"iotLocalId":{"type":"number","description":"IoT 게이트웨이 로컬 ID"},"keyCardNumber":{"type":"number","description":"객실 키 카드 식별번호"},"memo":{"type":"string","nullable":true,"maxLength":2000,"description":"객실 메모. 사용자가 직접 지우기 전까지 유지되며, 부킹 메모(예약자 메모)와는 별개입니다."}},"required":["roomTypeId","roomNo","floor"]},"UpdateRoomDto":{"type":"object","properties":{"roomTypeId":{"type":"string","description":"Room type ID"},"sectionId":{"type":"string","nullable":true,"description":"소속 구역 ID. null 을 보내면 구역 배정을 해제합니다."},"roomNo":{"type":"string","description":"객실 번호 (예: 101, B302, 매화(1동)601, 본관 608). 앞뒤·연속 공백과 제어문자는 사용할 수 없습니다.","maxLength":32},"floor":{"type":"number","minimum":0,"maximum":99,"description":"Floor number"},"iotGroupId":{"type":"number","description":"IoT 게이트웨이 그룹 ID"},"iotLocalId":{"type":"number","description":"IoT 게이트웨이 로컬 ID"},"keyCardNumber":{"type":"number","description":"객실 키 카드 식별번호"},"memo":{"type":"string","nullable":true,"maxLength":2000,"description":"객실 메모. null 또는 빈 문자열을 보내면 메모를 비웁니다. 부킹 메모와는 별개입니다."}}},"CreateRoomTypeDto":{"type":"object","properties":{"accommodationId":{"type":"string","description":"Accommodation ID"},"name":{"type":"string","minLength":1,"maxLength":15,"description":"객실 타입명"},"defaultCapacity":{"type":"number","minimum":1,"maximum":20,"description":"Default capacity"},"maxCapacity":{"type":"number","minimum":1,"maximum":20,"description":"Max capacity"}},"required":["accommodationId","name","defaultCapacity","maxCapacity"]},"UpdateRoomTypeDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":15,"description":"객실 타입명"},"defaultCapacity":{"type":"number","minimum":1,"maximum":20,"description":"Default capacity"},"maxCapacity":{"type":"number","minimum":1,"maximum":20,"description":"Max capacity"}}},"CreateRoomSectionDto":{"type":"object","properties":{"name":{"type":"string","maxLength":60,"description":"구역 이름 (예: 본관, 별관, 1동)"},"sortOrder":{"type":"number","minimum":0,"maximum":999,"description":"탭 노출 순서. 생략하면 0"}},"required":["name"]},"UpdateRoomSectionDto":{"type":"object","properties":{"name":{"type":"string","maxLength":60,"description":"구역 이름"},"sortOrder":{"type":"number","minimum":0,"maximum":999,"description":"탭 노출 순서"}}},"AssignRoomSectionDto":{"type":"object","properties":{"sectionId":{"type":"string","nullable":true,"description":"배정할 구역 ID. null 을 보내면 배정을 해제합니다."},"roomIds":{"minItems":1,"description":"대상 객실 ID 목록","maxItems":500,"type":"array","items":{"type":"string"}}},"required":["sectionId","roomIds"]},"AssignRoomSectionResultDto":{"type":"object","properties":{"updatedCount":{"type":"number","description":"구역이 실제로 바뀐 객실 수"}},"required":["updatedCount"]},"CreateDoorLockDto":{"type":"object","properties":{"roomId":{"type":"string","description":"객실 ID"},"masterPin":{"type":"string","minLength":8,"maxLength":8,"pattern":"/^\\d+$/","description":"마스터 비밀번호 (8자리 숫자)"},"serialNo":{"type":"number","minimum":1,"maximum":65535,"description":"도어락 펌웨어 일련번호. 미지정 시 숙소 내 max+1로 자동 부여. 레거시 임포트 시에만 명시."}},"required":["roomId"]},"UpdateDoorLockDto":{"type":"object","properties":{"masterPin":{"type":"string","minLength":8,"maxLength":8,"pattern":"/^\\d+$/","description":"마스터 비밀번호 (8자리 숫자)"},"rfOpenCloseVolume":{"type":"number","minimum":0,"maximum":255,"description":"RF 문 열림/닫힘 소리 (0~255)"},"rfInputVolume":{"type":"number","minimum":0,"maximum":255,"description":"RF 입력 소리 (0~255)"}}},"DoorLockOtpResponseDto":{"type":"object","properties":{"accommodationName":{"type":"string","description":"숙소 표시 이름"},"accommodationSerialNo":{"type":"number","description":"숙소 도어락 펌웨어 일련번호 (QR OTP v1 의 placeId)"},"roomNo":{"type":"string","description":"객실 호실 번호 (예: \"201\")"},"doorLockSerialNo":{"type":"number","description":"도어락 펌웨어 일련번호 (QR OTP v1 의 doorlockId)"},"otp":{"type":"string","description":"8자리 숫자 OTP. KST 시간 단위로 회전하며, 다음 정시까지 유효.","example":"01928374"},"otpExpireAt":{"format":"date-time","type":"string","description":"OTP 만료 시각 (다음 정시)"},"qrOtpV1":{"type":"string","description":"QR 코드용 OTP v1 페이로드. 형식: `otpv1.{accommodationSerialNo}.{doorLockSerialNo}.{otp}`"},"qrOtpV1ExpireAt":{"format":"date-time","type":"string","description":"QR OTP v1 만료 시각 (OTP 와 동일)"}},"required":["accommodationName","accommodationSerialNo","roomNo","doorLockSerialNo","otp","otpExpireAt","qrOtpV1","qrOtpV1ExpireAt"]},"CreateAccommodationGroupDto":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"description":"Group name"},"description":{"type":"string","description":"Group description"}},"required":["name"]},"AccommodationGroupResponseDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","name","createdAt","updatedAt"]},"AccommodationGroupListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AccommodationGroupResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"AccommodationSummaryDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"AccommodationGroupDetailResponseDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"accommodations":{"type":"array","items":{"$ref":"#/components/schemas/AccommodationSummaryDto"}}},"required":["id","name","createdAt","updatedAt","accommodations"]},"UpdateAccommodationGroupDto":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"description":"Group name"},"description":{"type":"string","description":"Group description"}}},"FmsAccommodationDirectoryItemDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"FmsAccommodationDirectoryResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/FmsAccommodationDirectoryItemDto"}},"total":{"type":"number"}},"required":["items","total"]},"EmqxWebhookDto":{"type":"object","properties":{"topic":{"type":"string"},"payload":{"type":"object"},"qos":{"type":"number"},"clientid":{"type":"string"},"username":{"type":"string"}},"required":["topic","payload"]},"WebhookAckResponseDto":{"type":"object","properties":{"success":{"type":"boolean"},"skipped":{"type":"boolean"}},"required":["success"]},"EmqxHeartbeatWebhookDto":{"type":"object","properties":{"topic":{"type":"string"},"payload":{"type":"object"}},"required":["topic"]},"EmqxClientDisconnectedWebhookDto":{"type":"object","properties":{"clientId":{"type":"string"},"reason":{"type":"string"},"disconnectedAt":{"type":"object","description":"EMQX `disconnected_at` (ms epoch). number 또는 문자열."}},"required":["clientId"]},"RoomIotCommandDto":{"type":"object","properties":{"temperature":{"type":"number","minimum":-20,"maximum":40,"description":"목표 객실 온도(℃, 1℃ 단위 권장)"},"chbStatus":{"type":"string","enum":["ON","OFF","SLOW_BLINK","FAST_BLINK"],"description":"차임벨(CHB) 상태 — ON / OFF / SLOW_BLINK / FAST_BLINK"},"powerStatus":{"type":"string","enum":["OFF"],"description":"객실 전원 차단(OFF만 지원)"}}},"UpdateRoomHeatingPolicyDto":{"type":"object","properties":{"heatingTempOnOccupied":{"type":"number","nullable":true,"minimum":10,"maximum":35,"description":"카드키(고객·청소) 삽입 시 목표 온도(℃, 10~35). null = 미설정"},"heatingTempOnVacant":{"type":"number","nullable":true,"minimum":10,"maximum":35,"description":"홀더 비움 시 목표 온도(℃, 10~35). null = 미설정"}}},"IssueDoorLockCardDto":{"type":"object","properties":{"cardType":{"type":"string","enum":["SETTING","TIME_SYNC","ROOM","FLOOR","AREA","RESET","HISTORY"]},"deviceId":{"type":"string","description":"발급할 발권기 디바이스 UUID. 생략 시 기본 발권기로 발급"},"roomId":{"type":"string","description":"객실 UUID (SETTING/ROOM 카드 필수)"},"floor":{"type":"number","minimum":1,"maximum":255,"description":"층별 카드(F) 대상 층"},"validFrom":{"type":"string","description":"유효 시작 (ROOM/FLOOR/AREA)"},"validUntil":{"type":"string","description":"유효 종료 (ROOM/FLOOR/AREA)"}},"required":["cardType"]},"DoorLockCardIssuanceResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"roomId":{"type":"string","nullable":true},"deviceId":{"type":"string","nullable":true,"description":"명령을 보낸 발권기 디바이스 UUID (레거시 발급은 null)"},"cardType":{"type":"string","enum":["SETTING","TIME_SYNC","ROOM","FLOOR","AREA","RESET","HISTORY"]},"regionId":{"type":"number"},"floor":{"type":"number","nullable":true},"doorLockId":{"type":"number","nullable":true},"cardId":{"type":"number","nullable":true},"validFrom":{"type":"string","nullable":true},"validUntil":{"type":"string","nullable":true},"status":{"type":"string"},"commandId":{"type":"string"},"cardUid":{"type":"string","nullable":true},"failureReason":{"type":"string","nullable":true},"requestedBy":{"type":"string"},"requestedByName":{"type":"string","nullable":true,"description":"요청자 표시명 (username). 조회 실패 시 null"},"createdAt":{"type":"string"},"completedAt":{"type":"string","nullable":true}},"required":["id","accommodationId","cardType","regionId","status","commandId","requestedBy","createdAt"]},"IssueDoorLockCardResponseDto":{"type":"object","properties":{"commandId":{"type":"string"},"issuance":{"$ref":"#/components/schemas/DoorLockCardIssuanceResponseDto"}},"required":["commandId","issuance"]},"DoorLockCardIssuanceListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DoorLockCardIssuanceResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"DoorLockCardIssuerStatusResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"deviceId":{"type":"string","nullable":true},"status":{"type":"string"},"source":{"type":"string"},"detail":{"type":"object","nullable":true},"recordedAt":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","accommodationId","status","source","recordedAt","createdAt"]},"DoorLockCardIssuerStatusListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DoorLockCardIssuerStatusResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"DoorLockCardIssuerResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"deviceId":{"type":"string","description":"발권기 데몬 디바이스 UUID"},"name":{"type":"string","nullable":true},"isPrimary":{"type":"boolean"},"protocolVersion":{"type":"number","description":"1 = 숙소 공용(레거시) 명령 토픽, 2 이상 = 디바이스 전용 토픽"},"lastStatus":{"type":"string","nullable":true,"description":"최근 status 기준 연결 상태"},"lastStatusAt":{"type":"string","nullable":true}},"required":["id","accommodationId","deviceId","isPrimary","protocolVersion"]},"DoorLockCardIssuerListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DoorLockCardIssuerResponseDto"}},"total":{"type":"number"}},"required":["items","total"]},"UpdateDoorLockCardIssuerDto":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"description":"발권기 표시 이름 (빈 문자열이면 이름 해제)"},"isPrimary":{"type":"boolean","description":"기본 발권기 지정 (숙소당 1대)"}}},"RegisterPushTokenDto":{"type":"object","properties":{"token":{"type":"string","maxLength":512,"description":"FCM 등록 토큰"},"platform":{"type":"string","enum":["ANDROID","IOS"],"description":"네이티브 플랫폼"},"installationId":{"type":"string","maxLength":64,"description":"단말 설치 신원 (앱이 생성해 영속)"}},"required":["token","platform","installationId"]},"PushTokenResponseDto":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"token":{"type":"string"},"platform":{"type":"string","enum":["ANDROID","IOS"]},"appType":{"type":"string"},"installationId":{"type":"string"},"lastSeenAt":{"format":"date-time","type":"string"},"disabledAt":{"format":"date-time","type":"string","nullable":true},"accommodationIds":{"type":"array","items":{"type":"string"}},"allAccommodations":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","userId","token","platform","appType","installationId","lastSeenAt","disabledAt","accommodationIds","allAccommodations","createdAt","updatedAt"]},"DeletePushTokenDto":{"type":"object","properties":{"installationId":{"type":"string","maxLength":64,"description":"단말 설치 신원"}},"required":["installationId"]},"SendTestPushDto":{"type":"object","properties":{"title":{"type":"string","maxLength":255,"description":"테스트 푸시 제목"},"body":{"type":"string","maxLength":4000,"description":"테스트 푸시 본문"}}},"SendTestPushResponseDto":{"type":"object","properties":{"queued":{"type":"number","description":"큐에 넣은 토큰(기기) 수"}},"required":["queued"]},"PushPreferenceAccommodationDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"PushPreferenceDeviceDto":{"type":"object","properties":{"platform":{"type":"string","enum":["ANDROID","IOS"]},"lastSeenAt":{"type":"string","description":"마지막 토큰 갱신 시각(ISO)"}},"required":["platform","lastSeenAt"]},"PushPreferenceResponseDto":{"type":"object","properties":{"enabled":{"type":"boolean"},"mutedEventTypes":{"type":"array","items":{"type":"string","enum":["OCCUPANCY","BOOKING","KIOSK","HOUSEKEEPING"]}},"mutedAccommodationIds":{"type":"array","items":{"type":"string"}},"accommodations":{"type":"array","items":{"$ref":"#/components/schemas/PushPreferenceAccommodationDto"}},"devices":{"description":"등록된 활성 앱 기기","type":"array","items":{"$ref":"#/components/schemas/PushPreferenceDeviceDto"}}},"required":["enabled","mutedEventTypes","mutedAccommodationIds","accommodations","devices"]},"UpdatePushPreferenceDto":{"type":"object","properties":{"enabled":{"type":"boolean","description":"푸시 마스터 스위치"},"mutedEventTypes":{"type":"array","description":"받지 않을 이벤트","items":{"type":"string","enum":["OCCUPANCY","BOOKING","KIOSK","HOUSEKEEPING"]}},"mutedAccommodationIds":{"description":"받지 않을 지점 ID","type":"array","items":{"type":"string","format":"uuid"}}},"required":["enabled","mutedEventTypes","mutedAccommodationIds"]},"NotificationLogItemDto":{"type":"object","properties":{"id":{"type":"string"},"bookingId":{"type":"string","nullable":true},"templateCode":{"type":"string","nullable":true,"description":"발송 근거 템플릿 코드"},"channel":{"type":"string","enum":["FCM","SMS","LMS","KAKAO","EMAIL"]},"status":{"type":"string","enum":["PENDING","SENT","FAILED"]},"recipient":{"type":"string","description":"수신 번호"},"title":{"type":"string","nullable":true,"description":"제목(LMS)"},"body":{"type":"string","description":"본문"},"statusCode":{"type":"string","nullable":true,"description":"Solapi 최종 상태 코드 (4000=수신완료)"},"providerMessageId":{"type":"string","nullable":true,"description":"Solapi 개별 메시지 ID"},"errorMessage":{"type":"string","nullable":true,"description":"실패 사유 (실패 시)"},"sentAt":{"type":"string","nullable":true,"description":"발송 성공 시각 (ISO 8601)"},"createdAt":{"type":"string","description":"생성 시각 (ISO 8601)"}},"required":["id","bookingId","templateCode","channel","status","recipient","title","body","statusCode","providerMessageId","errorMessage","sentAt","createdAt"]},"NotificationLogMonthlySummaryDto":{"type":"object","properties":{"period":{"type":"string","description":"집계 기준 월 (KST, `YYYY-MM`)"},"total":{"type":"number","description":"이번 달 총 발송 건수"},"sent":{"type":"number","description":"발송 성공 건수"},"failed":{"type":"number","description":"발송 실패 건수"},"pending":{"type":"number","description":"발송 대기 건수"}},"required":["period","total","sent","failed","pending"]},"NotificationLogListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/NotificationLogItemDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"monthlySummary":{"description":"이번 달(KST) 발송 요약. 필터와 무관하게 숙소 전체 기준으로 집계한다.","allOf":[{"$ref":"#/components/schemas/NotificationLogMonthlySummaryDto"}]}},"required":["items","total","page","limit","monthlySummary"]},"NotificationTemplateItemDto":{"type":"object","properties":{"code":{"type":"string","enum":["room_key_lms","booking_confirm_lms","booking_day_lms"]},"label":{"type":"string","description":"문자 종류 라벨"},"subject":{"type":"string","description":"제목(LMS 헤더)"},"body":{"type":"string","description":"숙소가 편집할 수 있는 본문"},"customized":{"type":"boolean","description":"숙소가 저장한 템플릿인지. false 면 시스템 기본값."}},"required":["code","label","subject","body","customized"]},"NotificationSettingResponseDto":{"type":"object","properties":{"bookingConfirmLmsEnabled":{"type":"boolean","description":"예약 확정 안내 자동 발송 여부"},"bookingDayLmsEnabled":{"type":"boolean","description":"당일 방문 안내 자동 발송 여부"},"bookingDayLmsSendTime":{"type":"string","nullable":true,"description":"당일 안내 발송 시각 (KST `HH:mm`). 미설정이면 null.","example":"10:00"},"skipDayLmsWhenConfirmed":{"type":"boolean","description":"예약 확정 문자를 받은 부킹은 당일 안내를 건너뛸지 여부"},"bookingLmsSubscribed":{"type":"boolean","description":"예약 문자 발송(booking_lms) 구독 활성 여부"},"templates":{"type":"array","items":{"$ref":"#/components/schemas/NotificationTemplateItemDto"}}},"required":["bookingConfirmLmsEnabled","bookingDayLmsEnabled","bookingDayLmsSendTime","skipDayLmsWhenConfirmed","bookingLmsSubscribed","templates"]},"UpdateNotificationTemplateDto":{"type":"object","properties":{"code":{"type":"string","enum":["room_key_lms","booking_confirm_lms","booking_day_lms"]},"subject":{"type":"string","description":"LMS 제목. Solapi 한도인 40바이트를 넘을 수 없다."},"body":{"type":"string","description":"머리말을 제외한 본문. 템플릿별 바이트 예산 안이어야 한다."}},"required":["code","subject","body"]},"UpdateNotificationSettingDto":{"type":"object","properties":{"bookingConfirmLmsEnabled":{"type":"boolean"},"bookingDayLmsEnabled":{"type":"boolean"},"bookingDayLmsSendTime":{"type":"string","nullable":true,"pattern":"HHMM_PATTERN","description":"당일 안내 발송 시각 (KST `HH:mm`). null 이면 해제.","example":"10:00"},"skipDayLmsWhenConfirmed":{"type":"boolean"},"templates":{"type":"array","items":{"$ref":"#/components/schemas/UpdateNotificationTemplateDto"}}}},"PreviewNotificationTemplateDto":{"type":"object","properties":{"code":{"type":"string","enum":["room_key_lms","booking_confirm_lms","booking_day_lms"]},"body":{"type":"string","maxLength":10000,"description":"편집 중인 본문. 저장 전 상태로 미리보기한다."},"subject":{"type":"string","maxLength":10000,"description":"편집 중인 제목."}},"required":["code","body"]},"NotificationTemplatePreviewResponseDto":{"type":"object","properties":{"subject":{"type":"string","description":"렌더된 제목"},"text":{"type":"string","description":"고정 블록까지 합친 최종 본문"},"bytes":{"type":"number","description":"EUC-KR 기준 바이트 수"},"truncated":{"type":"boolean","description":"LMS 한도 초과로 본문이 잘렸는지"},"unknownKeys":{"description":"값이 없어 빈 문자열로 치환된 변수 키","type":"array","items":{"type":"string"}}},"required":["subject","text","bytes","truncated","unknownKeys"]},"SendTestNotificationDto":{"type":"object","properties":{"code":{"type":"string","enum":["room_key_lms","booking_confirm_lms","booking_day_lms"]},"to":{"type":"string","pattern":"/^[0-9-]{9,20}$/","description":"수신 번호 (숫자·하이픈)","example":"010-1234-5678"},"body":{"type":"string","description":"편집 중인 본문으로 보낼 때 지정."},"subject":{"type":"string","description":"편집 중인 제목으로 보낼 때 지정."}},"required":["code","to"]},"SendTestNotificationResponseDto":{"type":"object","properties":{"notificationLogId":{"type":"string","description":"발송 큐에 등록된 알림 로그 id"},"text":{"type":"string","description":"실제 발송된 본문"},"bytes":{"type":"number","description":"EUC-KR 기준 바이트 수"}},"required":["notificationLogId","text","bytes"]},"ItemImageDto":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"sortOrder":{"type":"number"}},"required":["id","url","sortOrder"]},"CatalogItemResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"kind":{"type":"string","enum":["GOODS","SERVICE","AMENITY","BREAKFAST"]},"name":{"type":"string"},"sortOrder":{"type":"number"},"isActive":{"type":"boolean"},"allowMultipleSale":{"type":"boolean","description":"결제 한 줄당 수량 > 1 허용"},"currentPrice":{"type":"number","nullable":true,"description":"effectiveTo 없는 현재 단가 행 기준 적용 금액"},"images":{"type":"array","items":{"$ref":"#/components/schemas/ItemImageDto"}},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","accommodationId","kind","name","sortOrder","isActive","allowMultipleSale","images","createdAt","updatedAt"]},"CreateCatalogItemDto":{"type":"object","properties":{"kind":{"type":"string","enum":["GOODS","SERVICE","AMENITY","BREAKFAST"]},"name":{"type":"string","maxLength":120},"allowMultipleSale":{"type":"boolean","default":true},"sortOrder":{"type":"number","description":"초기 정렬값"},"initialPrice":{"type":"number","nullable":true,"minimum":0,"description":"초기 적용 단가 (생성 즉시 ItemPrice 행 추가)"}},"required":["kind","name"]},"ReorderCatalogItemsDto":{"type":"object","properties":{"itemIds":{"description":"숙소 내 전체 부대상품 ID 를 새 sortOrder 순으로","type":"array","items":{"type":"string","format":"uuid"}}},"required":["itemIds"]},"PatchCatalogItemDto":{"type":"object","properties":{"kind":{"type":"string","enum":["GOODS","SERVICE","AMENITY","BREAKFAST"]},"name":{"type":"string","maxLength":120},"sortOrder":{"type":"number"},"isActive":{"type":"boolean"},"allowMultipleSale":{"type":"boolean"}}},"ItemPriceAppliedDto":{"type":"object","properties":{"id":{"type":"string"},"price":{"type":"number"},"effectiveFrom":{"type":"string","description":"yyyy-MM-dd"},"effectiveTo":{"type":"string","nullable":true,"description":"yyyy-MM-dd"}},"required":["id","price","effectiveFrom"]},"AppendItemPriceDto":{"type":"object","properties":{"price":{"type":"number","minimum":0,"description":"적용 금액 (정수, ≥0)"},"effectiveFrom":{"type":"string","nullable":true,"description":"시작일 (YYYY-MM-DD). 생략 시 오늘(UTC)."}},"required":["price"]},"ReorderItemImagesDto":{"type":"object","properties":{"imageIds":{"description":"전체 이미지 ID 를 새 순서대로","type":"array","items":{"type":"string","format":"uuid"}}},"required":["imageIds"]},"ProductImageDto":{"type":"object","properties":{"id":{"type":"string","description":"이미지 ID"},"url":{"type":"string","description":"이미지 URL"},"sortOrder":{"type":"number","description":"정렬 순서"}},"required":["id","url","sortOrder"]},"ProductDefaultRateResponseDto":{"type":"object","properties":{"id":{"type":"string"},"productId":{"type":"string"},"dayOfWeek":{"type":"string","enum":["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"price":{"type":"number"},"extraPersonFee":{"type":"number","description":"추가 인원 1인당 요금 (원)"},"isSellable":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","productId","dayOfWeek","price","extraPersonFee","isSellable","createdAt","updatedAt"]},"ProductResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"상품 ID"},"primaryRoomTypeId":{"type":"string","nullable":true,"description":"기본 객실 타입 ID"},"name":{"type":"string","description":"상품명"},"stayType":{"type":"string","enum":["DAY_USE","OVERNIGHT"],"description":"숙박 유형"},"isVisibleOnKioskWalkIn":{"type":"boolean","description":"키오스크 워크인 판매 노출 여부"},"isDefaultForRoomTypeStay":{"type":"boolean","description":"해당 객실타입·스테이타입 조합의 기본 요금용 상품으로 지정됨"},"isActive":{"type":"boolean","description":"비활성화 시 목록·키오스크 등에서 제외 (soft delete 대용)"},"checkInFrom":{"type":"string","nullable":true,"description":"체크인 가능 시작 시간 (HH:MM)"},"checkInTo":{"type":"string","nullable":true,"description":"체크인 가능 종료 시간 (HH:MM). from>to 이면 자정 넘김 범위."},"checkOutBy":{"type":"string","nullable":true,"description":"체크아웃 마감 시간 (HH:MM). 숙박 전용."},"baseHours":{"type":"number","nullable":true,"description":"대실 기본 이용시간 (시간 단위). DAY_USE 전용."},"hourlyStayCutoff":{"type":"string","nullable":true,"description":"대실 마감시각 (HH:MM). null이면 마감 제한 없음. DAY_USE 전용."},"itemIds":{"description":"판매 가능 부대상품 ID 목록","type":"array","items":{"type":"string"}},"images":{"description":"상품 이미지 목록","type":"array","items":{"$ref":"#/components/schemas/ProductImageDto"}},"defaultRates":{"description":"요청 시 포함 (expand=rates)","type":"array","items":{"$ref":"#/components/schemas/ProductDefaultRateResponseDto"}},"createdAt":{"format":"date-time","type":"string","description":"생성일시"},"updatedAt":{"format":"date-time","type":"string","description":"수정일시"}},"required":["id","name","stayType","isVisibleOnKioskWalkIn","isDefaultForRoomTypeStay","isActive","itemIds","images","createdAt","updatedAt"]},"CreateProductDto":{"type":"object","properties":{"primaryRoomTypeId":{"type":"string","format":"uuid"},"name":{"type":"string"},"stayType":{"type":"string","enum":["DAY_USE","OVERNIGHT"]},"isVisibleOnKioskWalkIn":{"type":"boolean"},"checkInFrom":{"type":"string","nullable":true},"checkInTo":{"type":"string","nullable":true},"checkOutBy":{"type":"string","nullable":true},"baseHours":{"type":"number","nullable":true,"minimum":1,"description":"대실 기본 이용시간 (시간 단위). DAY_USE 전용."},"hourlyStayCutoff":{"type":"string","nullable":true,"description":"대실 마감시각 (HH:mm 또는 HH:mm:ss). null이면 마감 제한 없음. DAY_USE 전용."}},"required":["primaryRoomTypeId","name","stayType","isVisibleOnKioskWalkIn"]},"UpdateProductDto":{"type":"object","properties":{"primaryRoomTypeId":{"type":"string","format":"uuid"},"name":{"type":"string"},"stayType":{"type":"string","enum":["DAY_USE","OVERNIGHT"]},"isVisibleOnKioskWalkIn":{"type":"boolean"},"checkInFrom":{"type":"string","nullable":true},"checkInTo":{"type":"string","nullable":true},"checkOutBy":{"type":"string","nullable":true},"baseHours":{"type":"number","nullable":true,"minimum":1,"description":"대실 기본 이용시간 (시간 단위). DAY_USE 전용."},"hourlyStayCutoff":{"type":"string","nullable":true,"description":"대실 마감시각 (HH:mm 또는 HH:mm:ss). null이면 마감 제한 없음. DAY_USE 전용."},"isActive":{"type":"boolean","description":"false 시 비활성(목록·판매에서 제외)"},"isDefaultForRoomTypeStay":{"type":"boolean","description":"해당 객실타입·스테이타입 조합의 기본 요금제로 지정. true 이면 같은 조합의 다른 상품은 해제된다."}}},"ReplaceProductItemsDto":{"type":"object","properties":{"itemIds":{"description":"판매 가능 부대상품 ID (전체 교체)","type":"array","items":{"type":"string","format":"uuid"}}},"required":["itemIds"]},"ItemIdsResponseDto":{"type":"object","properties":{"itemIds":{"type":"array","items":{"type":"string"}}},"required":["itemIds"]},"DefaultRateItemDto":{"type":"object","properties":{"dayOfWeek":{"type":"string","enum":["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"price":{"type":"number","minimum":0},"extraPersonFee":{"type":"number","minimum":0,"description":"추가 인원 1인당 요금 (원). 생략 시 0"},"isSellable":{"type":"boolean"}},"required":["dayOfWeek","price","isSellable"]},"ReplaceDefaultRatesDto":{"type":"object","properties":{"rates":{"type":"array","items":{"$ref":"#/components/schemas/DefaultRateItemDto"}}},"required":["rates"]},"DailyRateResponseDto":{"type":"object","properties":{"id":{"type":"string"},"productId":{"type":"string"},"date":{"format":"date-time","type":"string","description":"날짜 (YYYY-MM-DD)"},"price":{"type":"number"},"extraPersonFee":{"type":"number","description":"추가 인원 1인당 요금 (원)"},"isSellable":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","productId","date","price","extraPersonFee","isSellable","createdAt","updatedAt"]},"UpsertDailyRateDto":{"type":"object","properties":{"date":{"type":"string","description":"YYYY-MM-DD"},"price":{"type":"number","minimum":0},"extraPersonFee":{"type":"number","minimum":0,"description":"추가 인원 1인당 요금 (원). 생략 시 0"},"isSellable":{"type":"boolean"}},"required":["date","price","isSellable"]},"ProductImageUploadResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"이미지 ID"},"url":{"type":"string","description":"이미지 URL"},"sortOrder":{"type":"number","description":"정렬 순서"},"createdAt":{"format":"date-time","type":"string","description":"생성일시"}},"required":["id","url","sortOrder","createdAt"]},"ReorderProductImagesDto":{"type":"object","properties":{"imageIds":{"description":"새 순서대로 정렬된 이미지 ID 배열","type":"array","items":{"type":"string","format":"uuid"}}},"required":["imageIds"]},"CatalogHistoryItemDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"productId":{"type":"string","nullable":true},"productName":{"type":"string","nullable":true},"entityType":{"type":"string","enum":["PRODUCT","PRODUCT_RATE","ITEM","ITEM_PRICE","PRODUCT_IMAGE","ITEM_IMAGE","PRODUCT_ITEM"]},"entityId":{"type":"string"},"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"]},"actorType":{"type":"string","enum":["USER","SYSTEM"]},"actorId":{"type":"string","nullable":true},"actorName":{"type":"string","nullable":true},"changes":{"type":"object"},"createdAt":{"type":"string"}},"required":["id","accommodationId","entityType","entityId","action","actorType","createdAt"]},"CatalogHistoryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CatalogHistoryItemDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"PublicHolidayResponseDto":{"type":"object","properties":{"date":{"type":"string","description":"날짜 (YYYY-MM-DD)","example":"2026-07-17"},"name":{"type":"string","description":"공휴일 명칭","example":"제헌절"}},"required":["date","name"]},"InventoryRoomTypeBucketDto":{"type":"object","properties":{"roomTypeId":{"type":"string"},"roomTypeName":{"type":"string"},"capacity":{"type":"number","description":"물리 객실 수(분모)"},"soldOvernight":{"type":"number","description":"숙박 점유 피크: 해당 영업일 시간 창(컷오프~같은 컷오프 다음날) 안에서 객실타입별 동시 활성 assignment 수의 최대값(시간뷰·타임라인과 동일한 재고 의미)"},"soldDayUse":{"type":"number","description":"대실 점유 피크: 영업일 창 안 동시 활성 대실 assignment 수의 최대값(숙박 잔여(capacity−soldOvernight) 계산에는 사용하지 않음)"},"availableOvernight":{"type":"number","description":"숙박 잔여 (capacity - soldOvernight, 최소 0)"}},"required":["roomTypeId","roomTypeName","capacity","soldOvernight","soldDayUse","availableOvernight"]},"InventoryCalendarDayDto":{"type":"object","properties":{"businessDate":{"type":"string","description":"영업일 YYYY-MM-DD"},"byRoomType":{"type":"array","items":{"$ref":"#/components/schemas/InventoryRoomTypeBucketDto"}}},"required":["businessDate","byRoomType"]},"InventoryTimelineAllocationDto":{"type":"object","properties":{"id":{"type":"string","description":"RoomAllocation.id"},"bookingId":{"type":"string"},"assignmentId":{"type":"string"},"roomTypeId":{"type":"string"},"startAt":{"type":"string"},"endAt":{"type":"string"},"status":{"type":"string","enum":["RESERVED","OCCUPIED","COMPLETED"]},"stayType":{"type":"string","enum":["OVERNIGHT","DAY_USE"]},"bookingStatus":{"type":"string","description":"Booking.status"},"channelType":{"type":"string","description":"ReservationInfo.channelType (직판 등)"},"label":{"type":"string","description":"표시용 라벨 (게스트명·상품명 등)"},"internalBookingNo":{"type":"string"},"bookingCreatedAt":{"type":"string","description":"부킹 생성 시각 (ISO 8601). 타임라인 오버존에서 최근 예약을 상단에 두는 데 사용됩니다."}},"required":["id","bookingId","assignmentId","roomTypeId","startAt","endAt","status","stayType","bookingStatus"]},"InventoryTimelineOutOfOrderDto":{"type":"object","properties":{"roomId":{"type":"string","description":"Room.id"},"startAt":{"type":"string","description":"판매중단 시작 시각 (조회 구간과의 교집합 시작)"},"endAt":{"type":"string","description":"판매중단 종료 시각 (expectedRecoveryAt 또는 조회 to 와 교집합)"},"reason":{"type":"string","description":"metadata.reason"},"expectedRecoveryAt":{"type":"string","description":"metadata.expectedRecoveryAt (원본)"}},"required":["roomId","startAt","endAt"]},"InventoryTimelineRoomTypeDto":{"type":"object","properties":{"roomTypeId":{"type":"string"},"roomTypeName":{"type":"string"},"capacity":{"type":"number","description":"해당 타입 물리 객실 수"},"allocations":{"type":"array","items":{"$ref":"#/components/schemas/InventoryTimelineAllocationDto"}},"outOfOrderBlocks":{"description":"판매중단(객실 단위)","type":"array","items":{"$ref":"#/components/schemas/InventoryTimelineOutOfOrderDto"}}},"required":["roomTypeId","roomTypeName","capacity","allocations","outOfOrderBlocks"]},"BookingFolioSummaryDto":{"type":"object","properties":{"id":{"type":"string"},"isMaster":{"type":"boolean","description":"해당 예약의 마스터 장부 여부"},"status":{"type":"string","enum":["OPEN","CLOSED","CANCELLED"]}},"required":["id","isMaster","status"]},"BookingItemResponseDto":{"type":"object","properties":{"id":{"type":"string"},"bookingId":{"type":"string"},"guestName":{"type":"string","description":"게스트명"},"guestPhone":{"type":"string","nullable":true},"guestEmail":{"type":"string","nullable":true},"roomId":{"type":"string","nullable":true,"description":"배정된 객실(호실) ID"},"lastCheckedInRoomId":{"type":"string","nullable":true,"description":"마지막 체크인 배정 객실 스냅샷 ID (체크아웃 후 roomId=null 이어도 유지)"},"roomNo":{"type":"string","nullable":true,"description":"배정 객실 호실 번호 (roomId 기준 조회)"},"lastCheckedInRoomNo":{"type":"string","nullable":true,"description":"마지막 체크인 객실 호실 번호 (lastCheckedInRoomId 기준 조회)"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","bookingId","guestName","createdAt","updatedAt"]},"PaymentDetailResponseDto":{"type":"object","properties":{"cashTendered":{"type":"number","nullable":true,"description":"받은 현금(원)"},"cashChange":{"type":"number","nullable":true,"description":"거스름돈(원)"},"cardPanLast4":{"type":"string","nullable":true},"cardBin6":{"type":"string","nullable":true},"cardIssuer":{"type":"string","nullable":true},"cardAcquirer":{"type":"string","nullable":true},"cardApprovalNo":{"type":"string","nullable":true},"cardApprovedAt":{"format":"date-time","type":"string","nullable":true},"cardInstallmentMonths":{"type":"number","nullable":true},"cardTerminalId":{"type":"string","nullable":true},"cardMerchantNo":{"type":"string","nullable":true},"transferBankCode":{"type":"string","nullable":true},"transferBankName":{"type":"string","nullable":true},"transferDepositorName":{"type":"string","nullable":true},"transferAccountLast4":{"type":"string","nullable":true},"transferReceivedAt":{"format":"date-time","type":"string","nullable":true},"memo":{"type":"string","nullable":true}}},"BookingPaymentResponseDto":{"type":"object","properties":{"id":{"type":"string"},"method":{"type":"string","enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"결제 수단"},"amount":{"type":"number","description":"결제 금액(원)"},"paidAt":{"format":"date-time","type":"string","nullable":true,"description":"결제 처리 시각"},"refundedAt":{"format":"date-time","type":"string","nullable":true,"description":"환불 처리 시각"},"paymentDetail":{"nullable":true,"description":"저장된 결제 세부 정보(현금·카드·이체)","allOf":[{"$ref":"#/components/schemas/PaymentDetailResponseDto"}]}},"required":["id","method","amount"]},"BookingAssignmentSegmentDto":{"type":"object","properties":{"startAt":{"format":"date-time","type":"string"},"endAt":{"format":"date-time","type":"string"},"status":{"type":"string","enum":["RESERVED","OCCUPIED","COMPLETED","CANCELLED"]}},"required":["startAt","endAt","status"]},"BookingAssignmentResponseDto":{"type":"object","properties":{"assignmentId":{"type":"string","description":"객실 자리(assignment) ID"},"roomId":{"type":"string","nullable":true,"description":"해당 자리에 배정된 물리 객실(없으면 타입 단위 슬롯만)"},"segments":{"type":"array","items":{"$ref":"#/components/schemas/BookingAssignmentSegmentDto"}}},"required":["assignmentId","segments"]},"BookingStatusHistoryItemDto":{"type":"object","properties":{"id":{"type":"string"},"bookingId":{"type":"string"},"status":{"type":"string","enum":["CONFIRMED","CHECKED_IN","CHECKED_OUT","CANCELLED","NO_SHOW","SALES_CANCELLED"]},"eventType":{"type":"string","enum":["STATUS_CHANGE","CHECK_IN_REVERTED","CHECK_OUT_REVERTED","BOOKING_CANCEL_REVERTED","SALES_CANCEL_REVERTED","CREATED","EXTENDED","ROOM_TRANSFERRED","ROOM_TYPE_CHANGED"],"description":"이벤트 종류. 일반 상태 전환은 STATUS_CHANGE, 사용자에 의한 체크인/체크아웃 취소는 별도 값으로 구분됩니다."},"actorType":{"type":"string","enum":["USER","DEVICE","API_KEY","SYSTEM","KIOSK"]},"actorId":{"type":"string","nullable":true},"actorName":{"type":"string","nullable":true,"description":"행위자 표시용 이름(username). 사용자 조회 실패 시 null, 시스템/디바이스 동작이면 null."},"reason":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"}},"required":["id","bookingId","status","eventType","actorType","createdAt"]},"BookingResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"internalBookingNo":{"type":"string"},"externalBookingNo":{"type":"string","nullable":true},"channelType":{"type":"string","enum":["DIRECT","YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"],"description":"유입 채널. `ReservationInfo` 가 연결된 부킹만 값이 있으며, 워크인 등 예약 원본이 없으면 생략됩니다."},"roomTypeId":{"type":"string","description":"객실 유형(property) ID"},"roomId":{"type":"string","nullable":true,"description":"배정 객실 ID(부킹 아이템 기준)"},"roomCount":{"type":"number","description":"예약 점유 객실 자리 수(room_count). 멀티룸 부킹은 1보다 큽니다.","minimum":1,"maximum":32},"personCount":{"type":"number","description":"투숙 인원 수","minimum":1},"status":{"type":"string","enum":["CONFIRMED","CHECKED_IN","CHECKED_OUT","CANCELLED","NO_SHOW","SALES_CANCELLED"]},"totalPrice":{"type":"number"},"roomChargeTotal":{"type":"number","description":"객실·연장 청구 금액 합계(ROOM / EXTENSION). 매출·ADR 집계의 객실 매출 정본."},"ancillaryChargeTotal":{"type":"number","description":"객실 외 기타 청구 합계(MINIBAR, DAMAGE 등). `totalPrice = roomChargeTotal + ancillaryChargeTotal`."},"fnbChargeTotal":{"type":"number","description":"조식(FNB) 청구 합계"},"amenityChargeTotal":{"type":"number","description":"어매니티 청구 합계"},"goodsChargeTotal":{"type":"number","description":"물품(GOODS) 청구 합계"},"serviceChargeTotal":{"type":"number","description":"서비스(SERVICE) 청구 합계"},"outstandingBalance":{"type":"number","description":"마스터 Folio 미수 잔액(전체). Σ(CHARGE+ADJUSTMENT)−Σ(PAYMENT)+Σ(REFUND)."},"ancillaryOutstanding":{"type":"number","description":"객실(ROOM/EXTENSION) 제외 부대·기타 카테고리 미수 잔액."},"guestName":{"type":"string","description":"대표 게스트(부킹 아이템 기준)"},"guestPhone":{"type":"string","nullable":true},"guestEmail":{"type":"string","nullable":true},"scheduledCheckInAt":{"format":"date-time","type":"string","description":"예정 체크인 시각"},"scheduledCheckOutAt":{"format":"date-time","type":"string","description":"예정 체크아웃 시각"},"actualCheckInAt":{"format":"date-time","type":"string","nullable":true,"description":"실제 체크인 시각 (체크인 처리된 경우)"},"actualCheckOutAt":{"format":"date-time","type":"string","nullable":true,"description":"실제 체크아웃 시각 (체크아웃 처리된 경우)"},"nightCount":{"type":"number","description":"숙박일수 (서버 계산, 대실 0)"},"notes":{"type":"string","nullable":true},"transportationType":{"type":"string","enum":["WALK","VEHICLE"],"description":"교통수단"},"vehicleNumber":{"type":"string","nullable":true,"description":"차량번호"},"productName":{"type":"string","nullable":true},"stayType":{"type":"string","nullable":true},"roomTypeName":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"folioId":{"type":"string","nullable":true,"description":"Phase 3 Folio ID (더블라이트 · 선택 필드)"},"reservationId":{"type":"string","nullable":true,"description":"ReservationInfo 행 ID (OTA 원본 예약 메타)"},"folios":{"description":"이 예약에 연결된 Folio 목록 요약","type":"array","items":{"$ref":"#/components/schemas/BookingFolioSummaryDto"}},"guests":{"type":"array","items":{"$ref":"#/components/schemas/BookingItemResponseDto"}},"payments":{"description":"예약에 연결된 결제 내역 (생성 순 오름차순). 결제수단 표시·매출 분석에 사용.","type":"array","items":{"$ref":"#/components/schemas/BookingPaymentResponseDto"}},"assignments":{"description":"객실 자리(assignment)별 점유 segment — 멀티룸·객실 이동 표현","type":"array","items":{"$ref":"#/components/schemas/BookingAssignmentResponseDto"}},"statusHistory":{"description":"예약 상태·가격 변경 이력","type":"array","items":{"$ref":"#/components/schemas/BookingStatusHistoryItemDto"}},"kioskCheckIn":{"type":"boolean","description":"COMPLETE 키오스크 세션이 연결된 체크인 여부"},"kioskSessionId":{"type":"string","nullable":true,"description":"키오스크 체크인 세션 ID (CCTV·신분증 조회용)"},"kioskCancelPending":{"type":"boolean","description":"매출취소 응답 전용 — 키오스크 카드 승인취소가 단말에서 진행 중이며, 취소 성공 이벤트 수신 후 매출취소가 확정됨을 의미한다. true 면 부킹 상태는 아직 CHECKED_OUT."}},"required":["id","accommodationId","internalBookingNo","roomTypeId","personCount","status","totalPrice","roomChargeTotal","ancillaryChargeTotal","guestName","scheduledCheckInAt","scheduledCheckOutAt","nightCount","transportationType","createdAt","updatedAt"]},"BookingListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BookingResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"PaymentDetailInputDto":{"type":"object","properties":{"cashTendered":{"type":"number","minimum":0,"description":"받은 현금(원). 현금 결제 시 필수."},"cashChange":{"type":"number","minimum":0,"description":"거스름돈(원). 미입력 시 서버가 자동 계산. 입력 시 받은 금액·결제금과 일치해야 함."},"cardPanLast4":{"type":"string","pattern":"/^\\d{4}$/","description":"카드번호 마지막 4자리(숫자만)","example":"1234"},"cardBin6":{"type":"string","pattern":"/^\\d{6}$/","description":"BIN 6자리","example":"123456"},"cardIssuer":{"type":"string","maxLength":40,"description":"카드 발급사"},"cardAcquirer":{"type":"string","maxLength":40,"description":"매입사"},"cardApprovalNo":{"type":"string","maxLength":40,"description":"승인번호. 카드 결제 세부 입력 시 필수."},"cardApprovedAt":{"type":"string","description":"승인 시각 ISO8601"},"cardInstallmentMonths":{"type":"number","minimum":0,"maximum":60,"description":"할부 개월(일시불 0)"},"cardTerminalId":{"type":"string","maxLength":40,"description":"단말기 ID"},"cardMerchantNo":{"type":"string","maxLength":40,"description":"가맹점 번호"},"transferBankCode":{"type":"string","maxLength":8,"description":"입금 은행 코드"},"transferBankName":{"type":"string","maxLength":40,"description":"입금 은행명"},"transferDepositorName":{"type":"string","maxLength":60,"description":"입금자명. 계좌이체 세부 입력 시 필수."},"transferAccountLast4":{"type":"string","pattern":"/^\\d{4}$/","description":"계좌번호 마지막 4자리","example":"9012"},"transferReceivedAt":{"type":"string","description":"입금 확인 시각 ISO8601"},"memo":{"type":"string","maxLength":500,"description":"메모"}}},"CreateBookingDto":{"type":"object","properties":{"productId":{"type":"string","format":"uuid","description":"판매 상품 ID (객실 타입은 상품에 연결된 객실 유형으로만 확정됩니다. 개별 호실은 예약 생성 시 배정할 수 없습니다)"},"channelType":{"type":"string","enum":["DIRECT","YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"],"description":"`isWalkIn` 이 true 가 아닐 때 필수. 현장 워크인(`isWalkIn: true`)이면 생략하며 서버는 ReservationInfo 를 생성하지 않습니다."},"isWalkIn":{"type":"boolean","description":"true 이면 현장 워크인으로 생성합니다. ReservationInfo(채널·외부예약번호 메타) 없이 Booking 만 저장합니다.","default":false},"externalBookingNo":{"type":"string","maxLength":120,"description":"외부(OTA) 예약 번호. 미입력 시 null 로 저장됩니다."},"guestName":{"type":"string","maxLength":100,"description":"투숙객 이름. 미입력/공백이면 빈 문자열로 저장됩니다."},"guestPhone":{"type":"string","pattern":"/^\\d{8,20}$/","description":"연락처 (숫자만 8~20자리, 하이픈 불가)","example":"01012345678"},"notes":{"type":"string","description":"메모"},"transportationType":{"type":"string","enum":["WALK","VEHICLE"],"description":"교통수단"},"vehicleNumber":{"type":"string","maxLength":20,"description":"차량번호"},"scheduledCheckInAt":{"type":"string","description":"예정 체크인 시각 (ISO 8601)"},"scheduledCheckOutAt":{"type":"string","description":"예정 체크아웃 시각 (ISO 8601)"},"totalPrice":{"type":"number","minimum":0,"description":"총 결제 금액(원)"},"roomCount":{"type":"number","minimum":1,"maximum":32,"description":"예약 객실 수(자리 수, 1~32). 생략 시 1","default":1},"personCount":{"type":"number","minimum":1,"description":"투숙 인원 수. 생략 시 2","default":2},"nights":{"type":"number","minimum":1,"maximum":30,"description":"OVERNIGHT 숙박 박 수(N박, 1~30). 제공 시 서버가 영업일 기준으로 예정 체크아웃을 도출한다(전달된 scheduledCheckOutAt 은 잠정값으로 무시). 미제공 시 호출자 체크아웃을 정본으로 사용(OTA 등). DAY_USE 는 무시"},"paymentMethod":{"type":"string","enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"결제 수단"},"paymentDetail":{"description":"결제 세부 정보(현금·카드·이체). EXTERNAL_PREPAID 에는 사용할 수 없습니다. 필드를 채우면 수단별 필수값 검증이 적용됩니다.","allOf":[{"$ref":"#/components/schemas/PaymentDetailInputDto"}]},"internalBookingNo":{"type":"string","maxLength":40,"pattern":"/^[A-Z0-9_-]{1,40}$/","description":"예약 번호를 직접 지정하고 싶을 때 사용. 미지정 시 서버가 자동 생성(8자리 숫자). 확정 또는 체크인 상태 예약과 같은 번호가 있으면 사용할 수 없습니다. 영문 대문자/숫자/하이픈/언더스코어만 허용한다(최대 40자).","example":"12345678"}},"required":["productId","scheduledCheckInAt","scheduledCheckOutAt","totalPrice","paymentMethod"]},"UpdateBookingPriceDto":{"type":"object","properties":{"price":{"type":"number","minimum":0,"description":"변경할 매출 금액"},"reason":{"type":"string","description":"변경 사유"}},"required":["price"]},"UpdateBookingGuestDto":{"type":"object","properties":{"guestName":{"type":"string","maxLength":100,"description":"투숙객 이름. 미입력/공백이면 빈 문자열로 저장됩니다."},"guestPhone":{"type":"string","pattern":"/^\\d{8,20}$/","description":"연락처 (숫자만 8~20자리, 하이픈 불가). 빈 문자열이면 null로 비웁니다.","example":"01012345678","nullable":true},"guestEmail":{"type":"string","maxLength":255,"pattern":"/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/","description":"이메일. 빈 문자열이면 null로 비웁니다.","nullable":true}}},"UpdateBookingNotesDto":{"type":"object","properties":{"notes":{"type":"string","description":"예약 메모(부킹별 운영 텍스트). 빈 문자열이면 메모를 비웁니다(null로 정규화). 최대 2000자.","nullable":true}},"required":["notes"]},"UpdateBookingTransportationDto":{"type":"object","properties":{"transportationType":{"type":"string","enum":["WALK","VEHICLE"],"description":"교통수단"},"vehicleNumber":{"type":"string","maxLength":20,"description":"차량번호"}},"required":["transportationType"]},"UpdateBookingRoomTypeDto":{"type":"object","properties":{"roomTypeId":{"type":"string","format":"uuid","description":"변경할 객실 유형 ID"},"reason":{"type":"string","maxLength":500,"description":"변경 사유(이력에 저장)"}},"required":["roomTypeId"]},"UpdateBookingScheduleDto":{"type":"object","properties":{"productId":{"type":"string","format":"uuid","description":"변경할 상품 ID"},"scheduledCheckInAt":{"type":"string","description":"예정 체크인 시각 (ISO 8601)"},"scheduledCheckOutAt":{"type":"string","description":"예정 체크아웃 시각 (ISO 8601)"}},"required":["productId","scheduledCheckInAt","scheduledCheckOutAt"]},"CreateBookingExtensionDto":{"type":"object","properties":{"productId":{"type":"string","format":"uuid","description":"연장 구간에 판매할 상품 ID (기존 예약과 동일 객실 유형이어야 함)"},"paymentMethod":{"type":"string","enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"추가 구간 결제 수단"},"paymentDetail":{"description":"추가 구간 결제 세부 정보. EXTERNAL_PREPAID 에는 사용할 수 없습니다.","allOf":[{"$ref":"#/components/schemas/PaymentDetailInputDto"}]},"additionalPrice":{"type":"number","minimum":0,"description":"추가 구간 총 결제 금액(원). 숙박 상품은 일별 요금이 있으면 서버가 카탈로그 기준으로 덮어쓸 수 있습니다."},"additionalNights":{"type":"number","minimum":1,"description":"숙박(OVERNIGHT) 연장 시 추가 숙박일수. `scheduledCheckOutAt` 과 동시에 지정할 수 없습니다."},"scheduledCheckOutAt":{"type":"string","description":"예정 체크아웃 시각 (ISO 8601). 숙박 연장 시 `additionalNights` 와 배타적으로 하나만 지정합니다. 대실 연장 시에는 필수입니다."},"internalBookingNo":{"type":"string","maxLength":40,"pattern":"/^[A-Z0-9_-]{1,40}$/","description":"내부 예약 번호 직접 지정. 미입력 시 자동 발번은 예약 생성과 동일(8자리 숫자)입니다."}},"required":["productId","paymentMethod","additionalPrice"]},"TransferBookingRoomDto":{"type":"object","properties":{"newRoomId":{"type":"string","format":"uuid","description":"이동할 호실 UUID"},"assignmentId":{"type":"string","format":"uuid","description":"멀티룸 예약에서 이동할 객실 자리(assignment_id). 단일실은 생략 가능"},"reason":{"type":"string","maxLength":500,"description":"운영 메모 / 사유"},"additionalPrice":{"type":"number","minimum":0,"description":"룸 업그레이드 등 추가 청구 금액(원). 0 또는 생략 시 원장에 반영하지 않습니다.","default":0},"paymentMethod":{"type":"string","enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"`additionalPrice` 가 1원 이상이면 필수입니다. 카드 등 결제 수단 선택."},"paymentDetail":{"description":"결제 세부 정보. EXTERNAL_PREPAID 에는 사용할 수 없습니다. `additionalPrice` 가 1원 이상이고 선결제가 아닐 때만 의미 있습니다.","allOf":[{"$ref":"#/components/schemas/PaymentDetailInputDto"}]}},"required":["newRoomId"]},"CheckInDto":{"type":"object","properties":{"roomId":{"type":"string","format":"uuid","description":"대표 객실(호실) ID(멀티룸 시 첫 번째 배정). `roomIds` 를 모두 보내도 되며, 생략 시 단일 `roomId` 만 사용됩니다."},"roomIds":{"description":"멀티룸 예약: 배정할 객실 ID를 room_count 개 보냅니다. 생략 시 `roomId` 하나만 사용(단일실과 동일).","type":"array","items":{"type":"string","format":"uuid"}},"confirmHourlyStayWarnings":{"type":"boolean","description":"대실 마감 관련 경고를 확인한 뒤 체크인을 진행할 때 true (첫 요청에서는 생략, 409 응답 후 재시도)"}},"required":["roomId"]},"HourlyStayCheckInWarningDto":{"type":"object","properties":{"code":{"type":"string","enum":["AFTER_HOURLY_CUTOFF","CHECKOUT_TIME_ADJUSTED","ROOM_TYPE_MISMATCH"]},"message":{"type":"string"},"adjustedCheckOutAt":{"type":"string","description":"조정된 퇴실 시각 (ISO8601)"}},"required":["code","message"]},"CheckInResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"internalBookingNo":{"type":"string"},"externalBookingNo":{"type":"string","nullable":true},"channelType":{"type":"string","enum":["DIRECT","YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"],"description":"유입 채널. `ReservationInfo` 가 연결된 부킹만 값이 있으며, 워크인 등 예약 원본이 없으면 생략됩니다."},"roomTypeId":{"type":"string","description":"객실 유형(property) ID"},"roomId":{"type":"string","nullable":true,"description":"배정 객실 ID(부킹 아이템 기준)"},"roomCount":{"type":"number","description":"예약 점유 객실 자리 수(room_count). 멀티룸 부킹은 1보다 큽니다.","minimum":1,"maximum":32},"personCount":{"type":"number","description":"투숙 인원 수","minimum":1},"status":{"type":"string","enum":["CONFIRMED","CHECKED_IN","CHECKED_OUT","CANCELLED","NO_SHOW","SALES_CANCELLED"]},"totalPrice":{"type":"number"},"roomChargeTotal":{"type":"number","description":"객실·연장 청구 금액 합계(ROOM / EXTENSION). 매출·ADR 집계의 객실 매출 정본."},"ancillaryChargeTotal":{"type":"number","description":"객실 외 기타 청구 합계(MINIBAR, DAMAGE 등). `totalPrice = roomChargeTotal + ancillaryChargeTotal`."},"fnbChargeTotal":{"type":"number","description":"조식(FNB) 청구 합계"},"amenityChargeTotal":{"type":"number","description":"어매니티 청구 합계"},"goodsChargeTotal":{"type":"number","description":"물품(GOODS) 청구 합계"},"serviceChargeTotal":{"type":"number","description":"서비스(SERVICE) 청구 합계"},"outstandingBalance":{"type":"number","description":"마스터 Folio 미수 잔액(전체). Σ(CHARGE+ADJUSTMENT)−Σ(PAYMENT)+Σ(REFUND)."},"ancillaryOutstanding":{"type":"number","description":"객실(ROOM/EXTENSION) 제외 부대·기타 카테고리 미수 잔액."},"guestName":{"type":"string","description":"대표 게스트(부킹 아이템 기준)"},"guestPhone":{"type":"string","nullable":true},"guestEmail":{"type":"string","nullable":true},"scheduledCheckInAt":{"format":"date-time","type":"string","description":"예정 체크인 시각"},"scheduledCheckOutAt":{"format":"date-time","type":"string","description":"예정 체크아웃 시각"},"actualCheckInAt":{"format":"date-time","type":"string","nullable":true,"description":"실제 체크인 시각 (체크인 처리된 경우)"},"actualCheckOutAt":{"format":"date-time","type":"string","nullable":true,"description":"실제 체크아웃 시각 (체크아웃 처리된 경우)"},"nightCount":{"type":"number","description":"숙박일수 (서버 계산, 대실 0)"},"notes":{"type":"string","nullable":true},"transportationType":{"type":"string","enum":["WALK","VEHICLE"],"description":"교통수단"},"vehicleNumber":{"type":"string","nullable":true,"description":"차량번호"},"productName":{"type":"string","nullable":true},"stayType":{"type":"string","nullable":true},"roomTypeName":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"folioId":{"type":"string","nullable":true,"description":"Phase 3 Folio ID (더블라이트 · 선택 필드)"},"reservationId":{"type":"string","nullable":true,"description":"ReservationInfo 행 ID (OTA 원본 예약 메타)"},"folios":{"description":"이 예약에 연결된 Folio 목록 요약","type":"array","items":{"$ref":"#/components/schemas/BookingFolioSummaryDto"}},"guests":{"type":"array","items":{"$ref":"#/components/schemas/BookingItemResponseDto"}},"payments":{"description":"예약에 연결된 결제 내역 (생성 순 오름차순). 결제수단 표시·매출 분석에 사용.","type":"array","items":{"$ref":"#/components/schemas/BookingPaymentResponseDto"}},"assignments":{"description":"객실 자리(assignment)별 점유 segment — 멀티룸·객실 이동 표현","type":"array","items":{"$ref":"#/components/schemas/BookingAssignmentResponseDto"}},"statusHistory":{"description":"예약 상태·가격 변경 이력","type":"array","items":{"$ref":"#/components/schemas/BookingStatusHistoryItemDto"}},"kioskCheckIn":{"type":"boolean","description":"COMPLETE 키오스크 세션이 연결된 체크인 여부"},"kioskSessionId":{"type":"string","nullable":true,"description":"키오스크 체크인 세션 ID (CCTV·신분증 조회용)"},"kioskCancelPending":{"type":"boolean","description":"매출취소 응답 전용 — 키오스크 카드 승인취소가 단말에서 진행 중이며, 취소 성공 이벤트 수신 후 매출취소가 확정됨을 의미한다. true 면 부킹 상태는 아직 CHECKED_OUT."},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/HourlyStayCheckInWarningDto"}}},"required":["id","accommodationId","internalBookingNo","roomTypeId","personCount","status","totalPrice","roomChargeTotal","ancillaryChargeTotal","guestName","scheduledCheckInAt","scheduledCheckOutAt","nightCount","transportationType","createdAt","updatedAt"]},"CancelStayActionDto":{"type":"object","properties":{"reason":{"type":"string","maxLength":500,"description":"취소 사유 (체크인/체크아웃 취소 시 부킹 이력에 기록)"}}},"WalkInQuoteWarningDto":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"adjustedCheckOutAt":{"type":"string","description":"조정된 퇴실 시각 (ISO8601)"}},"required":["code","message"]},"WalkInQuoteCandidateDto":{"type":"object","properties":{"productId":{"type":"string"},"productName":{"type":"string"},"checkInFrom":{"type":"string","nullable":true},"checkInTo":{"type":"string","nullable":true},"isDefault":{"type":"boolean"}},"required":["productId","productName","isDefault"]},"WalkInQuoteResponseDto":{"type":"object","properties":{"productId":{"type":"string"},"productName":{"type":"string"},"scheduledCheckInAt":{"type":"string","description":"예정 체크인 (ISO 8601)"},"scheduledCheckOutAt":{"type":"string","description":"예정 체크아웃 (ISO 8601)"},"totalPrice":{"type":"number","description":"총 금액(원)"},"baseHours":{"type":"number","nullable":true,"description":"대실 기본 이용시간(시간)"},"nights":{"type":"number","description":"숙박 박 수"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/WalkInQuoteWarningDto"}},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/WalkInQuoteCandidateDto"}}},"required":["productId","productName","scheduledCheckInAt","scheduledCheckOutAt","totalPrice","warnings","candidates"]},"WalkInCheckInDto":{"type":"object","properties":{"roomId":{"type":"string","format":"uuid","description":"입실할 객실 ID"},"stayType":{"type":"string","enum":["DAY_USE","OVERNIGHT"],"description":"대실(DAY_USE) 또는 숙박(OVERNIGHT)"},"paymentMethod":{"type":"string","enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"결제 수단. 워크인은 EXTERNAL_PREPAID 불가"},"expectedTotalPrice":{"type":"number","minimum":0,"description":"견적 금액(원). 서버 재계산과 다르면 409"},"nights":{"type":"number","minimum":1,"maximum":30,"description":"숙박 박 수. OVERNIGHT 만 사용. 생략 시 1박"},"productId":{"type":"string","description":"사용할 요금제 ID. 생략 시 기본 요금제"},"guestName":{"type":"string","maxLength":100,"description":"투숙객 이름"},"guestPhone":{"type":"string","pattern":"/^\\d{8,20}$/","description":"연락처 (숫자만 8~20자리)","example":"01012345678"},"vehicleNumber":{"type":"string","maxLength":20,"description":"차량번호"},"paymentDetail":{"$ref":"#/components/schemas/PaymentDetailInputDto"}},"required":["roomId","stayType","paymentMethod","expectedTotalPrice"]},"CancelBookingDto":{"type":"object","properties":{"reason":{"type":"string","maxLength":500,"description":"취소 사유"},"cancelKioskPayment":{"type":"boolean","description":"키오스크 카드결제 건이 있으면 카드단말 결제취소(환불)까지 연계","default":false}}},"BookingItemSelectionWithMetaResponseDto":{"type":"object","properties":{"id":{"type":"string"},"bookingId":{"type":"string"},"itemId":{"type":"string"},"quantity":{"type":"number"},"unitPriceSnapshot":{"type":"number","description":"저장 시점 단가 스냅샷 (원)"},"ledgerEntryId":{"type":"string","nullable":true,"description":"연결된 Folio CHARGE 원장 ID"},"isPaid":{"type":"boolean","description":"해당 CHARGE 에 대한 PAYMENT 가 존재하면 true"},"paymentMethod":{"type":"string","nullable":true,"enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"결제 완료 시 연결 PAYMENT 의 수단(CARD/CASH/TRANSFER). 미결제·기타 수단은 null"},"isCancelled":{"type":"boolean","description":"결제 취소(전액 환불)로 부대매출이 원복되면 true"},"cancelledAt":{"format":"date-time","type":"string","nullable":true,"description":"결제 취소로 원복된 시각(원복 전이면 null)"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"bookingCheckInAt":{"format":"date-time","type":"string","description":"부킹 예정 체크인 시각 (ISO 8601)"},"bookingStatus":{"type":"string","enum":["CONFIRMED","CHECKED_IN","CHECKED_OUT","CANCELLED","NO_SHOW","SALES_CANCELLED"]}},"required":["id","bookingId","itemId","quantity","unitPriceSnapshot","isPaid","isCancelled","createdAt","updatedAt","bookingCheckInAt","bookingStatus"]},"BookingItemSelectionResponseDto":{"type":"object","properties":{"id":{"type":"string"},"bookingId":{"type":"string"},"itemId":{"type":"string"},"quantity":{"type":"number"},"unitPriceSnapshot":{"type":"number","description":"저장 시점 단가 스냅샷 (원)"},"ledgerEntryId":{"type":"string","nullable":true,"description":"연결된 Folio CHARGE 원장 ID"},"isPaid":{"type":"boolean","description":"해당 CHARGE 에 대한 PAYMENT 가 존재하면 true"},"paymentMethod":{"type":"string","nullable":true,"enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"결제 완료 시 연결 PAYMENT 의 수단(CARD/CASH/TRANSFER). 미결제·기타 수단은 null"},"isCancelled":{"type":"boolean","description":"결제 취소(전액 환불)로 부대매출이 원복되면 true"},"cancelledAt":{"format":"date-time","type":"string","nullable":true,"description":"결제 취소로 원복된 시각(원복 전이면 null)"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","bookingId","itemId","quantity","unitPriceSnapshot","isPaid","isCancelled","createdAt","updatedAt"]},"CreateBookingItemSelectionDto":{"type":"object","properties":{"itemId":{"type":"string","format":"uuid"},"quantity":{"type":"number","minimum":1,"default":1},"unitPrice":{"type":"number","minimum":0,"description":"미지정 시 부대상품 현재 단가"}},"required":["itemId"]},"PatchBookingItemSelectionDto":{"type":"object","properties":{"quantity":{"type":"number","minimum":1},"unitPrice":{"type":"number","minimum":0}}},"CreateAncillaryPaymentDto":{"type":"object","properties":{"selectionIds":{"minItems":1,"description":"결제할 BookingItemSelection ID 목록","type":"array","items":{"type":"string","format":"uuid"}},"method":{"type":"string","enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"CARD | CASH | TRANSFER (EXTERNAL_PREPAID 불가)"},"paymentDetail":{"$ref":"#/components/schemas/PaymentDetailInputDto"}},"required":["selectionIds","method"]},"AncillaryPaymentResponseDto":{"type":"object","properties":{"paymentEntryIds":{"description":"생성된 PAYMENT 원장 ID 목록","type":"array","items":{"type":"string"}},"selectionIds":{"description":"결제 처리된 부대상품 선택 ID","type":"array","items":{"type":"string"}}},"required":["paymentEntryIds","selectionIds"]},"BookingHistoryListBookingSummaryDto":{"type":"object","properties":{"internalBookingNo":{"type":"string"},"scheduledCheckInAt":{"format":"date-time","type":"string"},"scheduledCheckOutAt":{"format":"date-time","type":"string"},"roomNo":{"type":"string","nullable":true,"description":"대표 게스트 기준 배정 객실 호실 번호"},"primaryGuestName":{"type":"string","nullable":true,"description":"첫 번째 게스트명"}},"required":["internalBookingNo","scheduledCheckInAt","scheduledCheckOutAt"]},"BookingHistoryListItemDto":{"type":"object","properties":{"id":{"type":"string"},"bookingId":{"type":"string"},"status":{"type":"string","enum":["CONFIRMED","CHECKED_IN","CHECKED_OUT","CANCELLED","NO_SHOW","SALES_CANCELLED"]},"eventType":{"type":"string","enum":["STATUS_CHANGE","CHECK_IN_REVERTED","CHECK_OUT_REVERTED","BOOKING_CANCEL_REVERTED","SALES_CANCEL_REVERTED","CREATED","EXTENDED","ROOM_TRANSFERRED","ROOM_TYPE_CHANGED"]},"actorType":{"type":"string","enum":["USER","DEVICE","API_KEY","SYSTEM","KIOSK"]},"actorId":{"type":"string","nullable":true},"actorName":{"type":"string","nullable":true},"reason":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"booking":{"$ref":"#/components/schemas/BookingHistoryListBookingSummaryDto"}},"required":["id","bookingId","status","eventType","actorType","createdAt","booking"]},"BookingHistoryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BookingHistoryListItemDto"}},"total":{"type":"number","description":"필터 일치 전체 건수"}},"required":["items","total"]},"BookingMessageItemDto":{"type":"object","properties":{"templateCode":{"type":"string","enum":["room_key_lms","booking_confirm_lms","booking_day_lms"]},"label":{"type":"string","description":"문자 종류 라벨"},"autoSendEnabled":{"type":"boolean","description":"이 숙소에서 자동 발송이 켜져 있는지"},"status":{"type":"string","nullable":true,"enum":["PENDING","SENT","FAILED"],"description":"최근 발송 상태. 발송 이력이 없으면 null."},"recipient":{"type":"string","nullable":true,"description":"수신 번호"},"sentAt":{"type":"string","nullable":true,"description":"발송 성공 시각 (ISO 8601)"},"lastAttemptedAt":{"type":"string","nullable":true,"description":"최근 시도 시각 (ISO 8601)"},"failureReason":{"type":"string","nullable":true,"description":"실패 사유(한국어)"},"canSend":{"type":"boolean","description":"지금 수동 발송이 가능한지"},"blockedReason":{"type":"string","nullable":true,"description":"발송할 수 없을 때 그 이유(한국어). canSend 가 true 면 null."}},"required":["templateCode","label","autoSendEnabled","status","recipient","sentAt","lastAttemptedAt","failureReason","canSend","blockedReason"]},"BookingMessageListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BookingMessageItemDto"}}},"required":["items"]},"BookingPaymentCancelResponseDto":{"type":"object","properties":{"sessionId":{"type":"string","description":"생성된 키오스크 카드단말 취소 세션 ID"}},"required":["sessionId"]},"CreatePersonAdditionDto":{"type":"object","properties":{"addedCount":{"type":"number","minimum":1,"description":"추가 인원 수"},"amount":{"type":"number","minimum":1,"description":"추가 인원 결제 금액(원). 운영자 확정 금액."},"method":{"type":"string","enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"CARD | CASH | TRANSFER (EXTERNAL_PREPAID 불가)"},"paymentDetail":{"$ref":"#/components/schemas/PaymentDetailInputDto"}},"required":["addedCount","amount","method"]},"PersonAdditionResponseDto":{"type":"object","properties":{"personCount":{"type":"number","description":"갱신된 부킹 투숙 인원 수"},"paymentEntryIds":{"description":"생성된 PAYMENT 원장 ID 목록","type":"array","items":{"type":"string"}},"additionId":{"type":"string","description":"생성된 인원추가 추적 레코드 ID"}},"required":["personCount","paymentEntryIds","additionId"]},"PaymentLedgerCardDetailDto":{"type":"object","properties":{"approvalNo":{"type":"string","nullable":true,"description":"카드 승인번호"},"panLast4":{"type":"string","nullable":true,"description":"카드 끝 4자리"},"issuer":{"type":"string","nullable":true,"description":"카드 발급사"},"approvedAt":{"type":"string","nullable":true,"description":"카드 승인 시각 (ISO)"},"installmentMonths":{"type":"number","nullable":true,"description":"할부 개월 수"}}},"PaymentLedgerLineDto":{"type":"object","properties":{"id":{"type":"string","description":"원장 항목 ID (취소 시 ledgerEntryId 로 사용)"},"bookingId":{"type":"string","description":"부킹 ID"},"internalBookingNo":{"type":"string","description":"내부 예약번호"},"bookingStatus":{"type":"string","enum":["CONFIRMED","CHECKED_IN","CHECKED_OUT","CANCELLED","NO_SHOW","SALES_CANCELLED"],"description":"부킹 상태"},"primaryGuestName":{"type":"string","nullable":true,"description":"대표 게스트명"},"channelType":{"type":"string","nullable":true,"enum":["DIRECT","YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"],"description":"예약 채널 (워크인은 null)"},"externalBookingNo":{"type":"string","nullable":true,"description":"외부 예약번호 (OTA)"},"type":{"type":"string","enum":["CHARGE","PAYMENT","REFUND","ADJUSTMENT"],"description":"PAYMENT 또는 REFUND"},"method":{"type":"string","nullable":true,"enum":["CARD","CASH","TRANSFER","EXTERNAL_PREPAID"],"description":"결제수단"},"category":{"type":"string","enum":["ROOM","DAY_USE","EXTENSION","FNB","AMENITY","GOODS","SERVICE","MINIBAR","DAMAGE","DEPOSIT","OTHER"],"description":"원장 카테고리"},"amount":{"type":"number","description":"금액"},"revenueCode":{"type":"string","nullable":true,"description":"매출 코드"},"businessDate":{"type":"string","description":"영업일 (YYYY-MM-DD)"},"occurredAt":{"type":"string","description":"발생 시각 (ISO)"},"referenceEntryId":{"type":"string","nullable":true,"description":"REFUND 라인이 참조하는 원결제(PAYMENT) ID"},"card":{"nullable":true,"description":"카드 세부 정보","allOf":[{"$ref":"#/components/schemas/PaymentLedgerCardDetailDto"}]},"cancelable":{"type":"boolean","description":"키오스크 카드단말 원격 승인취소 가능 여부. CARD + 카드승인번호 존재 + 미환불 PAYMENT 만 true. OTA(EXTERNAL_PREPAID)·현금·이체는 false."},"cashCancelable":{"type":"boolean","description":"키오스크 지폐방출기 현금취소(거스름 방출) 가능 여부. CASH + 미환불 PAYMENT 만 true. 실제 키오스크 라우팅은 취소 요청 시점에 검증한다."},"refundedAt":{"type":"string","nullable":true,"description":"이 PAYMENT 가 환불된 시각 (ISO). 미환불이면 null."}},"required":["id","bookingId","internalBookingNo","bookingStatus","type","category","amount","businessDate","occurredAt","cancelable","cashCancelable"]},"PaymentLedgerListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PaymentLedgerLineDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"BusinessDaySalesCellDto":{"type":"object","properties":{"count":{"type":"number","description":"건수"},"amount":{"type":"number","description":"금액(원). PAYMENT − REFUND."}},"required":["count","amount"]},"BusinessDaySalesRowDto":{"type":"object","properties":{"group":{"type":"string","enum":["DAY_USE","OVERNIGHT","ANCILLARY"]},"saleCount":{"type":"number","description":"이 행에 기여한 부킹 수(중복 제거)"},"cash":{"$ref":"#/components/schemas/BusinessDaySalesCellDto"},"transfer":{"$ref":"#/components/schemas/BusinessDaySalesCellDto"},"card":{"$ref":"#/components/schemas/BusinessDaySalesCellDto"},"externalPrepaid":{"description":"OTA 등 외부 사전결제","allOf":[{"$ref":"#/components/schemas/BusinessDaySalesCellDto"}]},"subtotal":{"description":"수단 4종 합계. 미수는 포함하지 않음","allOf":[{"$ref":"#/components/schemas/BusinessDaySalesCellDto"}]},"unpaid":{"description":"미수 잔액. 합계에서 제외","allOf":[{"$ref":"#/components/schemas/BusinessDaySalesCellDto"}]}},"required":["group","saleCount","cash","transfer","card","externalPrepaid","subtotal","unpaid"]},"BusinessDaySalesSummaryResponseDto":{"type":"object","properties":{"period":{"type":"object","description":"요청 구간"},"from":{"type":"string","description":"집계 시작 instant (포함, ISO 8601)"},"to":{"type":"string","description":"집계 종료 instant (제외, ISO 8601)"},"businessDayCutoff":{"type":"string","description":"적용된 영업일 컷오프 (HH:mm)"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/BusinessDaySalesRowDto"}},"total":{"description":"전체 합계 행","allOf":[{"$ref":"#/components/schemas/BusinessDaySalesRowDto"}]}},"required":["period","from","to","businessDayCutoff","rows","total"]},"BookingRoomStatusCheckedInBookingResponseDto":{"type":"object","properties":{"bookingId":{"type":"string"},"internalBookingNo":{"type":"string"},"guestName":{"type":"string","nullable":true},"scheduledCheckInAt":{"type":"string","format":"date-time"},"scheduledCheckOutAt":{"type":"string","format":"date-time"},"actualCheckInAt":{"type":"string","nullable":true,"format":"date-time"},"channelType":{"type":"string","nullable":true,"enum":["DIRECT","YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"transportationType":{"type":"string","enum":["WALK","VEHICLE"]},"vehicleNumber":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"productName":{"type":"string","nullable":true},"stayType":{"type":"string","nullable":true,"enum":["DAY_USE","OVERNIGHT"]},"kioskCheckIn":{"type":"boolean"}},"required":["bookingId","internalBookingNo","scheduledCheckInAt","scheduledCheckOutAt","transportationType","kioskCheckIn"]},"BookingRoomStatusKioskHoldResponseDto":{"type":"object","properties":{"sessionId":{"type":"string"},"kioskId":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"required":["sessionId","kioskId","expiresAt"]},"BookingRoomStatusResponseDto":{"type":"object","properties":{"id":{"type":"string"},"roomNo":{"type":"string"},"floor":{"type":"number"},"iotGroupId":{"type":"number","nullable":true},"iotLocalId":{"type":"number","nullable":true},"roomTypeId":{"type":"string"},"roomTypeName":{"type":"string"},"sectionId":{"type":"string","nullable":true},"housekeepingStatus":{"type":"string","nullable":true,"enum":["CLEANING_REQUESTED","CLEANING_IN_PROGRESS","CLEAN","INSPECTION_PENDING","INSPECTED"]},"communication":{"type":"string","nullable":true,"enum":["NORMAL","DISCONNECTED"]},"keyStatus":{"type":"string","nullable":true,"enum":["GUEST_KEY","HOUSEKEEPING_KEY","NO_KEY"]},"currentTemp":{"type":"number","nullable":true},"heatingSetpoint":{"type":"number","nullable":true},"doorStatus":{"type":"string","nullable":true,"enum":["OPEN","CLOSED"]},"outletPower":{"type":"boolean","nullable":true},"acPower":{"type":"boolean","nullable":true},"serviceAvailability":{"type":"string","nullable":true,"enum":["AVAILABLE","OUT_OF_ORDER"]},"serviceAvailabilityReason":{"type":"string","nullable":true},"serviceAvailabilityExpectedRecoveryAt":{"type":"string","nullable":true,"format":"date-time"},"occupancyStatus":{"type":"string","nullable":true,"enum":["OCCUPIED","VACANT"]},"memo":{"type":"string","nullable":true},"lastCleaningRequestedAt":{"type":"string","nullable":true,"format":"date-time"},"lastCleaningStartedAt":{"type":"string","nullable":true,"format":"date-time"},"lastCleaningCompletedAt":{"type":"string","nullable":true,"format":"date-time"},"lastInspectionCompletedAt":{"type":"string","nullable":true,"format":"date-time"},"lastServiceAvailabilityChangedAt":{"type":"string","nullable":true,"format":"date-time"},"currentBooking":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/BookingRoomStatusCheckedInBookingResponseDto"}]},"hasCancelableCheckOut":{"type":"boolean"},"kioskHold":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/BookingRoomStatusKioskHoldResponseDto"}]},"heatingTempOnOccupied":{"type":"number","nullable":true},"heatingTempOnVacant":{"type":"number","nullable":true}},"required":["id","roomNo","floor","roomTypeId"]},"DashboardResponseDto":{"type":"object","properties":{"rooms":{"type":"array","items":{"$ref":"#/components/schemas/BookingRoomStatusResponseDto"}},"todayBookings":{"type":"array","items":{"$ref":"#/components/schemas/BookingResponseDto"}}},"required":["rooms","todayBookings"]},"DaemonRoomResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"객실 ID (UUID)"},"roomNo":{"type":"string","description":"객실 번호 (호실)"},"floor":{"type":"number","description":"층"},"iotGroupId":{"type":"number","nullable":true,"description":"IoT 게이트웨이 그룹 ID"},"iotLocalId":{"type":"number","nullable":true,"description":"IoT 게이트웨이 로컬 ID"},"keyStatus":{"type":"string","nullable":true,"description":"키 홀더 상태 (EMPTY / GUEST_KEY / HOUSEKEEPING_KEY)"},"temperature":{"type":"number","nullable":true,"description":"현재 객실 온도(℃)"},"heatingSetpoint":{"type":"number","nullable":true,"description":"난방 설정 온도(℃)"},"outletPower":{"type":"boolean","nullable":true,"description":"콘센트 전원 상태"},"acPower":{"type":"boolean","nullable":true,"description":"에어컨 전원 상태"},"communication":{"type":"string","nullable":true,"description":"객실 IoT 장비 통신 상태 (NORMAL / DISCONNECTED)"},"door":{"type":"boolean","nullable":true,"description":"문 상태. MQTT status 페이로드의 `door` 와 동일 — `true` = 열림, `false` = 닫힘"},"chbStatus":{"type":"string","description":"차임벨(CHB) 목표 상태 — 청소중: SLOW_BLINK, 청소지시: FAST_BLINK, 체크인 배정 객실: ON, 그 외: OFF","enum":["ON","OFF","SLOW_BLINK","FAST_BLINK"]}},"required":["id","roomNo","floor","chbStatus"]},"DaemonRoomListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DaemonRoomResponseDto"}},"total":{"type":"number","description":"전체 객실 수 (gid/lid 미할당 포함)"}},"required":["items","total"]},"BookingRoomStatusListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BookingRoomStatusResponseDto"}},"total":{"type":"number"}},"required":["items","total"]},"BookingRoomStatusHistoryItemResponseDto":{"type":"object","properties":{"id":{"type":"string"},"roomId":{"type":"string"},"roomNo":{"type":"string"},"field":{"type":"string","enum":["OCCUPANCY_STATUS","HOUSEKEEPING_STATUS","STAY_TYPE","COMMUNICATION","CURRENT_TEMP","HEATING_SETPOINT","DOOR_STATUS","OUTLET_POWER","AC_POWER","SERVICE_AVAILABILITY","KEY_STATUS"]},"value":{"type":"string"},"changedAt":{"type":"string","format":"date-time"},"changedBy":{"type":"string","nullable":true},"changedByName":{"type":"string","nullable":true},"metadata":{"type":"object","nullable":true,"additionalProperties":true}},"required":["id","roomId","roomNo","field","value","changedAt"]},"BookingRoomStatusHistoryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BookingRoomStatusHistoryItemResponseDto"}},"total":{"type":"number"}},"required":["items","total"]},"UpdateHousekeepingStatusDto":{"type":"object","properties":{"status":{"type":"string","enum":["CLEANING_REQUESTED","CLEANING_IN_PROGRESS","CLEAN","INSPECTION_PENDING","INSPECTED"],"description":"객실 정비 상태로 직접 강제 변경. null 전환은 별도 complete 엔드포인트를 사용합니다."}},"required":["status"]},"UpdateServiceAvailabilityDto":{"type":"object","properties":{"status":{"type":"string","enum":["AVAILABLE","OUT_OF_ORDER"],"description":"객실 판매 가용성 상태 (AVAILABLE = 판매 재개, OUT_OF_ORDER = 판매 중단)"},"reason":{"type":"string","maxLength":200,"description":"판매 중단 사유 (status=OUT_OF_ORDER 일 때 권장)"},"expectedRecoveryAt":{"type":"string","description":"판매 재개 예정 시각 (ISO 8601, 선택)"}},"required":["status"]},"FolioReservationSummaryDto":{"type":"object","properties":{"id":{"type":"string"},"channelType":{"type":"string","enum":["DIRECT","YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"externalBookingNo":{"type":"string","nullable":true},"stayType":{"type":"string","enum":["DAY_USE","OVERNIGHT"]},"scheduledStart":{"format":"date-time","type":"string","description":"예정 시작. 연결 Booking 의 예정 체크인과 동일"},"scheduledEnd":{"format":"date-time","type":"string","description":"예정 종료. 연결 Booking 의 예정 체크아웃과 동일"},"price":{"type":"number","description":"요금(원). 해당 예약 마스터 Folio 의 CHARGE 원장 합계"},"status":{"type":"string","enum":["CONFIRMED","CHECKED_IN","CHECKED_OUT","CANCELLED","NO_SHOW","SALES_CANCELLED"]},"bookingIds":{"description":"이 Reservation 에 묶인 Booking ID 목록 (순서 비보장)","type":"array","items":{"type":"string"}},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","channelType","stayType","scheduledStart","scheduledEnd","price","status","bookingIds","createdAt","updatedAt"]},"FolioResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"status":{"type":"string","enum":["OPEN","CLOSED","CANCELLED"]},"openedAt":{"format":"date-time","type":"string"},"closedAt":{"format":"date-time","type":"string","nullable":true},"reservations":{"type":"array","items":{"$ref":"#/components/schemas/FolioReservationSummaryDto"}},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","accommodationId","status","openedAt","reservations","createdAt","updatedAt"]},"ReservationResponseDto":{"type":"object","properties":{"id":{"type":"string"},"folioId":{"type":"string","nullable":true,"description":"연결된 Booking 의 마스터 Folio ID (없으면 null)"},"accommodationId":{"type":"string"},"channelType":{"type":"string","enum":["DIRECT","YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"externalBookingNo":{"type":"string","nullable":true},"stayType":{"type":"string","enum":["DAY_USE","OVERNIGHT"]},"scheduledStart":{"format":"date-time","type":"string","description":"예정 시작(체크인 구간 시작). 연결된 Booking 의 예정 체크인과 동일"},"scheduledEnd":{"format":"date-time","type":"string","description":"예정 종료(체크아웃 구간 종료). 연결된 Booking 의 예정 체크아웃과 동일"},"price":{"type":"number","description":"요금(원). 해당 예약 마스터 Folio 의 CHARGE 원장 합계"},"status":{"type":"string","enum":["CONFIRMED","CHECKED_IN","CHECKED_OUT","CANCELLED","NO_SHOW","SALES_CANCELLED"],"description":"연결된 Booking 의 운영 상태"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","accommodationId","channelType","stayType","scheduledStart","scheduledEnd","price","status","createdAt","updatedAt"]},"ReservationListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ReservationResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"RoomKeyResponseDto":{"type":"object","properties":{"accommodationName":{"type":"string","description":"숙소 표시 이름"},"roomNo":{"type":"string","description":"객실 호실 번호 (예: \"201\")"},"otp":{"type":"string","description":"8자리 숫자 OTP. KST 시간 단위로 회전.","example":"01928374"},"qrOtpV1":{"type":"string","description":"QR 코드용 OTP v1 페이로드 (도어락 펌웨어 호환). 형식: `otpv1.{a}.{r}.{otp}`"},"expireAt":{"type":"string","description":"OTP/QR 만료 시각 (다음 정시, ISO 8601)"},"validUntil":{"type":"string","description":"객실 키 자체의 유효 종료 시각 (예약된 체크아웃 시각, ISO 8601)"}},"required":["accommodationName","roomNo","otp","qrOtpV1","expireAt","validUntil"]},"RevokeServiceAgreementsResponseDto":{"type":"object","properties":{"revokedCount":{"type":"number"}},"required":["revokedCount"]},"SubscriptionServiceCatalogItemResponseDto":{"type":"object","properties":{"code":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"billingMode":{"type":"string","enum":["PER_USAGE","FLAT_MONTHLY"]},"unitLabel":{"type":"string","nullable":true},"defaultUnitPrice":{"type":"number","nullable":true},"defaultMonthlyPrice":{"type":"number","nullable":true},"available":{"type":"boolean"}},"required":["code","label","description","billingMode","available"]},"BillingAccountResponseDto":{"type":"object","properties":{"accommodationId":{"type":"string"},"balance":{"type":"number","description":"음수면 미납액"},"creditLimit":{"type":"number"},"availableCredit":{"type":"number","description":"지금 추가로 사용할 수 있는 금액"},"outstanding":{"type":"number"},"delinquentSince":{"type":"string","nullable":true,"format":"date-time"},"billingDay":{"type":"number"},"autoRechargeEnabled":{"type":"boolean"},"autoRechargeThreshold":{"type":"number","nullable":true},"autoRechargeAmount":{"type":"number","nullable":true}},"required":["accommodationId","balance","creditLimit","availableCredit","outstanding","billingDay","autoRechargeEnabled"]},"ResolvedEntitlementResponseDto":{"type":"object","properties":{"code":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"billingMode":{"type":"string","enum":["PER_USAGE","FLAT_MONTHLY"]},"unitLabel":{"type":"string","nullable":true},"defaultUnitPrice":{"type":"number","nullable":true},"defaultMonthlyPrice":{"type":"number","nullable":true},"available":{"type":"boolean"},"serviceCode":{"type":"string"},"enabled":{"type":"boolean"},"suspendedAt":{"type":"string","nullable":true,"format":"date-time"},"unitPrice":{"type":"number","nullable":true},"monthlyPrice":{"type":"number","nullable":true}},"required":["code","label","description","billingMode","available","serviceCode","enabled"]},"AdminSubscriptionResponseDto":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/BillingAccountResponseDto"},"entitlements":{"type":"array","items":{"$ref":"#/components/schemas/ResolvedEntitlementResponseDto"}}},"required":["account","entitlements"]},"UpdateEntitlementDto":{"type":"object","properties":{"enabled":{"type":"boolean"},"billingMode":{"type":"object"},"unitPrice":{"type":"number","nullable":true,"minimum":0},"monthlyPrice":{"type":"number","nullable":true,"minimum":0}},"required":["enabled"]},"AdjustBalanceDto":{"type":"object","properties":{"mode":{"type":"object"},"amount":{"type":"number","description":"TOPUP·CREDIT 은 증액분, ADJUSTMENT 는 목표 잔액이다."},"memo":{"type":"string","maxLength":500}},"required":["mode","amount"]},"BalanceLedgerItemResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"type":{"type":"string","enum":["TOPUP","USAGE_CHARGE","MONTHLY_CHARGE","REFUND","ADJUSTMENT","CREDIT"]},"amount":{"type":"number"},"balanceAfter":{"type":"number"},"serviceCode":{"type":"string","nullable":true},"billingPeriod":{"type":"string","nullable":true},"reference":{"type":"string","nullable":true},"memo":{"type":"string","nullable":true},"createdBy":{"type":"string","nullable":true},"createdByAccountId":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}},"required":["id","accommodationId","type","amount","balanceAfter","createdAt"]},"PaginatedBalanceLedgerResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BalanceLedgerItemResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"UpdateCreditLimitDto":{"type":"object","properties":{"creditLimit":{"type":"number","description":"0 으로 내리면 해당 지점만 선불로 동작한다.","minimum":0,"maximum":100000000},"reason":{"type":"string","description":"여신 한도는 금전 리스크 노출액이라 변경 사유를 필수로 남긴다.","minLength":2,"maxLength":200}},"required":["creditLimit","reason"]},"CreditLimitHistoryItemResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"previousLimit":{"type":"number"},"newLimit":{"type":"number"},"reason":{"type":"string"},"changedBy":{"type":"string","nullable":true},"changedAt":{"type":"string","format":"date-time"}},"required":["id","accommodationId","previousLimit","newLimit","reason","changedAt"]},"CreditLimitHistoryResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CreditLimitHistoryItemResponseDto"}}},"required":["items"]},"UpdateBillingSettingsDto":{"type":"object","properties":{"billingDay":{"type":"number","description":"월 청구 기준일. 말일 이슈를 피하려 28일까지만 허용한다.","minimum":1,"maximum":28},"autoRechargeEnabled":{"type":"boolean"},"autoRechargeThreshold":{"type":"number","minimum":0},"autoRechargeAmount":{"type":"number","minimum":10000,"maximum":10000000}}},"UsageHistoryItemResponseDto":{"type":"object","properties":{"id":{"type":"string"},"serviceCode":{"type":"string"},"label":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"billingPeriod":{"type":"string"},"quantity":{"type":"number"},"unitPrice":{"type":"number"},"amount":{"type":"number"},"referenceType":{"type":"string","nullable":true},"referenceId":{"type":"string","nullable":true}},"required":["id","serviceCode","label","occurredAt","billingPeriod","quantity","unitPrice","amount"]},"PaginatedUsageHistoryResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/UsageHistoryItemResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"InvoiceSummaryResponseDto":{"type":"object","properties":{"id":{"type":"string"},"billingPeriod":{"type":"string"},"status":{"type":"string","enum":["DRAFT","ISSUED","PAID","PARTIALLY_PAID","UNCOLLECTIBLE","VOID"]},"total":{"type":"number"},"paidAmount":{"type":"number"},"issuedAt":{"type":"string","nullable":true,"format":"date-time"},"dueAt":{"type":"string","nullable":true,"format":"date-time"},"paidAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","billingPeriod","status","total","paidAmount"]},"PaginatedInvoiceSummaryResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceSummaryResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"InvoiceLineResponseDto":{"type":"object","properties":{"id":{"type":"string"},"lineType":{"type":"string","enum":["USAGE","MONTHLY","CREDIT","ADJUSTMENT"]},"serviceCode":{"type":"string","nullable":true},"description":{"type":"string"},"quantity":{"type":"number"},"unitPrice":{"type":"number"},"amount":{"type":"number"}},"required":["id","lineType","description","quantity","unitPrice","amount"]},"PaymentCancelResponseDto":{"type":"object","properties":{"id":{"type":"string"},"cancelAmount":{"type":"number"},"reason":{"type":"string"},"canceledAt":{"type":"string","format":"date-time"}},"required":["id","cancelAmount","reason","canceledAt"]},"PaymentSummaryResponseDto":{"type":"object","properties":{"id":{"type":"string"},"purpose":{"type":"string","enum":["TOPUP","SETTLEMENT","AUTO_RECHARGE"]},"status":{"type":"string","enum":["REQUESTED","PAID","FAILED","CANCELED","PARTIAL_CANCELED"]},"amount":{"type":"number"},"canceledAmount":{"type":"number"},"method":{"type":"string","nullable":true},"receiptUrl":{"type":"string","nullable":true},"approvedAt":{"type":"string","nullable":true,"format":"date-time"},"failureMessage":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"cancels":{"type":"array","items":{"$ref":"#/components/schemas/PaymentCancelResponseDto"}}},"required":["id","purpose","status","amount","canceledAmount","createdAt","cancels"]},"InvoiceDetailResponseDto":{"type":"object","properties":{"id":{"type":"string"},"billingPeriod":{"type":"string"},"status":{"type":"string","enum":["DRAFT","ISSUED","PAID","PARTIALLY_PAID","UNCOLLECTIBLE","VOID"]},"total":{"type":"number"},"paidAmount":{"type":"number"},"issuedAt":{"type":"string","nullable":true,"format":"date-time"},"dueAt":{"type":"string","nullable":true,"format":"date-time"},"paidAt":{"type":"string","nullable":true,"format":"date-time"},"usageSubtotal":{"type":"number"},"monthlySubtotal":{"type":"number"},"creditApplied":{"type":"number"},"adjustmentTotal":{"type":"number"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLineResponseDto"}},"payment":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/PaymentSummaryResponseDto"}]}},"required":["id","billingPeriod","status","total","paidAmount","usageSubtotal","monthlySubtotal","creditApplied","adjustmentTotal","lines"]},"ChargeResultResponseDto":{"type":"object","properties":{"paymentId":{"type":"string"},"status":{"type":"string","enum":["REQUESTED","PAID","FAILED","CANCELED","PARTIAL_CANCELED"]},"amount":{"type":"number"},"receiptUrl":{"type":"string","nullable":true},"failureMessage":{"type":"string","nullable":true}},"required":["paymentId","status","amount"]},"PaginatedPaymentSummaryResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PaymentSummaryResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"}},"required":["items","total","page","limit"]},"CancelPaymentDto":{"type":"object","properties":{"cancelAmount":{"type":"number","minimum":1},"reason":{"type":"string","minLength":2,"maxLength":200}},"required":["cancelAmount","reason"]},"AdminBillingDashboardResponseDto":{"type":"object","properties":{"exposure":{"type":"object","additionalProperties":true},"billingPeriod":{"type":"string"},"periodSummary":{"type":"object","additionalProperties":true},"delinquentAccommodations":{"type":"array","items":{"type":"object"}},"unpaidInvoices":{"type":"array","items":{"type":"object"}}},"required":["exposure","billingPeriod","periodSummary","delinquentAccommodations","unpaidInvoices"]},"AdminUsageSearchResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totals":{"type":"object","additionalProperties":true}},"required":["items","total","page","limit","totals"]},"AdminUsageStatisticsResponseDto":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"byService":{"type":"array","items":{"type":"object"}},"byAccommodation":{"type":"array","items":{"type":"object"}},"monthly":{"type":"array","items":{"type":"object"}},"totals":{"type":"object","additionalProperties":true}},"required":["from","to","byService","byAccommodation","monthly","totals"]},"AdminInvoiceSearchResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totals":{"type":"object","additionalProperties":true}},"required":["items","total","page","limit","totals"]},"AdminPaymentSearchResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totals":{"type":"object","additionalProperties":true}},"required":["items","total","page","limit","totals"]},"ClosePeriodInternalDto":{"type":"object","properties":{"billingPeriod":{"type":"string","description":"미지정이면 직전 달을 마감한다.","pattern":"/^\\d{4}-(0[1-9]|1[0-2])$/"}}},"ClosePeriodSweepResultResponseDto":{"type":"object","properties":{"billingPeriod":{"type":"string"},"processed":{"type":"number"},"settled":{"type":"number"},"delinquent":{"type":"number"},"failed":{"type":"number"}},"required":["billingPeriod","processed","settled","delinquent","failed"]},"DunningSweepResultResponseDto":{"type":"object","properties":{"scanned":{"type":"number"},"suspended":{"type":"number"}},"required":["scanned","suspended"]},"AutoRechargeSweepResultResponseDto":{"type":"object","properties":{"candidates":{"type":"number"},"recharged":{"type":"number"},"failed":{"type":"number"}},"required":["candidates","recharged","failed"]},"PmsEntitlementsResponseDto":{"type":"object","properties":{"entitlements":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ResolvedEntitlementResponseDto"}}},"required":["entitlements"]},"CurrentPeriodUsageResponseDto":{"type":"object","properties":{"serviceCode":{"type":"string"},"label":{"type":"string"},"quantity":{"type":"number"},"amount":{"type":"number"},"unitLabel":{"type":"string","nullable":true}},"required":["serviceCode","label","quantity","amount"]},"PaymentMethodResponseDto":{"type":"object","properties":{"id":{"type":"string"},"cardCompany":{"type":"string","nullable":true},"cardNumberMasked":{"type":"string","nullable":true},"cardType":{"type":"string","nullable":true},"registeredAt":{"type":"string","format":"date-time"}},"required":["id","registeredAt"]},"BillingOverviewResponseDto":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/BillingAccountResponseDto"},"billingPeriod":{"type":"string"},"currentPeriodUsage":{"type":"array","items":{"$ref":"#/components/schemas/CurrentPeriodUsageResponseDto"}},"currentPeriodTotal":{"type":"number"},"paymentMethod":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/PaymentMethodResponseDto"}]},"latestInvoice":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/InvoiceSummaryResponseDto"}]},"graceDaysRemaining":{"type":"number","nullable":true}},"required":["account","billingPeriod","currentPeriodUsage","currentPeriodTotal"]},"UsageStatisticsResponseDto":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"daily":{"type":"array","items":{"type":"object"}},"dailyByService":{"type":"array","items":{"type":"object"}},"byService":{"type":"array","items":{"type":"object"}},"monthly":{"type":"array","items":{"type":"object"}},"totalQuantity":{"type":"number"},"totalAmount":{"type":"number"}},"required":["from","to","daily","dailyByService","byService","monthly","totalQuantity","totalAmount"]},"ServiceAgreementBusinessProfileResponseDto":{"type":"object","properties":{"legalName":{"type":"string","nullable":true},"businessRegistrationNumber":{"type":"string","nullable":true},"representativeName":{"type":"string","nullable":true}}},"ServiceAgreementStatusResponseDto":{"type":"object","properties":{"accommodationId":{"type":"string"},"agreed":{"type":"boolean"},"currentVersion":{"type":"string"},"agreedVersion":{"type":"string","nullable":true},"agreedAt":{"type":"string","nullable":true,"format":"date-time"},"businessProfileComplete":{"type":"boolean"},"businessProfile":{"$ref":"#/components/schemas/ServiceAgreementBusinessProfileResponseDto"}},"required":["accommodationId","agreed","currentVersion","businessProfileComplete","businessProfile"]},"RegisterBillingKeyDto":{"type":"object","properties":{"authKey":{"type":"string","description":"토스 결제창(`requestBillingAuth`) 인증 후 리다이렉트로 받는 authKey.","minLength":4,"maxLength":300}},"required":["authKey"]},"RegisterBillingKeyResponseDto":{"type":"object","properties":{"id":{"type":"string"},"cardCompany":{"type":"string","nullable":true},"cardNumberMasked":{"type":"string","nullable":true}},"required":["id"]},"SuccessResponseDto":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"]},"ChargeTopupDto":{"type":"object","properties":{"amount":{"type":"number","minimum":1000,"maximum":10000000}},"required":["amount"]},"ChannelConnectionListItemResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"channelType":{"type":"string","enum":["YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"status":{"type":"string","enum":["ACTIVE","INACTIVE","ERROR"]},"accountId":{"type":"string","nullable":true},"loginId":{"type":"string","nullable":true},"hasPassword":{"type":"boolean"},"syncEnabled":{"type":"boolean"},"syncIntervalMin":{"type":"number","nullable":true},"lastSyncAt":{"type":"string","nullable":true,"format":"date-time"},"lastErrorMessage":{"type":"string","nullable":true},"externalPropertyId":{"type":"string","nullable":true},"externalPropertyName":{"type":"string","nullable":true},"setupStep":{"type":"string","enum":["NONE","LOGGED_IN","PLACE_SELECTED","MAPPED","COMPLETED"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"mappingCount":{"type":"number"}},"required":["id","accommodationId","channelType","status","hasPassword","syncEnabled","setupStep","createdAt","updatedAt","mappingCount"]},"ChannelLoginDto":{"type":"object","properties":{"loginId":{"type":"string","maxLength":255},"password":{"type":"string","maxLength":512}},"required":["loginId","password"]},"ChannelLoginResponseDto":{"type":"object","properties":{"accountId":{"type":"string"},"places":{"type":"array","items":{"type":"object"}},"processedAt":{"type":"string","nullable":true}},"required":["places"]},"ChannelSelectPlaceDto":{"type":"object","properties":{"placeId":{"type":"string","maxLength":120,"description":"OTA 지점(place) ID"},"placeName":{"type":"string","maxLength":255,"description":"지점명"}},"required":["placeId","placeName"]},"ChannelConnectionSafeResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"channelType":{"type":"string","enum":["YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"status":{"type":"string","enum":["ACTIVE","INACTIVE","ERROR"]},"accountId":{"type":"string","nullable":true},"loginId":{"type":"string","nullable":true},"hasPassword":{"type":"boolean"},"syncEnabled":{"type":"boolean"},"syncIntervalMin":{"type":"number","nullable":true},"lastSyncAt":{"type":"string","nullable":true,"format":"date-time"},"lastErrorMessage":{"type":"string","nullable":true},"externalPropertyId":{"type":"string","nullable":true},"externalPropertyName":{"type":"string","nullable":true},"setupStep":{"type":"string","enum":["NONE","LOGGED_IN","PLACE_SELECTED","MAPPED","COMPLETED"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","accommodationId","channelType","status","hasPassword","syncEnabled","setupStep","createdAt","updatedAt"]},"ChannelOtaProductsResponseDto":{"type":"object","properties":{"products":{"type":"array","items":{"type":"object"}},"fetchedAt":{"type":"string","nullable":true}},"required":["products"]},"ChannelProductMappingResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"channelType":{"type":"string","enum":["YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"productId":{"type":"string"},"externalProductId":{"type":"string"},"externalProductName":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","accommodationId","channelType","productId","externalProductId","createdAt","updatedAt"]},"ReplaceMappingItemDto":{"type":"object","properties":{"productId":{"type":"string","format":"uuid","description":"PMS(catalog) 상품 ID"},"externalProductId":{"type":"string","maxLength":120,"description":"OTA 상품 ID"},"externalProductName":{"type":"string","nullable":true,"maxLength":255}}},"ChannelReplaceMappingsDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ReplaceMappingItemDto"}}},"required":["items"]},"ChannelPreviewReservationsDto":{"type":"object","properties":{"dateFrom":{"type":"string","description":"YYYY-MM-DD"},"dateTo":{"type":"string","description":"YYYY-MM-DD"}},"required":["dateFrom","dateTo"]},"ChannelPreviewReservationsResponseDto":{"type":"object","properties":{"reservations":{"type":"array","items":{"type":"object"}},"scrapedAt":{"type":"string","nullable":true}},"required":["reservations"]},"ChannelImportSkippedReasonsResponseDto":{"type":"object","properties":{"noMapping":{"type":"number"},"noProduct":{"type":"number"},"notInAccommodation":{"type":"number"},"invalidDate":{"type":"number"},"alreadyExists":{"type":"number"}},"required":["noMapping","noProduct","notInAccommodation","invalidDate","alreadyExists"]},"ChannelSyncImportResultResponseDto":{"type":"object","properties":{"imported":{"type":"number"},"updated":{"type":"number"},"skipped":{"type":"number"},"mappingsCount":{"type":"number"},"reservationsCount":{"type":"number"},"skippedReasons":{"$ref":"#/components/schemas/ChannelImportSkippedReasonsResponseDto"},"details":{"type":"array","items":{"type":"object"}},"scrapedAt":{"type":"string","nullable":true}},"required":["imported","updated","skipped"]},"ChannelSyncLogEntryResponseDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"channelType":{"type":"string"},"loginStatus":{"type":"string"},"loginMessage":{"type":"string","nullable":true},"roomTypeStatus":{"type":"string"},"roomTypeMessage":{"type":"string","nullable":true},"roomTypeData":{"type":"object","nullable":true},"reservationStatus":{"type":"string"},"reservationMessage":{"type":"string","nullable":true},"reservationData":{"type":"object","nullable":true},"createdAt":{"type":"string","format":"date-time"}},"required":["id","accommodationId","channelType","loginStatus","roomTypeStatus","reservationStatus","createdAt"]},"ChannelSyncLogListResponseDto":{"type":"object","properties":{"logs":{"type":"array","items":{"$ref":"#/components/schemas/ChannelSyncLogEntryResponseDto"}},"total":{"type":"number"}},"required":["logs","total"]},"ChannelDisconnectResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","example":true}},"required":["ok"]},"InboundMailForwarderDto":{"type":"object","properties":{"address":{"type":"string"},"status":{"type":"string","enum":["PENDING","VERIFIED"]},"verifiedAt":{"type":"string","nullable":true,"format":"date-time"},"lastSeenAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["address","status"]},"InboundMailChannelStatusDto":{"type":"object","properties":{"channelType":{"type":"string","enum":["YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"health":{"type":"object"},"reservationActivityCount":{"type":"number"},"mailHitCount":{"type":"number"},"lastHitAt":{"type":"string","nullable":true,"format":"date-time"},"lastSyncAt":{"type":"string","nullable":true,"format":"date-time"},"diagnosis":{"type":"string"}},"required":["channelType","health","reservationActivityCount","mailHitCount","diagnosis"]},"InboundMailSelfTestDto":{"type":"object","properties":{"hitCount":{"type":"number"},"lastAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["hitCount"]},"InboundMailStatusResponseDto":{"type":"object","properties":{"triggerId":{"type":"string","nullable":true},"code":{"type":"string","nullable":true},"inboundAddress":{"type":"string","nullable":true},"enabled":{"type":"boolean"},"onboardingOpenedAt":{"type":"string","nullable":true,"format":"date-time"},"forwarders":{"type":"array","items":{"$ref":"#/components/schemas/InboundMailForwarderDto"}},"channels":{"type":"array","items":{"$ref":"#/components/schemas/InboundMailChannelStatusDto"}},"selfTest":{"$ref":"#/components/schemas/InboundMailSelfTestDto"}},"required":["enabled","forwarders","channels","selfTest"]},"InboundMailOnboardingResponseDto":{"type":"object","properties":{"triggerId":{"type":"string"},"code":{"type":"string"},"inboundAddress":{"type":"string"},"enabled":{"type":"boolean"},"onboardingOpenedAt":{"type":"string","nullable":true,"format":"date-time"},"forwarders":{"type":"array","items":{"$ref":"#/components/schemas/InboundMailForwarderDto"}}},"required":["triggerId","code","inboundAddress","enabled","forwarders"]},"InboundMailCoverageCellDto":{"type":"object","properties":{"accommodationId":{"type":"string"},"accommodationName":{"type":"string"},"channelType":{"type":"string","enum":["YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"health":{"type":"object"},"reservationActivityCount":{"type":"number"},"mailHitCount":{"type":"number"},"lastHitAt":{"type":"string","nullable":true,"format":"date-time"}},"required":["accommodationId","accommodationName","channelType","health","reservationActivityCount","mailHitCount"]},"InboundMailCoverageLatencyDto":{"type":"object","properties":{"mailTriggeredCount":{"type":"number"},"cronTriggeredCount":{"type":"number"},"avgMailDelaySeconds":{"type":"number","nullable":true},"avgCronDelaySeconds":{"type":"number","nullable":true}},"required":["mailTriggeredCount","cronTriggeredCount"]},"InboundMailCoverageResponseDto":{"type":"object","properties":{"lookbackDays":{"type":"number"},"cells":{"type":"array","items":{"$ref":"#/components/schemas/InboundMailCoverageCellDto"}},"misconfigured":{"type":"array","items":{"$ref":"#/components/schemas/InboundMailCoverageCellDto"}},"latency":{"$ref":"#/components/schemas/InboundMailCoverageLatencyDto"}},"required":["lookbackDays","cells","misconfigured","latency"]},"OtaSmsHitDto":{"type":"object","properties":{"senderNumber":{"type":"string"},"channelType":{"type":"string","nullable":true,"enum":["YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]},"messageType":{"type":"string"},"subject":{"type":"string","nullable":true},"bodyPreview":{"type":"string","nullable":true},"dispatched":{"type":"boolean"},"skipReason":{"type":"string","nullable":true},"receivedAt":{"type":"string","format":"date-time"}},"required":["senderNumber","messageType","dispatched","receivedAt"]},"OtaSmsStatusResponseDto":{"type":"object","properties":{"number":{"type":"string","nullable":true,"description":"지점에 배정된 수신번호. 없으면 아직 발급 전이다."},"numberStatus":{"type":"string","nullable":true,"enum":["ASSIGNED","QUARANTINED","IDLE","RELEASED"]},"assignedAt":{"type":"string","nullable":true,"format":"date-time"},"health":{"type":"string","enum":["NOT_STARTED","WAITING","UNMAPPED_SENDER","LIVE"]},"hitCount":{"type":"number","description":"최근 수신 건수. 대기 화면에서 첫 수신을 감지하는 데 쓴다."},"dispatchedCount":{"type":"number"},"lastHitAt":{"type":"string","nullable":true,"format":"date-time"},"unmappedSenders":{"description":"매핑되지 않아 버려진 발신번호. 업주에게는 \"확인 중\"으로 보여준다.","type":"array","items":{"type":"string"}},"recentHits":{"type":"array","items":{"$ref":"#/components/schemas/OtaSmsHitDto"}},"diagnosis":{"type":"string"}},"required":["health","hitCount","dispatchedCount","unmappedSenders","recentHits","diagnosis"]},"OtaSmsUnmappedSenderDto":{"type":"object","properties":{"senderNumber":{"type":"string"},"hitCount":{"type":"number"},"lastReceivedAt":{"type":"string","format":"date-time"},"lastBodyPreview":{"type":"string","nullable":true,"description":"가장 최근 문자의 본문 앞부분. 어느 OTA 인지 눈으로 판정할 단서다."}},"required":["senderNumber","hitCount","lastReceivedAt"]},"OtaSmsSenderMappingDto":{"type":"object","properties":{"senderNumber":{"type":"string"},"channelTypes":{"type":"array","items":{"type":"string","enum":["YANOLJA_MOTEL","YANOLJA_HOTEL","YEOGI_MARKETING","YEOGI_PARTNER","NAVER","AIRBNB","AGODA","EXPEDIA","BOOKING_COM","HOTELS_COM","TRIP_COM","KKULSTAY"]}},"label":{"type":"string","nullable":true},"enabled":{"type":"boolean"},"updatedAt":{"type":"string","format":"date-time"}},"required":["senderNumber","channelTypes","enabled","updatedAt"]},"UpsertOtaSmsSenderMappingDto":{"type":"object","properties":{"senderNumber":{"type":"string","maxLength":20},"channelTypes":{"minItems":1,"type":"array","items":{"type":"object"}},"label":{"type":"string","maxLength":100},"enabled":{"type":"boolean"}},"required":["senderNumber","channelTypes"]},"OtaSmsNumberResponseDto":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"object"},"accommodationId":{"type":"string","nullable":true},"assignedAt":{"type":"string","nullable":true,"format":"date-time"},"quarantineUntil":{"type":"string","nullable":true,"format":"date-time"},"providerAccountId":{"type":"string"}},"required":["id","number","status","providerAccountId"]},"OtaSmsNumbersListResponseDto":{"type":"object","properties":{"counts":{"type":"object","additionalProperties":{"type":"number"}},"numbers":{"type":"array","items":{"$ref":"#/components/schemas/OtaSmsNumberResponseDto"}}},"required":["counts","numbers"]},"OtaSmsOrphanNumbersResponseDto":{"type":"object","properties":{"numbers":{"type":"array","items":{"type":"string"}}},"required":["numbers"]},"ExternalPingResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"apiKeyId":{"type":"string","nullable":true},"scopedAccommodationGroupId":{"type":"string","nullable":true}},"required":["ok"]},"KioskAddonItemDto":{"type":"object","properties":{"itemId":{"type":"string","description":"부대상품(아이템) ID"},"name":{"type":"string","description":"표시명"},"unitPrice":{"type":"number","description":"현재 단가 (원)"},"unitLabel":{"type":"string","description":"단위 라벨 (예: 개, 박스)"},"allowMultipleSale":{"type":"boolean","description":"PMS 설정: 수량 복수 선택 허용 여부. false 면 수량 고정 1","default":true}},"required":["itemId","name","unitPrice","unitLabel","allowMultipleSale"]},"UnsellableReasonDto":{"type":"object","properties":{"code":{"type":"string","description":"판매 불가 사유 코드"},"message":{"type":"string","description":"판매 불가 사유 설명 (한글)"}},"required":["code","message"]},"ProductImageInfoDto":{"type":"object","properties":{"id":{"type":"string","description":"이미지 ID"},"url":{"type":"string","description":"이미지 URL"},"sortOrder":{"type":"number","description":"정렬 순서"}},"required":["id","url","sortOrder"]},"KioskRoomTypeContextDto":{"type":"object","properties":{"roomTypeId":{"type":"string","description":"객실 타입 ID"},"roomTypeName":{"type":"string","description":"객실 타입명"},"defaultCapacity":{"type":"number","description":"기본 수용 인원"},"maxCapacity":{"type":"number","description":"최대 수용 인원"},"totalRooms":{"type":"number","description":"총 객실 수"},"vacantRooms":{"type":"number","description":"공실 수 (상태 기반, 카드키 있는 객실만)"},"todayReservedCount":{"type":"number","description":"당일 예약 수 (상품 기준)"},"todayAssignedCount":{"type":"number","description":"실제 배정된 객실 수"},"availableForSale":{"type":"number","description":"판매 가능 객실 수"}},"required":["roomTypeId","roomTypeName","defaultCapacity","maxCapacity","totalRooms","vacantRooms","todayReservedCount","todayAssignedCount","availableForSale"]},"ProductAvailabilityDto":{"type":"object","properties":{"productId":{"type":"string","description":"상품 ID"},"productName":{"type":"string","description":"상품명"},"stayType":{"type":"string","enum":["DAY_USE","OVERNIGHT"],"description":"숙박 유형"},"currentPrice":{"type":"number","nullable":true,"description":"현재 가격 (원)"},"extraPersonFee":{"type":"number","description":"추가 인원 1인당 요금 (원). 요금 미설정 시 0"},"items":{"description":"상품에 연결된 부대상품","type":"array","items":{"$ref":"#/components/schemas/KioskAddonItemDto"}},"baseHours":{"type":"number","nullable":true,"description":"기본 이용 시간 (시간)"},"checkInFrom":{"type":"string","nullable":true,"description":"체크인 가능 시작 시간 (HH:MM)"},"checkInTo":{"type":"string","nullable":true,"description":"체크인 가능 종료 시간 (HH:MM)"},"checkOutBy":{"type":"string","nullable":true,"description":"체크아웃 마감 시간 (HH:MM)"},"isSellable":{"type":"boolean","description":"판매 가능 여부"},"unsellableReasons":{"description":"판매 불가 사유 목록","type":"array","items":{"$ref":"#/components/schemas/UnsellableReasonDto"}},"images":{"description":"상품 이미지 목록","type":"array","items":{"$ref":"#/components/schemas/ProductImageInfoDto"}},"roomType":{"description":"소속 객실 타입 재고 컨텍스트","allOf":[{"$ref":"#/components/schemas/KioskRoomTypeContextDto"}]}},"required":["productId","productName","stayType","extraPersonFee","items","isSellable","unsellableReasons","images","roomType"]},"KioskRoomAvailabilityResponseDto":{"type":"object","properties":{"accommodationId":{"type":"string","description":"숙소 ID"},"generatedAt":{"type":"string","description":"조회 시점 (ISO8601)"},"currentTime":{"type":"string","description":"조회 기준 시각 (HH:MM)"},"products":{"description":"상품별 판매 가능 정보 (flat)","type":"array","items":{"$ref":"#/components/schemas/ProductAvailabilityDto"}}},"required":["accommodationId","generatedAt","currentTime","products"]},"KioskSelfResponseDto":{"type":"object","properties":{"kioskId":{"type":"string"},"accommodationId":{"type":"string"},"deviceCode":{"type":"string"},"commandTopic":{"type":"string","description":"구독: 서버 명령"},"broadcastStatusTopic":{"type":"string","description":"상태 브로드캐스트(retained 가능)"},"sessionStateTopic":{"type":"string","description":"구독: KioskSession 상태 스냅샷(retained)"},"uiCommandTopic":{"type":"string","description":"구독: 화면 강제 전환 등 UI 명령"}},"required":["kioskId","accommodationId","deviceCode","commandTopic","broadcastStatusTopic","sessionStateTopic","uiCommandTopic"]},"KioskCardSlotItemDto":{"type":"object","properties":{"slotId":{"type":"string"},"iotGroupId":{"type":"number","description":"카드데크 그룹 주소(gid)"},"iotLocalId":{"type":"number","description":"카드데크 로컬 주소(lid)"},"keyCardNumber":{"type":"number","description":"슬롯 적재 카드 바코드 (= property.room.key_card_number)"},"status":{"type":"string","enum":["OK","ERROR"],"description":"슬롯 HW/적재 상태"},"roomId":{"type":"string","nullable":true,"description":"바코드로 해석한 객실 ID. 일치 객실이 없으면 null"},"roomNo":{"type":"string","nullable":true,"description":"바코드로 해석한 호실. 일치 객실이 없으면 null"}},"required":["slotId","iotGroupId","iotLocalId","keyCardNumber","status","roomId","roomNo"]},"KioskCardSlotsResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/KioskCardSlotItemDto"}}},"required":["items"]},"KioskTerminalPolicyResponseDto":{"type":"object","properties":{"adultVerificationEnabled":{"type":"boolean","description":"성인 인증 단계 필요 여부"},"outOfService":{"type":"boolean","description":"사용 중단(점검) 상태 여부. true 면 단말에 점검중 화면 표시."}},"required":["adultVerificationEnabled","outOfService"]},"CreateKioskSessionBodyDto":{"type":"object","properties":{}},"CreateKioskSessionResponseDto":{"type":"object","properties":{"sessionId":{"type":"string"},"step":{"type":"string","enum":["INTRO","HOME","RESERVATION_LOOKUP","VEHICLE_REGISTER","PRODUCT_SELECT","GUEST_COUNT","ADDON_SELECT","PAYMENT","ADULT_VERIFY","COMPLETE","CANCELLED"]}},"required":["sessionId","step"]},"KioskSelectedAddonDto":{"type":"object","properties":{"itemId":{"type":"string","description":"부대상품(아이템) ID"},"quantity":{"type":"number","description":"선택 수량","minimum":1}},"required":["itemId","quantity"]},"KioskSessionProductContextDto":{"type":"object","properties":{"productId":{"type":"string","description":"상품 ID"},"extraPersonFee":{"type":"number","description":"추가 인원 1인당 요금 (원)"},"minPersonCount":{"type":"number","description":"선택 가능 최소 인원"},"maxPersonCount":{"type":"number","description":"선택 가능 최대 인원"},"bookedPersonCount":{"type":"number","nullable":true,"description":"예약 시 확정된 인원 (예약 플로우)"},"items":{"description":"선택 가능 부대상품","type":"array","items":{"$ref":"#/components/schemas/KioskAddonItemDto"}},"paymentAmount":{"type":"number","nullable":true,"description":"현재 예상 결제 금액 (원)"}},"required":["productId","extraPersonFee","minPersonCount","maxPersonCount","items"]},"AssignedRoomKioskDto":{"type":"object","properties":{"id":{"type":"string"},"roomNo":{"type":"string"},"keyCardNumber":{"type":"number","nullable":true}},"required":["id","roomNo","keyCardNumber"]},"KioskSessionStateDto":{"type":"object","properties":{"sessionId":{"type":"string"},"flow":{"type":"string","nullable":true,"enum":["WALK_IN_HOURLY","WALK_IN_OVERNIGHT","RESERVATION","ADDITIONAL_PAYMENT"],"description":"HOME(인트로) 단계에서는 null"},"step":{"type":"string","enum":["INTRO","HOME","RESERVATION_LOOKUP","VEHICLE_REGISTER","PRODUCT_SELECT","GUEST_COUNT","ADDON_SELECT","PAYMENT","ADULT_VERIFY","COMPLETE","CANCELLED"]},"bookingId":{"type":"string","nullable":true},"productId":{"type":"string","nullable":true},"personCount":{"type":"number","nullable":true,"description":"선택 인원 수 (GUEST_COUNT 단계 이후)"},"requestedNights":{"type":"number","description":"워크인 OVERNIGHT 숙박 박 수(N박). 단일 1박이면 1. DAY_USE·예약 flow 는 1. paymentAmount 는 이 박 수의 박별 정확 합 기준"},"requestedRoomCount":{"type":"number","description":"워크인 다객실 객실 수. 단일이면 1. 예약 flow 는 booking.roomCount 사용하므로 1. paymentAmount 는 이 객실 수가 반영된 합계"},"selectedItemIds":{"description":"선택한 부대상품 item ID 목록(멀티셋). 동일 item 이 수량만큼 반복되어 포함된다. 수량 집계는 selectedItems 사용 권장","type":"array","items":{"type":"string"}},"selectedItems":{"description":"선택한 부대상품을 수량과 함께 집계한 목록","type":"array","items":{"$ref":"#/components/schemas/KioskSelectedAddonDto"}},"transportationType":{"type":"string","nullable":true,"enum":["WALK","VEHICLE"],"description":"선택한 방문 수단(WALK/VEHICLE). VEHICLE_REGISTER 단계 통과 전에는 null"},"vehicleNumber":{"type":"string","nullable":true,"description":"차량번호(차량 방문 시). 도보거나 미입력이면 null"},"paymentAmount":{"type":"number","nullable":true,"description":"결제 금액 (원)"},"paymentMethod":{"type":"string","nullable":true,"enum":["CARD","CASH"]},"paymentStatus":{"type":"string","nullable":true},"adultVerifyRequired":{"type":"boolean"},"adultVerifyResult":{"type":"string","nullable":true,"enum":["PASSED","FAILED","SKIPPED"]},"productContext":{"nullable":true,"description":"현재 단계 UI용 상품·인원·부대상품 컨텍스트","allOf":[{"$ref":"#/components/schemas/KioskSessionProductContextDto"}]},"assignedRooms":{"description":"배정·체크인 완료된 전체 객실 목록(다객실). 단일 객실이면 길이 1, 미배정 시 빈 배열. 대표(1차) 객실은 assignedRooms[0]. 키 카드는 각 객실별 1장씩 토출됨","type":"array","items":{"$ref":"#/components/schemas/AssignedRoomKioskDto"}},"updatedAt":{"type":"string"}},"required":["sessionId","step","requestedNights","requestedRoomCount","adultVerifyRequired","assignedRooms","updatedAt"]},"SelectFlowBodyDto":{"type":"object","properties":{"flow":{"type":"string","enum":["WALK_IN_HOURLY","WALK_IN_OVERNIGHT","RESERVATION"]}},"required":["flow"]},"ReservationSearchBodyDto":{"type":"object","properties":{"q":{"type":"string","minLength":1,"maxLength":64,"description":"예약번호·전화 뒷자리·이름 등"},"suffixLength":{"type":"number","minimum":1,"maximum":20,"description":"외부예약번호·전화번호 뒷자리 매칭 자릿수 (기본 4)","default":4}},"required":["q"]},"ReservationSearchItemDto":{"type":"object","properties":{"bookingId":{"type":"string"},"code":{"type":"string"},"guestName":{"type":"string"},"roomSummary":{"type":"string"}},"required":["bookingId","code","guestName","roomSummary"]},"ReservationSearchResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ReservationSearchItemDto"}},"ambiguous":{"type":"boolean","description":"동일 검색어로 2건 이상 매칭 시 true — 풀 예약번호 또는 전화번호 입력 안내 필요"}},"required":["items","ambiguous"]},"SelectBookingBodyDto":{"type":"object","properties":{"bookingId":{"type":"string"}},"required":["bookingId"]},"RegisterVehicleBodyDto":{"type":"object","properties":{"transportationType":{"type":"string","enum":["WALK","VEHICLE"],"description":"방문 수단. WALK(도보) 또는 VEHICLE(차량). VEHICLE 이면 vehicleNumber 필수"},"vehicleNumber":{"type":"string","minLength":1,"maxLength":20,"description":"차량번호(차량 방문 시 필수). 최대 20자"}},"required":["transportationType"]},"AdultVerifyBodyDto":{"type":"object","properties":{"result":{"type":"string","enum":["PASSED","FAILED"]}},"required":["result"]},"SubmitIdVerificationBodyDto":{"type":"object","properties":{"imageBase64":{"type":"string","minLength":100,"maxLength":7340032,"description":"신분증 이미지 base64 (data URL 허용)"},"verifierRole":{"type":"string","enum":["PRIMARY","COMPANION"],"default":"PRIMARY","description":"인증 주체: PRIMARY(본인) | COMPANION(동반자)"},"isLastVerification":{"type":"boolean","default":true,"description":"이번 인증 후 ADULT_VERIFY 단계를 종료할지. false면 동반자 스캔 대기(ADULT_VERIFY 유지)"}},"required":["imageBase64"]},"IdVerificationResultDto":{"type":"object","properties":{"verificationId":{"type":"string"},"verifierRole":{"type":"string","enum":["PRIMARY","COMPANION"]},"documentType":{"type":"string","enum":["RESIDENT_REGISTRATION_CARD","DRIVER_LICENSE","PASSPORT","FOREIGN_REGISTRATION_CARD","UNKNOWN"]},"isAdult":{"type":"boolean"},"birthDate":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"verifiedAdultCount":{"type":"number","description":"현재 세션에서 성인 인증 완료 인원 수"},"maxAdultCount":{"type":"number","description":"성인 인증 가능 최대 인원(본인 포함)"},"canAddCompanion":{"type":"boolean","description":"동반자 1명 추가 인증 가능 여부"}},"required":["verificationId","verifierRole","documentType","isAdult","verifiedAdultCount","maxAdultCount","canAddCompanion"]},"KioskDispenseCardBodyDto":{"type":"object","properties":{"barcode":{"type":"number","minimum":0,"description":"토출 대상 카드 바코드(정수)"}},"required":["barcode"]},"KioskIssueCommandResponseDto":{"type":"object","properties":{"commandId":{"type":"string"}},"required":["commandId"]},"KioskPrintReceiptResponseDto":{"type":"object","properties":{"commandId":{"type":"string","description":"발행된 영수증 출력 command id"}},"required":["commandId"]},"KioskAncillaryPaymentItemDto":{"type":"object","properties":{"itemId":{"type":"string","format":"uuid","description":"부대상품(카탈로그 item) ID"},"quantity":{"type":"number","minimum":1,"description":"수량"}},"required":["itemId","quantity"]},"KioskAncillaryPaymentStartBodyDto":{"type":"object","properties":{"bookingId":{"type":"string","format":"uuid","description":"대상 예약 ID"},"amount":{"type":"number","minimum":1,"description":"카드단말에 청구할 금액(원). 선택 부대상품 합계."},"items":{"minItems":1,"description":"결제할 부대상품(품목+수량) 목록","type":"array","items":{"$ref":"#/components/schemas/KioskAncillaryPaymentItemDto"}}},"required":["bookingId","amount","items"]},"KioskAdditionalPaymentStartResponseDto":{"type":"object","properties":{"sessionId":{"type":"string","description":"생성된 키오스크 추가결제 세션 ID"}},"required":["sessionId"]},"KioskExtensionPaymentStartBodyDto":{"type":"object","properties":{"bookingId":{"type":"string","format":"uuid","description":"대상 예약 ID"},"productId":{"type":"string","format":"uuid","description":"연장 구간 판매 상품 ID"},"additionalPrice":{"type":"number","minimum":1,"description":"추가 구간 결제 금액(원). 카드단말 청구 금액."},"additionalNights":{"type":"number","minimum":1,"description":"숙박 연장 시 추가 숙박일수"},"scheduledCheckOutAt":{"type":"string","description":"예정 체크아웃 시각 (ISO8601). 대실 연장 시 필수."}},"required":["bookingId","productId","additionalPrice"]},"KioskPersonAdditionPaymentStartBodyDto":{"type":"object","properties":{"bookingId":{"type":"string","format":"uuid","description":"대상 예약 ID"},"addedCount":{"type":"number","minimum":1,"description":"추가 인원 수"},"amount":{"type":"number","minimum":1,"description":"카드단말에 청구할 금액(원). 추가 인원 요금."}},"required":["bookingId","addedCount","amount"]},"SelectProductBodyDto":{"type":"object","properties":{"productId":{"type":"string"},"roomCount":{"type":"number","minimum":1,"maximum":32,"description":"워크인 다객실 — 한 번에 잡을 객실 수. 생략 시 1(단일 객실, 기존 동작). 동일 상품(객실 타입) N실 배정·체크인"},"nights":{"type":"number","minimum":1,"maximum":30,"description":"워크인 OVERNIGHT 숙박 박 수(N박). 생략 시 1(1박, 기존 동작). DAY_USE·예약(RESERVATION) flow 에서는 무시(1). 박별 정확 요금은 서버가 catalog 로 계산"}},"required":["productId"]},"GuestCountBodyDto":{"type":"object","properties":{"personCount":{"type":"number","minimum":1,"description":"투숙 인원 수"}},"required":["personCount"]},"SelectAddonItemDto":{"type":"object","properties":{"itemId":{"type":"string","pattern":"UUID_STRING_PATTERN","description":"부대상품(아이템) ID"},"quantity":{"type":"number","minimum":1,"maximum":99,"description":"선택 수량 (기본 1). allowMultipleSale=false 인 item 은 1 로 강제된다","default":1}},"required":["itemId"]},"SelectAddonsBodyDto":{"type":"object","properties":{"items":{"description":"수량 포함 부대상품 선택 목록. allowMultipleSale 이 켜진 item 만 quantity>1 허용. 빈 배열이면 선택 없음.","type":"array","items":{"$ref":"#/components/schemas/SelectAddonItemDto"}}},"required":["items"]},"StartPaymentBodyDto":{"type":"object","properties":{"method":{"type":"string","enum":["CARD","CASH"]}},"required":["method"]},"CheckInKioskBodyDto":{"type":"object","properties":{"idVerificationId":{"type":"string","description":"1단계 성인 인증에서 발급된 ID"}}},"CheckInResponseKioskDto":{"type":"object","properties":{"bookingId":{"type":"string"},"assignedRooms":{"description":"체크인 완료된 전체 객실(다객실). 단일이면 길이 1. 대표(1차) 객실은 assignedRooms[0]","type":"array","items":{"$ref":"#/components/schemas/AssignedRoomKioskDto"}},"cardDispenseCommandIds":{"description":"배정 객실별 키 카드 토출 command id 목록(다객실 = N개). 대표(1차) 객실은 [0]","type":"array","items":{"type":"string"}}},"required":["bookingId","assignedRooms","cardDispenseCommandIds"]},"KioskSummaryDto":{"type":"object","properties":{"id":{"type":"string"},"accommodationId":{"type":"string"},"deviceCode":{"type":"string"},"adultVerificationEnabled":{"type":"boolean"},"outOfService":{"type":"boolean","description":"운영자가 사용 중단(점검) 상태로 전환했는지 여부"},"lastSeenAt":{"type":"string","nullable":true}},"required":["id","accommodationId","deviceCode","adultVerificationEnabled","outOfService"]},"KioskSummariesResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/KioskSummaryDto"}},"total":{"type":"number"}},"required":["items","total"]},"UpdateKioskSettingsBodyDto":{"type":"object","properties":{"adultVerificationEnabled":{"type":"boolean"},"outOfService":{"type":"boolean","description":"키오스크 사용 중단(점검) 토글"}}},"UpdateKioskSettingsResponseDto":{"type":"object","properties":{"id":{"type":"string"},"adultVerificationEnabled":{"type":"boolean"},"outOfService":{"type":"boolean"}},"required":["id","adultVerificationEnabled","outOfService"]},"KioskActiveSessionDto":{"type":"object","properties":{"sessionId":{"type":"string"},"flow":{"type":"string","nullable":true,"description":"HOME(인트로) 단계에서는 null"},"step":{"type":"string"},"startedAt":{"type":"string"},"lastStepAt":{"type":"string"},"expiresAt":{"type":"string"},"assignedRoomName":{"type":"string","nullable":true}},"required":["sessionId","step","startedAt","lastStepAt","expiresAt"]},"KioskActiveSessionResponseDto":{"type":"object","properties":{"session":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/KioskActiveSessionDto"}]},"state":{"nullable":true,"description":"활성 세션 전체 상태(원격 제어 콘솔용). session 이 null 이면 null.","allOf":[{"$ref":"#/components/schemas/KioskSessionStateDto"}]}}},"KioskLatestDeviceSnapshotDto":{"type":"object","properties":{"deviceKind":{"type":"string"},"slotKey":{"type":"string","nullable":true},"eventType":{"type":"string"},"errorCode":{"type":"string","nullable":true},"payload":{"type":"object"},"occurredAt":{"type":"string"},"receivedAt":{"type":"string"}},"required":["deviceKind","eventType","payload","occurredAt","receivedAt"]},"KioskDeviceLatestResponseDto":{"type":"object","properties":{"kioskId":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/KioskLatestDeviceSnapshotDto"}}},"required":["kioskId","items"]},"KioskDeviceEventsPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object"}},"nextCursor":{"type":"string","nullable":true}},"required":["items"]},"KioskEventHistoryItemDto":{"type":"object","properties":{"id":{"type":"string"},"kioskId":{"type":"string"},"deviceCode":{"type":"string","description":"키오스크 식별 코드"},"deviceKind":{"type":"string"},"slotKey":{"type":"string","nullable":true},"eventType":{"type":"string"},"errorCode":{"type":"string","nullable":true},"payload":{"type":"object"},"commandId":{"type":"string","nullable":true},"direction":{"type":"string"},"occurredAt":{"type":"string"},"receivedAt":{"type":"string"}},"required":["id","kioskId","deviceCode","deviceKind","eventType","payload","direction","occurredAt","receivedAt"]},"KioskEventHistoryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/KioskEventHistoryItemDto"}},"total":{"type":"number"}},"required":["items","total"]},"CctvChannelImageDto":{"type":"object","properties":{"channelNo":{"type":"number","minimum":1,"maximum":8,"description":"DVR 채널 번호(1~8)"},"imageBase64":{"type":"string","minLength":100,"maxLength":8388608,"description":"채널 스냅샷 이미지 base64 (data URL 허용)"}},"required":["channelNo","imageBase64"]},"SubmitCctvCaptureBodyDto":{"type":"object","properties":{"capturePoint":{"type":"string","enum":["CUSTOMER_ARRIVAL","BEFORE_ADULT_VERIFY","PAYMENT_COMPLETE"],"description":"CCTV 캡처 세션 시점"},"channels":{"minItems":1,"description":"채널별 스냅샷(최대 8채널). 일부 채널만 전송 가능.","type":"array","items":{"$ref":"#/components/schemas/CctvChannelImageDto"}}},"required":["capturePoint","channels"]},"SubmitCctvCaptureResultDto":{"type":"object","properties":{"captureId":{"type":"string"},"capturePoint":{"type":"string","enum":["CUSTOMER_ARRIVAL","BEFORE_ADULT_VERIFY","PAYMENT_COMPLETE"]},"channelCount":{"type":"number","description":"저장된 채널 수"},"capturedAt":{"type":"string","description":"ISO 8601"}},"required":["captureId","capturePoint","channelCount","capturedAt"]},"CctvSessionSummaryDto":{"type":"object","properties":{"sessionId":{"type":"string"},"flow":{"type":"string","nullable":true,"enum":["WALK_IN_HOURLY","WALK_IN_OVERNIGHT","RESERVATION","ADDITIONAL_PAYMENT"]},"step":{"type":"string","enum":["INTRO","HOME","RESERVATION_LOOKUP","VEHICLE_REGISTER","PRODUCT_SELECT","GUEST_COUNT","ADDON_SELECT","PAYMENT","ADULT_VERIFY","COMPLETE","CANCELLED"]},"startedAt":{"type":"string","nullable":true,"description":"세션 시작 시각 ISO 8601"},"lastCapturedAt":{"type":"string","description":"최근 캡처 시각 ISO 8601"},"captureCount":{"type":"number","description":"세션의 캡처 이벤트 수"},"bookingId":{"type":"string","nullable":true,"description":"연결된 예약 ID(체크인 완료 세션)"}},"required":["sessionId","step","lastCapturedAt","captureCount"]},"CctvSessionListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CctvSessionSummaryDto"}}},"required":["items"]},"CctvCaptureChannelDto":{"type":"object","properties":{"channelNo":{"type":"number"},"imageUrl":{"type":"string","description":"인증 프록시 이미지 조회 URL(상대 경로)"}},"required":["channelNo","imageUrl"]},"CctvCaptureItemDto":{"type":"object","properties":{"captureId":{"type":"string"},"capturePoint":{"type":"string","enum":["CUSTOMER_ARRIVAL","BEFORE_ADULT_VERIFY","PAYMENT_COMPLETE"]},"capturedAt":{"type":"string","description":"ISO 8601"},"channels":{"type":"array","items":{"$ref":"#/components/schemas/CctvCaptureChannelDto"}}},"required":["captureId","capturePoint","capturedAt","channels"]},"CctvCaptureListResponseDto":{"type":"object","properties":{"sessionId":{"type":"string"},"captures":{"type":"array","items":{"$ref":"#/components/schemas/CctvCaptureItemDto"}}},"required":["sessionId","captures"]},"KioskIdVerificationViewItemDto":{"type":"object","properties":{"verificationId":{"type":"string"},"verifierRole":{"type":"string","enum":["PRIMARY","COMPANION"]},"documentType":{"type":"string","enum":["RESIDENT_REGISTRATION_CARD","DRIVER_LICENSE","PASSPORT","FOREIGN_REGISTRATION_CARD","UNKNOWN"]},"maskingStatus":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED","EXPIRED"]},"imageUrl":{"type":"string","nullable":true,"description":"마스킹 완료 시에만 이미지 프록시 URL이 포함됩니다."}},"required":["verificationId","verifierRole","documentType","maskingStatus","imageUrl"]},"KioskIdVerificationListResponseDto":{"type":"object","properties":{"bookingId":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/KioskIdVerificationViewItemDto"}}},"required":["bookingId","items"]},"AnalystDatabaseInfoResponseDto":{"type":"object","properties":{"database":{"type":"string","enum":["property","booking","catalog","notification","channel","kiosk","subscription"]},"descriptionKo":{"type":"string"}},"required":["database","descriptionKo"]},"AnalystDatabaseCatalogResponseDto":{"type":"object","properties":{"databases":{"type":"array","items":{"$ref":"#/components/schemas/AnalystDatabaseInfoResponseDto"}}},"required":["databases"]},"AnalystMessageDto":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant"],"description":"발화 주체"},"content":{"type":"string","maxLength":8000,"description":"메시지 본문"}},"required":["role","content"]},"AnalystMessageImageDto":{"type":"object","properties":{"mimeType":{"type":"string","enum":["image/jpeg","image/png","image/webp","application/pdf","text/plain","text/csv","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-excel"],"description":"첨부 파일 MIME 타입"},"data":{"type":"string","maxLength":14000000,"description":"base64 인코딩 파일 (data: 접두사 없음)"},"fileName":{"type":"string","maxLength":255,"description":"UI 표시용 파일명 (Gemini 전송에는 미사용)"}},"required":["mimeType","data"]},"AnalystQueryRequestDto":{"type":"object","properties":{"messages":{"minItems":1,"maxItems":50,"description":"대화 히스토리 (마지막이 최신 질문)","type":"array","items":{"$ref":"#/components/schemas/AnalystMessageDto"}},"latestImages":{"maxItems":4,"description":"이번 질문(마지막 user 메시지)에 첨부한 파일 (최대 4개). 히스토리에는 넣지 않는다.","type":"array","items":{"$ref":"#/components/schemas/AnalystMessageImageDto"}},"mode":{"type":"string","enum":["fast","precise"],"default":"fast","description":"fast=Flash(빠른 분석), precise=Pro(정밀 분석)"}},"required":["messages"]},"ApiErrorResponseDto":{"type":"object","required":["statusCode","error","timestamp"],"properties":{"statusCode":{"type":"integer","example":400},"error":{"type":"object","required":["code","message","messageKo"],"properties":{"code":{"type":"string","example":"VALIDATION_FAILED"},"message":{"type":"string","example":"Validation failed"},"messageKo":{"type":"string","example":"요청 값이 올바르지 않습니다."}}},"timestamp":{"type":"string","format":"date-time"},"details":{"type":"object","additionalProperties":true}}}},"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"},"api-key":{"type":"apiKey","in":"header","name":"X-API-Key"}}},"tags":[{"name":"숙소·객실 설정","description":"숙소·객실·그룹 설정"},{"name":"키오스크","description":"키오스크 세션·원격 제어·주변기기"}],"x-tagGroups":[{"name":"API","tags":["숙소·객실 설정","키오스크"]}]}