> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.vpms.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 숙박시설 관리 (Accommodation)

> 숙박시설, 키오스크, 테마 관리를 위한 GraphQL API

## 개요

Core 서비스의 숙박시설 도메인은 숙박시설(Accommodation) 정보 관리, 키오스크 설정, 테마 관리, 게시물 관리 등 숙박시설 운영에 필요한 전반적인 기능을 제공합니다.

## 권한 체계

숙박시설 API는 다음과 같은 권한 레벨을 사용합니다:

* **OWNER**: 숙박시설 소유자 (모든 권한)
* **MANAGER**: 관리자 (키오스크, 테마, 게시물 관리)
* **STAFF**: 직원 (기본 조회)
* **MAID**: 객실 관리자 (청소 및 객실 상태 관리)

## Queries

### getMyAccommodations

현재 사용자가 관리하는 숙박시설 목록을 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetMyAccommodations {
  getMyAccommodations {
    id
    name
    address1
    address2
    contact
    csContact
    state
    isActive
    isHome
  }
}
```

#### 권한 요구사항

<ParamField path="userType" type="PARTNER" required>
  파트너 계정 이상의 권한 필요
</ParamField>

#### 응답

<ResponseField name="id" type="String!">
  숙박시설 고유 ID (ULID 형식)
</ResponseField>

<ResponseField name="name" type="String!">
  숙박시설 이름
</ResponseField>

<ResponseField name="address1" type="String">
  주소 (도로명/지번)
</ResponseField>

<ResponseField name="address2" type="String">
  상세 주소
</ResponseField>

<ResponseField name="contact" type="String">
  대표 연락처
</ResponseField>

<ResponseField name="csContact" type="String">
  고객 서비스 연락처
</ResponseField>

<ResponseField name="isActive" type="Boolean!">
  활성화 상태
</ResponseField>

<ResponseField name="isHome" type="Boolean">
  홈 화면 기본 숙박시설 여부
</ResponseField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  query {
    getMyAccommodations {
      id
      name
      isActive
      rooms {
        id
        name
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "getMyAccommodations": [
        {
          "id": "01HQKS9V8X2N3P4Q5R6S7T8U9V",
          "name": "벤딧 호텔",
          "isActive": true,
          "rooms": [
            {
              "id": "01HQKS9V8X2N3P4Q5R6S7T8U9W",
              "name": "101호"
            }
          ]
        }
      ]
    }
  }
  ```
</CodeGroup>

***

### getSingleAccommodation

특정 숙박시설의 상세 정보를 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetSingleAccommodation($id: ID!) {
  getSingleAccommodation(id: $id) {
    id
    name
    address1
    address2
    contact
    csContact
    registererName
    registrationNumber
    state
    isActive
    options {
      key
      value
    }
    rooms {
      id
      name
    }
    kiosks {
      id
      name
      type
      state
    }
  }
}
```

#### 파라미터

<ParamField path="id" type="ID!" required>
  조회할 숙박시설 ID
</ParamField>

#### 권한 요구사항

* 숙박시설 관리 권한 (MAID 이상) 또는
* 서드파티 API 접근 권한 (`ACC_ROOMTYPE_READ`)

#### 응답

<ResponseField name="options" type="[Option]">
  숙박시설 설정 옵션 배열

  * `defaultCheckOut`: 기본 체크아웃 시간
  * `defaultInitTemperature`: 기본 초기 온도
  * 기타 커스텀 설정
</ResponseField>

<ResponseField name="rooms" type="[Room]">
  숙박시설에 속한 객실 목록
</ResponseField>

<ResponseField name="kiosks" type="[Kiosk]">
  숙박시설에 설치된 키오스크 목록
</ResponseField>

<ResponseField name="state" type="String">
  숙박시설 상태:

  * `inactive`: 비활성화
  * `needKiosk`: 키오스크 설치 필요
  * `error`: 키오스크 오류 발생
  * `normal`: 정상 운영
</ResponseField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  query {
    getSingleAccommodation(id: "01HQKS9V8X2N3P4Q5R6S7T8U9V") {
      id
      name
      state
      options {
        key
        value
      }
      upcomingReservationCount
      activeReservationCount
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "getSingleAccommodation": {
        "id": "01HQKS9V8X2N3P4Q5R6S7T8U9V",
        "name": "벤딧 호텔",
        "state": "normal",
        "options": [
          {
            "key": "defaultCheckOut",
            "value": "11:00"
          },
          {
            "key": "defaultInitTemperature",
            "value": "24"
          }
        ],
        "upcomingReservationCount": 5,
        "activeReservationCount": 12
      }
    }
  }
  ```
</CodeGroup>

***

### getSingleAccommodationByName

숙박시설 이름으로 공개 정보를 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetSingleAccommodationByName($name: String!) {
  getSingleAccommodationByName(name: $name) {
    id
    name
    address1
    address2
    csContact
  }
}
```

#### 파라미터

<ParamField path="name" type="String!" required>
  조회할 숙박시설 이름 (정확히 일치해야 함)
</ParamField>

#### 특징

<Info>
  인증 없이 접근 가능한 공개 API입니다. 민감한 정보(등록번호, 암호화키 등)는 반환되지 않습니다.
</Info>

***

### getBriefAccommodationById

숙박시설 ID로 공개 정보를 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetBriefAccommodationById($id: ID!) {
  getBriefAccommodationById(id: $id) {
    id
    name
    address1
    address2
    csContact
  }
}
```

#### 파라미터

<ParamField path="id" type="ID!" required>
  조회할 숙박시설 ID
</ParamField>

***

### getAccommodationKiosks

숙박시설의 키오스크 목록을 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetAccommodationKiosks($id: ID!) {
  getAccommodationKiosks(id: $id) {
    id
    name
    type
    location
    state
    accommodationId
  }
}
```

#### 파라미터

<ParamField path="id" type="ID!" required>
  숙박시설 ID
</ParamField>

#### 권한 요구사항

<ParamField path="authority" type="MANAGER" required>
  관리자 이상의 권한 필요
</ParamField>

#### 응답

<ResponseField name="state" type="KioskState">
  키오스크 상태:

  * `ACTIVE`: 정상 가동
  * `ERROR`: 오류 발생
  * `MAINTENANCE`: 유지보수 중
  * `STOPPED`: 정지됨
</ResponseField>

***

### getAccommodationArticles

숙박시설 게시물 목록을 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetAccommodationArticles($accommodationId: ID!, $type: String) {
  getAccommodationArticles(accommodationId: $accommodationId, type: $type) {
    id
    title
    content
    type
    attachments
    views
    createdAt
    updatedAt
  }
}
```

#### 파라미터

<ParamField path="accommodationId" type="ID!" required>
  숙박시설 ID
</ParamField>

<ParamField path="type" type="String">
  게시물 타입:

  * `ACC_INTRO`: 숙박시설 소개
  * `KIOSK_INTRO`: 키오스크 안내
  * `KIOSK_MAIN_INTRO`: 키오스크 메인 화면
  * `TERMS_INTRO`: 이용약관
</ParamField>

#### 응답

<ResponseField name="attachments" type="[String]">
  첨부 이미지 파일명 배열
</ResponseField>

<ResponseField name="views" type="Int">
  조회수 (IP 기반 중복 방지)
</ResponseField>

***

## Mutations

### createAccommodation

새로운 숙박시설을 생성합니다.

#### GraphQL Signature

```graphql theme={null}
mutation CreateAccommodation($input: CreateAccommodationInput!) {
  createAccommodation(input: $input) {
    id
    name
    address1
    address2
    contact
    csContact
    isActive
  }
}
```

#### 파라미터

<ParamField path="input.name" type="String!" required>
  숙박시설 이름 (중복 불가)
</ParamField>

<ParamField path="input.contact" type="String">
  대표 연락처
</ParamField>

<ParamField path="input.address1" type="String">
  주소
</ParamField>

<ParamField path="input.address2" type="String">
  상세 주소
</ParamField>

<ParamField path="input.csContact" type="String">
  고객 서비스 연락처
</ParamField>

<ParamField path="input.registererName" type="String">
  등록자 이름
</ParamField>

<ParamField path="input.registrationNumber" type="String">
  사업자등록번호
</ParamField>

#### 권한 요구사항

<ParamField path="userType" type="PARTNERADMIN" required>
  파트너 관리자 권한 필요
</ParamField>

#### 특징

* 생성 시 자동으로 기본 RoomType 생성
* 생성자가 자동으로 OWNER 권한으로 등록
* 초기 상태는 `isActive: false` (관리자 승인 필요)

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  mutation {
    createAccommodation(
      input: {
        name: "벤딧 호텔"
        address1: "서울시 강남구 테헤란로 123"
        address2: "벤딧빌딩 10층"
        contact: "02-1234-5678"
        csContact: "02-1234-5679"
        registererName: "홍길동"
        registrationNumber: "123-45-67890"
      }
    ) {
      id
      name
      isActive
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "createAccommodation": {
        "id": "01HQKS9V8X2N3P4Q5R6S7T8U9V",
        "name": "벤딧 호텔",
        "isActive": false
      }
    }
  }
  ```
</CodeGroup>

***

### updateAccommodation

숙박시설 정보를 수정합니다.

#### GraphQL Signature

```graphql theme={null}
mutation UpdateAccommodation($input: UpdateAccommodationInput!) {
  updateAccommodation(input: $input) {
    id
    name
    address1
    address2
    contact
    options {
      key
      value
    }
  }
}
```

#### 파라미터

<ParamField path="input.id" type="ID!" required>
  수정할 숙박시설 ID
</ParamField>

<ParamField path="input.name" type="String">
  숙박시설 이름
</ParamField>

<ParamField path="input.options" type="[OptionInput]">
  설정 옵션 배열

  * 존재하지 않는 키는 새로 생성
  * 존재하는 키는 값 업데이트
</ParamField>

#### 권한 요구사항

<ParamField path="authority" type="OWNER" required>
  소유자 권한 필요
</ParamField>

#### 제약사항

<Warning>
  * 활성화된 숙박시설만 수정 가능
  * `system`으로 시작하는 키는 수정 불가 (시스템 예약)
</Warning>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  mutation {
    updateAccommodation(
      input: {
        id: "01HQKS9V8X2N3P4Q5R6S7T8U9V"
        name: "벤딧 프리미엄 호텔"
        contact: "02-9999-8888"
        options: [
          { key: "defaultCheckOut", value: "12:00" }
          { key: "defaultInitTemperature", value: "25" }
          { key: "customSetting", value: "enabled" }
        ]
      }
    ) {
      id
      name
      options {
        key
        value
      }
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "updateAccommodation": {
        "id": "01HQKS9V8X2N3P4Q5R6S7T8U9V",
        "name": "벤딧 프리미엄 호텔",
        "options": [
          {
            "key": "defaultCheckOut",
            "value": "12:00"
          },
          {
            "key": "defaultInitTemperature",
            "value": "25"
          },
          {
            "key": "customSetting",
            "value": "enabled"
          }
        ]
      }
    }
  }
  ```
</CodeGroup>

***

### deleteAccommodation

숙박시설을 삭제합니다.

#### GraphQL Signature

```graphql theme={null}
mutation DeleteAccommodation($id: ID!) {
  deleteAccommodation(id: $id) {
    result
  }
}
```

#### 파라미터

<ParamField path="id" type="ID!" required>
  삭제할 숙박시설 ID
</ParamField>

#### 권한 요구사항

<ParamField path="authority" type="OWNER" required>
  소유자 권한 필요
</ParamField>

***

### addUserToAccommodation

숙박시설에 사용자를 추가합니다.

#### GraphQL Signature

```graphql theme={null}
mutation AddUserToAccommodation(
  $userId: ID!
  $accommodationId: ID!
  $authority: AccommodationAuthority
) {
  addUserToAccommodation(
    userId: $userId
    accommodationId: $accommodationId
    authority: $authority
  ) {
    id
    name
  }
}
```

#### 파라미터

<ParamField path="userId" type="ID!" required>
  추가할 사용자 ID
</ParamField>

<ParamField path="accommodationId" type="ID!" required>
  숙박시설 ID
</ParamField>

<ParamField path="authority" type="AccommodationAuthority">
  부여할 권한:

  * `OWNER`: 소유자
  * `MANAGER`: 관리자
  * `STAFF`: 직원 (기본값)
  * `MAID`: 객실 관리자
  * `KIOSK`: 키오스크
</ParamField>

#### 권한 요구사항

<ParamField path="authority" type="OWNER" required>
  소유자 권한 또는 시스템 관리자 권한 필요
</ParamField>

***

### deleteUserFromAccommodation

숙박시설에서 사용자를 제거합니다.

#### GraphQL Signature

```graphql theme={null}
mutation DeleteUserFromAccommodation($userId: ID!, $accommodationId: ID!) {
  deleteUserFromAccommodation(userId: $userId, accommodationId: $accommodationId) {
    id
    name
  }
}
```

#### 제약사항

<Warning>
  마지막 남은 OWNER는 삭제할 수 없습니다. 최소 1명의 소유자가 필요합니다.
</Warning>

***

### activateSingleAccommodation

숙박시설을 활성화합니다.

#### GraphQL Signature

```graphql theme={null}
mutation ActivateSingleAccommodation($accommodationId: ID!) {
  activateSingleAccommodation(accommodationId: $accommodationId) {
    id
    isActive
  }
}
```

#### 권한 요구사항

<ParamField path="userType" type="ADMIN" required>
  시스템 관리자 권한 필요
</ParamField>

***

### setHomeAccommodation

사용자의 기본(홈) 숙박시설을 설정합니다.

#### GraphQL Signature

```graphql theme={null}
mutation SetHomeAccommodation($accommodationId: ID!) {
  setHomeAccommodation(accommodationId: $accommodationId) {
    id
    isHome
  }
}
```

#### 특징

* 이전 홈 숙박시설은 자동으로 `isHome: false`로 변경
* 사용자당 1개의 홈 숙박시설만 설정 가능

***

## 키오스크 관리

### 키오스크 Enum 타입

#### KioskState

| 값             | 설명     |
| ------------- | ------ |
| `ACTIVE`      | 정상 가동  |
| `ERROR`       | 오류 발생  |
| `MAINTENANCE` | 유지보수 중 |
| `STOPPED`     | 정지됨    |

#### KioskLanguage

키오스크 지원 언어:

| 값       | 설명     |
| ------- | ------ |
| `KO`    | 한국어    |
| `EN`    | 영어     |
| `ZH_CN` | 중국어 간체 |
| `ZH_TW` | 중국어 번체 |
| `JA`    | 일본어    |

#### KioskColorMode

| 값       | 설명     |
| ------- | ------ |
| `LIGHT` | 라이트 모드 |
| `DARK`  | 다크 모드  |

***

### createAccommodationKiosk

숙박시설에 새 키오스크를 생성합니다.

#### GraphQL Signature

```graphql theme={null}
mutation CreateAccommodationKiosk($input: CreateKioskInput!) {
  createAccommodationKiosk(input: $input) {
    id
    name
    type
    location
    state
  }
}
```

#### 파라미터

<ParamField path="input.accommodationId" type="ID!" required>
  숙박시설 ID
</ParamField>

<ParamField path="input.name" type="String!" required>
  키오스크 이름 (숙박시설 내 중복 불가)
</ParamField>

<ParamField path="input.type" type="String">
  키오스크 타입
</ParamField>

<ParamField path="input.location" type="String">
  설치 위치
</ParamField>

<ParamField path="input.state" type="KioskState">
  초기 상태
</ParamField>

#### 권한 요구사항

<ParamField path="authority" type="OWNER" required>
  소유자 권한 필요
</ParamField>

***

### updateAccommodationKiosk

키오스크 정보를 수정합니다.

#### GraphQL Signature

```graphql theme={null}
mutation UpdateAccommodationKiosk($input: UpdateKioskInput!) {
  updateAccommodationKiosk(input: $input) {
    id
    name
    type
    location
    state
  }
}
```

#### 권한 요구사항

<ParamField path="authority" type="MANAGER" required>
  관리자 이상의 권한 필요
</ParamField>

***

### deleteAccommodationKiosk

키오스크를 삭제합니다.

#### GraphQL Signature

```graphql theme={null}
mutation DeleteAccommodationKiosk($id: ID!) {
  deleteAccommodationKiosk(id: $id) {
    result
  }
}
```

#### 권한 요구사항

<ParamField path="authority" type="OWNER" required>
  소유자 권한 필요
</ParamField>

***

### setKioskOptions

키오스크 설정 옵션을 변경합니다.

#### GraphQL Signature

```graphql theme={null}
mutation SetKioskOptions($kioskId: ID!, $inputs: [OptionInput!]!) {
  setKioskOptions(kioskId: $kioskId, inputs: $inputs) {
    key
    value
  }
}
```

#### 파라미터

<ParamField path="kioskId" type="ID!" required>
  키오스크 ID
</ParamField>

<ParamField path="inputs" type="[OptionInput!]!" required>
  설정할 옵션 배열
</ParamField>

#### 특징

* 존재하지 않는 키는 새로 생성
* 존재하는 키는 값 업데이트
* 캐시 자동 갱신

***

## 이미지 업로드

### uploadAuthImages

키오스크 인증용 이미지를 업로드합니다.

#### GraphQL Signature

```graphql theme={null}
mutation UploadAuthImages($kioskId: ID!, $files: [Upload!]!) {
  uploadAuthImages(kioskId: $kioskId, files: $files)
}
```

#### 파라미터

<ParamField path="kioskId" type="ID!" required>
  키오스크 ID
</ParamField>

<ParamField path="files" type="[Upload!]!" required>
  업로드할 이미지 파일 배열
</ParamField>

#### 제약사항

* **허용 형식**: PNG, JPEG, JPG, GIF
* **최대 크기**: 20MB/파일
* 업로드된 이미지는 인증용 스토리지에 저장

#### 응답

<ResponseField name="urls" type="[String!]!">
  업로드된 이미지의 사전 서명된 URL 배열
</ResponseField>

***

### uploadKioskBannerImages

키오스크 배너 이미지를 업로드하고 관리합니다.

#### GraphQL Signature

```graphql theme={null}
mutation UploadKioskBannerImages(
  $kioskId: ID!
  $files: [Upload!]!
  $persistFiles: [String!]
) {
  uploadKioskBannerImages(
    kioskId: $kioskId
    files: $files
    persistFiles: $persistFiles
  )
}
```

#### 파라미터

<ParamField path="kioskId" type="ID!" required>
  키오스크 ID
</ParamField>

<ParamField path="files" type="[Upload!]!" required>
  새로 업로드할 이미지 파일 배열
</ParamField>

<ParamField path="persistFiles" type="[String!]">
  유지할 기존 파일명 배열 (이 배열에 없는 기존 파일은 삭제됨)
</ParamField>

#### 권한 요구사항

<ParamField path="authority" type="MANAGER" required>
  관리자 이상의 권한 필요
</ParamField>

***

## 게시물 관리

### createAccommodationArticle

숙박시설 게시물을 생성합니다.

#### GraphQL Signature

```graphql theme={null}
mutation CreateAccommodationArticle($input: CreateAccommodationArticleInput!) {
  createAccommodationArticle(input: $input) {
    id
    title
    content
    type
    attachments
  }
}
```

#### 파라미터

<ParamField path="input.accommodationId" type="ID!" required>
  숙박시설 ID
</ParamField>

<ParamField path="input.title" type="String">
  게시물 제목
</ParamField>

<ParamField path="input.content" type="String">
  게시물 내용
</ParamField>

<ParamField path="input.type" type="String!" required>
  게시물 타입:

  * `ACC_INTRO`: 숙박시설 소개
  * `KIOSK_INTRO`: 키오스크 안내
  * `KIOSK_MAIN_INTRO`: 키오스크 메인 화면
  * `TERMS_INTRO`: 이용약관
</ParamField>

#### 권한 요구사항

<ParamField path="authority" type="MANAGER" required>
  관리자 이상의 권한 또는 시스템 관리자 권한 필요
</ParamField>

***

### uploadAccommodationArticleImages

게시물에 이미지를 업로드합니다.

#### GraphQL Signature

```graphql theme={null}
mutation UploadAccommodationArticleImages(
  $articleId: ID!
  $files: [Upload!]!
  $persistFiles: [String!]
) {
  uploadAccommodationArticleImages(
    articleId: $articleId
    files: $files
    persistFiles: $persistFiles
  ) {
    id
    attachments
  }
}
```

#### 특징

* 새 이미지 업로드 및 기존 이미지 관리
* `persistFiles`에 없는 기존 파일은 자동 삭제
* 이미지는 게시물별 디렉토리에 저장

***

### updateAccommodationArticle

게시물을 수정합니다.

#### GraphQL Signature

```graphql theme={null}
mutation UpdateAccommodationArticle($input: UpdateAccommodationArticleInput!) {
  updateAccommodationArticle(input: $input) {
    id
    title
    content
    type
  }
}
```

***

### deleteAccommodationArticle

게시물을 삭제합니다.

#### GraphQL Signature

```graphql theme={null}
mutation DeleteAccommodationArticle($id: ID!) {
  deleteAccommodationArticle(id: $id) {
    result
  }
}
```

***

## 테마 관리

### createTheme

숙박시설에 새 테마를 생성합니다.

#### GraphQL Signature

```graphql theme={null}
mutation CreateTheme($name: String!, $accommodationId: ID!) {
  createTheme(name: $name, accommodationId: $accommodationId) {
    id
    name
    accommodationId
  }
}
```

#### 파라미터

<ParamField path="name" type="String!" required>
  테마 이름 (숙박시설 내 중복 불가)
</ParamField>

<ParamField path="accommodationId" type="ID!" required>
  숙박시설 ID
</ParamField>

#### 권한 요구사항

<ParamField path="authority" type="MANAGER" required>
  관리자 이상의 권한 필요
</ParamField>

***

### updateTheme

테마 정보를 수정합니다.

#### GraphQL Signature

```graphql theme={null}
mutation UpdateTheme($id: ID!, $name: String!) {
  updateTheme(id: $id, name: $name) {
    id
    name
  }
}
```

***

### deleteTheme

테마를 삭제합니다.

#### GraphQL Signature

```graphql theme={null}
mutation DeleteTheme($id: ID!) {
  deleteTheme(id: $id) {
    result
  }
}
```

***

## OCR 및 얼굴 인식

### verifyIdByOCR

신분증 이미지를 OCR로 인식하고 검증합니다.

#### GraphQL Signature

```graphql theme={null}
mutation VerifyIdByOCR($input: VerifyIdByOCRInput!) {
  verifyIdByOCR(input: $input) {
    isValid
    idType
    userIdentifier
    name
    maskedCoordinates
    croppedCoordinates
  }
}
```

#### 파라미터

<ParamField path="input.idImage" type="Upload!" required>
  신분증 이미지 파일
</ParamField>

#### 권한 요구사항

<ParamField path="userType" type="PARTNERADMIN" required>
  파트너 관리자 권한 필요
</ParamField>

#### 응답

<ResponseField name="isValid" type="Boolean!">
  신분증 유효성 검증 결과
</ResponseField>

<ResponseField name="idType" type="String">
  신분증 타입 (자동 감지)
</ResponseField>

<ResponseField name="userIdentifier" type="String">
  주민등록번호 등 식별자
</ResponseField>

<ResponseField name="name" type="String">
  인식된 이름
</ResponseField>

<ResponseField name="maskedCoordinates" type="[[[Int]]]">
  개인정보 마스킹 영역 좌표
</ResponseField>

<ResponseField name="croppedCoordinates" type="[[Int]]">
  신분증 영역 좌표
</ResponseField>

#### 특징

* Google Vision API를 사용한 OCR
* 국가 자동 감지 (한국, 외국인등록증 등)
* 개인정보 자동 마스킹 좌표 제공
* 보안을 위해 처리 후 이미지 버퍼 즉시 삭제

***

### requestFaceDetection

이미지에서 얼굴을 감지하고 연령/성별을 추정합니다.

#### GraphQL Signature

```graphql theme={null}
mutation RequestFaceDetection($pictures: [Upload!]!) {
  requestFaceDetection(pictures: $pictures) {
    faces {
      age {
        low
        high
        estimated
      }
      gender
      x
      y
      width
      height
    }
  }
}
```

#### 파라미터

<ParamField path="pictures" type="[Upload!]!" required>
  얼굴 감지할 이미지 파일 배열
</ParamField>

#### 제약사항

* **허용 형식**: PNG, JPEG, JPG, GIF
* **최대 크기**: 10MB/파일

#### 응답

<ResponseField name="faces" type="[Face]">
  감지된 얼굴 정보 배열
</ResponseField>

<ResponseField name="faces[].age.low" type="Int">
  추정 연령 하한
</ResponseField>

<ResponseField name="faces[].age.high" type="Int">
  추정 연령 상한
</ResponseField>

<ResponseField name="faces[].age.estimated" type="Int">
  추정 연령 (하한 + 30%)
</ResponseField>

<ResponseField name="faces[].gender" type="String">
  성별: `MALE` 또는 `FEMALE`
</ResponseField>

<ResponseField name="faces[].x" type="Float">
  얼굴 영역 X 좌표 (비율)
</ResponseField>

<ResponseField name="faces[].y" type="Float">
  얼굴 영역 Y 좌표 (비율)
</ResponseField>

<ResponseField name="faces[].width" type="Float">
  얼굴 영역 너비 (비율)
</ResponseField>

<ResponseField name="faces[].height" type="Float">
  얼굴 영역 높이 (비율)
</ResponseField>

#### 특징

* AWS Rekognition을 사용한 얼굴 감지
* 여러 이미지 동시 처리 가능
* 이미지당 여러 얼굴 감지 지원

***

## 오디오 옵션 관리

### createAccommodationAudioOption

숙박시설 오디오 옵션을 생성합니다.

#### GraphQL Signature

```graphql theme={null}
mutation CreateAccommodationAudioOption($input: CreateAudioOptionInput!) {
  createAccommodationAudioOption(input: $input) {
    id
    accommodationId
    key
    value
  }
}
```

***

### updateAccommodationAudioOption

오디오 옵션을 수정합니다.

#### GraphQL Signature

```graphql theme={null}
mutation UpdateAccommodationAudioOption($input: UpdateAudioOptionInput!) {
  updateAccommodationAudioOption(input: $input) {
    id
    key
    value
  }
}
```

***

### deleteAccommodationAudioOption

오디오 옵션을 삭제합니다.

#### GraphQL Signature

```graphql theme={null}
mutation DeleteAccommodationAudioOption($id: ID!) {
  deleteAccommodationAudioOption(id: $id)
}
```

***

## 유효성 검증

### validateAccommodationInfo

숙박시설 정보의 유효성을 검증합니다 (중복 확인 등).

#### GraphQL Signature

```graphql theme={null}
mutation ValidateAccommodationInfo($input: ValidateAccommodationInfoInput!) {
  validateAccommodationInfo(input: $input) {
    isValid
  }
}
```

#### 파라미터

<ParamField path="input.name" type="String!" required>
  검증할 숙박시설 이름
</ParamField>

#### 응답

<ResponseField name="isValid" type="Boolean!">
  유효성 검증 결과:

  * `true`: 사용 가능한 이름
  * `false`: 이미 존재하는 이름
</ResponseField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  mutation {
    validateAccommodationInfo(input: { name: "벤딧 호텔" }) {
      isValid
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "validateAccommodationInfo": {
        "isValid": false
      }
    }
  }
  ```
</CodeGroup>

***

## 라이선스 관리

### activateLicense

숙박시설의 제품 라이선스를 활성화합니다.

#### GraphQL Signature

```graphql theme={null}
mutation ActivateLicense($accommodationId: ID!, $productType: String!) {
  activateLicense(accommodationId: $accommodationId, productType: $productType)
}
```

#### 파라미터

<ParamField path="accommodationId" type="ID!" required>
  숙박시설 ID
</ParamField>

<ParamField path="productType" type="String!" required>
  제품 타입:

  * `VPMS`: 숙박 관리 시스템
</ParamField>

***

### inactivateLicense

숙박시설의 제품 라이선스를 비활성화합니다.

#### GraphQL Signature

```graphql theme={null}
mutation InactivateLicense($accommodationId: ID!, $productType: String!) {
  inactivateLicense(accommodationId: $accommodationId, productType: $productType)
}
```

***

## 시스템 제어

### sendCcuControlPacket

CCU(중앙 제어 장치)에 제어 패킷을 전송합니다.

#### GraphQL Signature

```graphql theme={null}
mutation SendCcuControlPacket($ccuId: ID!, $data: JSONObject!) {
  sendCcuControlPacket(ccuId: $ccuId, data: $data)
}
```

***

### sendKioskControlPacket

키오스크에 제어 패킷을 전송합니다.

#### GraphQL Signature

```graphql theme={null}
mutation SendKioskControlPacket($kioskId: ID!, $data: JSONObject!) {
  sendKioskControlPacket(kioskId: $kioskId, data: $data)
}
```

***

### checkAccommodationRoomDevicesIntegrity

숙박시설의 객실 장치 무결성을 검사합니다.

#### GraphQL Signature

```graphql theme={null}
mutation CheckAccommodationRoomDevicesIntegrity($accommodationId: ID!) {
  checkAccommodationRoomDevicesIntegrity(accommodationId: $accommodationId)
}
```

***

### checkAllAccommodationsRoomDevicesIntegrity

모든 활성화된 숙박시설의 객실 장치 무결성을 검사합니다.

#### GraphQL Signature

```graphql theme={null}
mutation CheckAllAccommodationsRoomDevicesIntegrity {
  checkAllAccommodationsRoomDevicesIntegrity
}
```

#### 권한 요구사항

<ParamField path="userType" type="SUPERADMIN" required>
  슈퍼 관리자 권한 필요
</ParamField>

***

## 에러 코드

<ResponseField name="DATA_NOT_FOUND_ON_ID">
  요청한 ID의 데이터를 찾을 수 없습니다.
</ResponseField>

<ResponseField name="DUPLICATED_DATA_FOUND">
  중복된 데이터가 존재합니다 (이름, 키오스크명 등).
</ResponseField>

<ResponseField name="REQUIRED_ACTIVATED_ACCOMMODATION">
  활성화된 숙박시설에서만 수행 가능한 작업입니다.
</ResponseField>

<ResponseField name="LAST_OWNER_CANNOT_BE_DELETED">
  마지막 소유자는 삭제할 수 없습니다.
</ResponseField>

<ResponseField name="INVALID_PARAMETER">
  잘못된 파라미터입니다.
</ResponseField>

<ResponseField name="EXTERNAL_API_ERROR">
  외부 API (Google Vision, AWS Rekognition) 호출 중 오류가 발생했습니다.
</ResponseField>

***

## 관련 API

* [객실 관리 API](/api-reference/core-svc/room) - 숙박시설의 객실 관리
* [예약 관리 API](/api-reference/core-svc/reservation) - 숙박시설의 예약 관리
* [사용자 관리 API](/api-reference/core-svc/user) - 숙박시설 사용자 권한 관리
* [마일리지 API](/api-reference/core-svc/mileage) - 숙박시설의 마일리지 설정
