> ## 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.

# 채널 관리 (Channel)

> OTA 채널 및 예약 연동 관리 API

## 개요

Core 서비스의 채널 도메인은 숙박시설의 OTA(Online Travel Agency) 채널을 관리합니다. Booking.com, Expedia, Agoda 등 외부 예약 플랫폼과의 연동 정보를 설정하고 관리할 수 있습니다.

### 주요 기능

* **채널 등록**: 새로운 OTA 채널 연동 설정
* **채널 수정**: 기존 채널 정보 및 설정 업데이트
* **채널 조회**: 숙박시설의 채널 목록 및 상세 정보 확인
* **채널 삭제**: 사용하지 않는 채널 제거
* **채널 활성화 관리**: 채널별 활성화/비활성화 제어

## Queries

### getAccommodationChannelList

특정 숙박시설에 등록된 모든 채널 목록을 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetAccommodationChannelList($accommodationId: ID!) {
  getAccommodationChannelList(accommodationId: $accommodationId) {
    id
    accommodationId
    otaKey
    name
    shortName
    registeredName
    isDisabled
    createdAt
    updatedAt
  }
}
```

#### 파라미터

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

#### 응답 필드

<ResponseField name="id" type="ID!">
  채널 고유 식별자
</ResponseField>

<ResponseField name="accommodationId" type="ID!">
  숙박시설 ID
</ResponseField>

<ResponseField name="otaKey" type="String!">
  OTA 플랫폼 키:

  * `BOOKING_COM`: Booking.com
  * `EXPEDIA`: Expedia
  * `AGODA`: Agoda
  * `AIRBNB`: Airbnb
  * `DIRECT`: 직접 예약
  * 기타 OTA 플랫폼
</ResponseField>

<ResponseField name="name" type="String!">
  채널 표시 이름
</ResponseField>

<ResponseField name="shortName" type="String">
  채널 축약 이름
</ResponseField>

<ResponseField name="registeredName" type="String">
  OTA에 등록된 숙박시설 이름
</ResponseField>

<ResponseField name="isDisabled" type="Boolean!">
  채널 비활성화 여부

  * `true`: 비활성화 (예약 수신 중지)
  * `false`: 활성화 (예약 수신 가능)
</ResponseField>

<ResponseField name="createdAt" type="DateTime!">
  채널 등록일시
</ResponseField>

<ResponseField name="updatedAt" type="DateTime!">
  최종 수정일시
</ResponseField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  query {
    getAccommodationChannelList(
      accommodationId: "01HQKS9V8X2N3P4Q5R6S7T8U9V"
    ) {
      id
      otaKey
      name
      shortName
      isDisabled
      createdAt
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "getAccommodationChannelList": [
        {
          "id": "01HQKT1A2B3C4D5E6F7G8H9J0K",
          "otaKey": "BOOKING_COM",
          "name": "Booking.com",
          "shortName": "부킹",
          "isDisabled": false,
          "createdAt": "2024-01-15T10:30:00Z"
        },
        {
          "id": "01HQKT2B3C4D5E6F7G8H9J0K1L",
          "otaKey": "EXPEDIA",
          "name": "Expedia",
          "shortName": "익스피디아",
          "isDisabled": false,
          "createdAt": "2024-01-16T14:20:00Z"
        },
        {
          "id": "01HQKT3C4D5E6F7G8H9J0K1L2M",
          "otaKey": "DIRECT",
          "name": "직접 예약",
          "shortName": "직예약",
          "isDisabled": false,
          "createdAt": "2024-01-10T09:00:00Z"
        }
      ]
    }
  }
  ```
</CodeGroup>

#### 접근 권한

이 Query는 다음 권한을 가진 사용자만 호출할 수 있습니다:

* 해당 숙박시설 관리 권한이 있는 사용자
* 시스템 관리자 (ADMIN)

***

### getSingleChannel

특정 채널의 상세 정보를 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetSingleChannel($id: ID!) {
  getSingleChannel(id: $id) {
    id
    accommodationId
    otaKey
    name
    shortName
    registeredName
    isDisabled
    createdAt
    updatedAt
  }
}
```

#### 파라미터

<ParamField path="id" type="ID!" required>
  조회할 채널 ID
</ParamField>

#### 응답

`getAccommodationChannelList`와 동일한 채널 객체를 반환합니다.

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  query {
    getSingleChannel(id: "01HQKT1A2B3C4D5E6F7G8H9J0K") {
      id
      otaKey
      name
      shortName
      registeredName
      isDisabled
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "getSingleChannel": {
        "id": "01HQKT1A2B3C4D5E6F7G8H9J0K",
        "otaKey": "BOOKING_COM",
        "name": "Booking.com",
        "shortName": "부킹",
        "registeredName": "Grand Hotel Seoul",
        "isDisabled": false
      }
    }
  }
  ```
</CodeGroup>

#### 접근 권한

이 Query는 다음 권한을 가진 사용자만 호출할 수 있습니다:

* 해당 채널의 숙박시설 관리 권한이 있는 사용자
* 시스템 관리자 (ADMIN)

#### 에러 처리

<ResponseField name="DATA_NOT_FOUND_ON_ID">
  존재하지 않는 채널 ID로 조회 시 반환됩니다.
</ResponseField>

***

## Mutations

### addChannel

새로운 OTA 채널을 숙박시설에 추가합니다.

#### GraphQL Signature

```graphql theme={null}
mutation AddChannel($input: AddChannelInput!) {
  addChannel(input: $input) {
    id
    accommodationId
    otaKey
    name
    shortName
    registeredName
    isDisabled
    createdAt
  }
}
```

#### 파라미터

<ParamField path="input" type="AddChannelInput!" required>
  채널 추가 정보:

  * `accommodationId`: 숙박시설 ID (필수)
  * `otaKey`: OTA 플랫폼 키 (필수)
  * `name`: 채널 이름 (필수)
  * `shortName`: 축약 이름
  * `registeredName`: OTA 등록 이름
  * `isDisabled`: 비활성화 여부 (기본값: false)
</ParamField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  mutation {
    addChannel(input: {
      accommodationId: "01HQKS9V8X2N3P4Q5R6S7T8U9V"
      otaKey: "AGODA"
      name: "Agoda"
      shortName: "아고다"
      registeredName: "Seoul Grand Hotel"
      isDisabled: false
    }) {
      id
      otaKey
      name
      isDisabled
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "addChannel": {
        "id": "01HQKT4D5E6F7G8H9J0K1L2M3N",
        "otaKey": "AGODA",
        "name": "Agoda",
        "isDisabled": false
      }
    }
  }
  ```
</CodeGroup>

#### 접근 권한

이 Mutation은 다음 권한을 가진 사용자만 호출할 수 있습니다:

* 해당 숙박시설 관리 권한이 있는 사용자
* 시스템 관리자 (ADMIN)

***

### modifyChannel

기존 채널의 정보를 수정합니다.

#### GraphQL Signature

```graphql theme={null}
mutation ModifyChannel($input: ModifyChannelInput!) {
  modifyChannel(input: $input) {
    id
    otaKey
    name
    shortName
    registeredName
    isDisabled
    updatedAt
  }
}
```

#### 파라미터

<ParamField path="input" type="ModifyChannelInput!" required>
  수정할 채널 정보:

  * `id`: 채널 ID (필수)
  * `otaKey`: OTA 플랫폼 키
  * `name`: 채널 이름
  * `shortName`: 축약 이름
  * `registeredName`: OTA 등록 이름
  * `isDisabled`: 비활성화 여부

  수정하지 않을 필드는 제외 가능 (선택적 업데이트)
</ParamField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  mutation {
    modifyChannel(input: {
      id: "01HQKT1A2B3C4D5E6F7G8H9J0K"
      name: "Booking.com - Premium"
      shortName: "부킹프리미엄"
      isDisabled: false
    }) {
      id
      name
      shortName
      isDisabled
      updatedAt
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "modifyChannel": {
        "id": "01HQKT1A2B3C4D5E6F7G8H9J0K",
        "name": "Booking.com - Premium",
        "shortName": "부킹프리미엄",
        "isDisabled": false,
        "updatedAt": "2024-01-20T15:45:00Z"
      }
    }
  }
  ```
</CodeGroup>

#### 접근 권한

이 Mutation은 다음 권한을 가진 사용자만 호출할 수 있습니다:

* 해당 채널의 숙박시설 관리 권한이 있는 사용자
* 시스템 관리자 (ADMIN)

#### 에러 처리

<ResponseField name="DATA_NOT_FOUND_ON_ID">
  존재하지 않는 채널 ID로 수정 시 반환됩니다.
</ResponseField>

***

### deleteChannel

채널을 삭제합니다.

#### GraphQL Signature

```graphql theme={null}
mutation DeleteChannel($id: ID!) {
  deleteChannel(id: $id)
}
```

#### 파라미터

<ParamField path="id" type="ID!" required>
  삭제할 채널 ID
</ParamField>

#### 응답

<ResponseField name="success" type="Boolean!">
  삭제 성공 여부 (항상 true)
</ResponseField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  mutation {
    deleteChannel(id: "01HQKT1A2B3C4D5E6F7G8H9J0K")
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "deleteChannel": true
    }
  }
  ```
</CodeGroup>

#### 접근 권한

이 Mutation은 다음 권한을 가진 사용자만 호출할 수 있습니다:

* 해당 채널의 숙박시설 관리 권한이 있는 사용자
* 시스템 관리자 (ADMIN)

#### 에러 처리

<ResponseField name="DATA_NOT_FOUND_ON_ID">
  존재하지 않는 채널 ID로 삭제 시 반환됩니다.
</ResponseField>

<Warning>
  채널을 삭제하면 해당 채널과 연결된 예약 데이터는 유지되지만,
  새로운 예약을 해당 채널로 받을 수 없습니다.
  일시적으로 중단하려면 `isDisabled`를 `true`로 설정하는 것을 권장합니다.
</Warning>

***

## OTA Key 목록

채널 등록 시 사용 가능한 주요 OTA 플랫폼 키:

| OTA Key       | 플랫폼 이름         | 설명            |
| ------------- | -------------- | ------------- |
| `BOOKING_COM` | Booking.com    | 부킹닷컴          |
| `EXPEDIA`     | Expedia        | 익스피디아         |
| `AGODA`       | Agoda          | 아고다           |
| `AIRBNB`      | Airbnb         | 에어비앤비         |
| `HOTELS_COM`  | Hotels.com     | 호텔스닷컴         |
| `TRIP_COM`    | Trip.com       | 트립닷컴          |
| `DIRECT`      | Direct Booking | 직접 예약         |
| `YANOLJA`     | 여기어때           | 여기어때          |
| `GOODCHOICE`  | 여기어때           | 여기어때 (구 굿초이스) |
| `INTERPARK`   | 인터파크           | 인터파크 투어       |

<Note>
  새로운 OTA 플랫폼을 추가해야 하는 경우, 시스템 관리자에게 문의하여
  `otaKey` 값을 등록 후 사용할 수 있습니다.
</Note>

## 채널 활성화 관리

채널의 `isDisabled` 필드를 사용하여 예약 수신을 제어할 수 있습니다:

### 채널 비활성화

```graphql theme={null}
mutation {
  modifyChannel(input: {
    id: "01HQKT1A2B3C4D5E6F7G8H9J0K"
    isDisabled: true
  }) {
    id
    isDisabled
  }
}
```

채널을 비활성화하면:

* 해당 채널로부터 새로운 예약 수신 중지
* 기존 예약은 유지되며 정상 처리
* 필요 시 언제든 재활성화 가능

### 채널 활성화

```graphql theme={null}
mutation {
  modifyChannel(input: {
    id: "01HQKT1A2B3C4D5E6F7G8H9J0K"
    isDisabled: false
  }) {
    id
    isDisabled
  }
}
```

## 사용 흐름

### 1. 새로운 OTA 채널 등록

```graphql theme={null}
mutation {
  addChannel(input: {
    accommodationId: "01HQKS9V8X2N3P4Q5R6S7T8U9V"
    otaKey: "BOOKING_COM"
    name: "Booking.com"
    shortName: "부킹"
    registeredName: "Grand Hotel Seoul"
  }) {
    id
    otaKey
  }
}
```

### 2. 채널 목록 조회

```graphql theme={null}
query {
  getAccommodationChannelList(
    accommodationId: "01HQKS9V8X2N3P4Q5R6S7T8U9V"
  ) {
    id
    otaKey
    name
    isDisabled
  }
}
```

### 3. 채널 정보 수정

```graphql theme={null}
mutation {
  modifyChannel(input: {
    id: "01HQKT1A2B3C4D5E6F7G8H9J0K"
    shortName: "부킹프리미엄"
    isDisabled: false
  }) {
    id
    shortName
    isDisabled
  }
}
```

### 4. 필요시 채널 삭제

```graphql theme={null}
mutation {
  deleteChannel(id: "01HQKT1A2B3C4D5E6F7G8H9J0K")
}
```

## 관련 API

* [예약 API](/api-reference/core-svc/reservation) - 채널별 예약 데이터 관리
* [프로필 API](/api-reference/core-svc/profile) - 채널별 고객 프로필 관리
* [인증 API](/api-reference/core-svc/auth) - API 접근 인증
