돌아가기 오디오 어노테이터 스키마
## 오디오 어노테이터 전용 스키마

### 지원 도구(Tools)

| Tool Code        | 설명                          |
| ---------------- | ----------------------------- |
| `selection_tool` | 기본 선택 도구                |
| `segmentation`   | 오디오 구간(Region) 생성 도구 |

### 오디오 전용 메타데이터 (`extra`)

| 키         | 타입   | 설명                          |
| ---------- | ------ | ----------------------------- |
| duration   | number | 오디오 길이(초)               |
| sampleRate | number | 샘플레이트(Hz, 예: 44100)     |
| channels   | number | 채널 수(모노: 1, 스테레오: 2) |
| format     | string | 오디오 포맷(예: wav, mp3)     |

> 필요 시 프로젝트별 속성을 자유롭게 추가합니다.

### 어노테이션 객체 (`annotations`)

오디오 어노테이터에서 모든 어노테이션 객체는 공통 `AnnotationBase`를 상속합니다.

#### Annotation 필드 구조

| 필드             | 타입                     | 설명                  |
| ---------------- | ------------------------ | --------------------- |
| `id`             | `string`                 | 어노테이션 고유 ID    |
| `tool`           | `string`                 | 항상 `"segmentation"` |
| `isLocked`       | `boolean`                | 편집 잠금 여부        |
| `isVisible`      | `boolean`                | 화면 표시 여부        |
| `classification` | `Classification \| null` | 분류 정보             |

### annotationData 필드 구조 (도구별)

**segmentation:**

```json
{
  "id": "abc123",
  "section": {
    "start": 0.0,
    "end": 2.85
  }
}
```

#### segmentation 구조

| 필드            | 타입     | 설명               |
| --------------- | -------- | ------------------ |
| `id`            | `string` | 어노테이션 고유 ID |
| `section`       | `object` | 오디오 구간 정보   |
| `section.start` | `number` | 시작 시간(초 단위) |
| `section.end`   | `number` | 종료 시간(초 단위) |

### 샘플

```json
{
  "assignmentId": 7001,
  "extra": {
    "audio_1": {
      "duration": 45.5,
      "sampleRate": 44100,
      "channels": 2,
      "format": "wav"
    }
  },
  "annotations": {
    "audio_1": [
      {
        "id": "abc123",
        "tool": "segmentation",
        "isLocked": false,
        "isVisible": true,
        "classification": {
          "class": "speech",
          "gender": "F",
          "region": "서울",
          "quality": "5",
          "generation": "20대",
          "emotion": "neutral"
        }
      },
      {
        "id": "def456",
        "tool": "segmentation",
        "isLocked": false,
        "isVisible": true,
        "classification": {
          "class": "speech",
          "gender": "M",
          "region": "서울",
          "quality": "4",
          "generation": "30대",
          "emotion": "positive"
        }
      },
      {
        "id": "ghi789",
        "tool": "segmentation",
        "isLocked": false,
        "isVisible": true,
        "classification": {
          "class": "background_music"
        }
      }
    ]
  },
  "annotationsData": {
    "audio_1": [
      {
        "id": "abc123",
        "section": {
          "start": 0.0,
          "end": 2.85
        }
      },
      {
        "id": "def456",
        "section": {
          "start": 2.85,
          "end": 5.92
        }
      },
      {
        "id": "ghi789",
        "section": {
          "start": 12.0,
          "end": 18.5
        }
      }
    ]
  },
  "annotationGroups": {
    "audio_1": [
      {
        "id": "grp001",
        "tool": "annotationGroup",
        "isLocked": false,
        "annotationList": [
          { "children": [], "annotationId": "abc123" },
          { "children": [], "annotationId": "def456" }
        ],
        "classification": {
          "class": "dialogue",
          "scene": "outdoor"
        }
      }
    ]
  },
  "relations": {
    "audio_1": [
      {
        "id": "rel001",
        "tool": "relation",
        "isLocked": false,
        "isVisible": true,
        "annotationId": "abc123",
        "targetAnnotationId": "def456",
        "classification": {
          "class": "conversation"
        }
      }
    ]
  }
}
```