---
title: "トラックリスト データ設計書"
---

最終更新: 2026-05-28

## 1. 概要

`releases.json` にアルバム収録曲・シングルカップリングのトラックリストを追加するためのデータ設計。
プレイリスト機能（#336）において楽曲とリリースを紐付ける `trackId` の参照先を確立することが本設計の主目的である。

---

## 2. 背景・目的

現行の `releases.json` はリリースのメタ情報（タイトル・日付・フォーマット）のみを保持しており、収録曲情報がない。

| 目的 | 詳細 |
| --- | --- |
| プレイリスト楽曲の参照先確立 | `PlaylistEntry.trackId` が指す `Track` エンティティを定義する |
| リリース詳細画面の収録曲表示 | トラック番号・曲名・ディスク番号を画面に表示できるようにする |
| MusicBrainz API との整合 | 取得可能なフィールドを洗い出し、スキーマに反映する |

---

## 3. MusicBrainz API フィールドマッピング

取得エンドポイント: `https://musicbrainz.org/ws/2/release/{mbid}?inc=recordings&fmt=json`

### レスポンス構造（関連部分）

```json
{
  "media": [
    {
      "position": 1,
      "format": "CD",
      "tracks": [
        {
          "id": "...",
          "number": "1",
          "title": "愛の種",
          "length": 214000,
          "recording": {
            "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          }
        }
      ]
    }
  ]
}
```

### フィールド対応表

| MusicBrainz フィールド | 本設計フィールド | 説明 |
| --- | --- | --- |
| `media[].tracks[].recording.id` | `Track.id` | MusicBrainz recording UUID（楽曲の安定識別子） |
| `media[].tracks[].id` | `Track.mbTrackId` | MusicBrainz track UUID（リリース上の出現位置） |
| `media[].tracks[].number` | `Track.trackNumber` | ディスク内でのトラック番号（数値化） |
| `media[].position` | `Track.discNumber` | ディスク番号（1始まり） |
| `media[].tracks[].title` | `Track.title` | 収録曲タイトル |
| `media[].tracks[].length` | `Track.length` | 曲の長さ（ミリ秒） |

> **`Track.id` に recording UUID を採用する理由**
> 同一楽曲がシングルとアルバムに重複収録される場合、track UUID はリリースごとに異なるが recording UUID は同一となる。`PlaylistEntry.trackId` からの参照は recording UUID の方が安定しており、クロスリリース参照（「このシングル曲はどのアルバムにも収録されている」等）が可能になる。

---

## 4. 型定義

### `Track` インターフェース（新規追加）

```typescript
export interface Track {
  /** MusicBrainz recording UUID（楽曲の安定識別子・PlaylistEntry.trackId の参照先） */
  id: string;
  /** MusicBrainz track UUID（このリリース上の出現位置の識別子）。手動登録リリースでは省略可 */
  mbTrackId?: string;
  /** ディスク内でのトラック番号（1始まり） */
  trackNumber: number;
  /** ディスク番号（1始まり。シングル等の1枚組は省略可） */
  discNumber?: number;
  /** 収録曲タイトル */
  title: string;
  /** 曲の長さ（ミリ秒。MusicBrainz に未登録の場合は省略可） */
  length?: number;
  /** 外部リンク（YouTube MV・YouTube Music・YouTube Shorts 等）。sync-discography により自動付与。未取得時は省略 */
  links?: ExternalLink[];
  /** MusicBrainz artist-credit から取得したアーティスト名。sync-discography で自動設定 */
  artist?: string;
  /** アーティストがユニットの場合のユニット ID（units.json の id と一致）。sync-discography で自動設定 */
  unitId?: string;
  /** MusicBrainz artist MBID（artist-credit から取得）。sync-discography で自動設定 */
  artistMbid?: string;
}
```

### `ExternalLink` 型（`Track.links` の要素）

`ExternalLink` は `{ type: ExternalLinkType; url: string }` の形式で定義される（`types/external-link.ts`）。

| `ExternalLinkType` 値 | 説明 | 付与元 |
| --- | --- | --- |
| `youtube` | YouTube MV（曲詳細でインライン iframe 表示） | `syncTrackLinks` |
| `youtube-music` | YouTube Music（曲詳細の外部リンクセクションにボタン表示） | `syncTrackLinks` |
| `youtube-short` | YouTube Shorts（シングル曲のみ・Instrumental 除外・最大10件・曲詳細でインライン iframe 表示）（#774, #828） | `syncTrackShortLinks` |
| `spotify` | Spotify | 手動登録 |
| `apple-music` | Apple Music | 手動登録 |
| `line-music` | LINE MUSIC | 手動登録 |
| `recochoku` | レコチョク | 手動登録 |
| `mora` | mora | 手動登録 |
| `genius` | Genius（歌詞リンクセクション専用。曲詳細で「Genius で歌詞を見る」リンクとして表示） | `syncGeniusLinks` |
| `other` | その他外部リンク | 手動登録 |

### `Release` インターフェース（`tracks` フィールド追加）

```typescript
export interface Release {
  id: string;
  title: string;
  releaseDate: string;
  format: ReleaseFormat;
  source: string;
  sourceUrl: string;
  /** トラックリスト（sync-discography による取得後に付与。未取得時は省略） */
  tracks?: Track[];
}
```

> `tracks` を省略可（`optional`）にすることで、既存データへの後方互換を維持する。

---

## 5. ER 図

→ [docs/design/er-diagram.mdx](/design/common/er-diagram) を参照すること。

本設計で追加される `Track` エンティティの位置づけは ER 図の「v0.5.0 完成時点」セクションに記載。
`Playlist` / `PlaylistEntry` との関係は「v0.6.0 完成時点・全体」セクションに記載。

---

## 6. `releases.json` スキーマ変更

### 変更前

```json
{
  "releases": [
    {
      "id": "...",
      "title": "LOVEマシーン",
      "releaseDate": "1999-09-09",
      "format": "single",
      "source": "musicbrainz",
      "sourceUrl": "https://musicbrainz.org/release/..."
    }
  ]
}
```

### 変更後（`tracks` フィールド追加例）

```json
{
  "releases": [
    {
      "id": "fcd58b7d-77c0-37db-9334-5f50d92b09f1",
      "title": "LOVEマシーン",
      "releaseDate": "1999-09-09",
      "format": "single",
      "source": "musicbrainz",
      "sourceUrl": "https://musicbrainz.org/release/fcd58b7d-77c0-37db-9334-5f50d92b09f1",
      "tracks": [
        {
          "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
          "mbTrackId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
          "trackNumber": 1,
          "title": "LOVEマシーン",
          "length": 273000
        },
        {
          "id": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
          "mbTrackId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
          "trackNumber": 2,
          "title": "ザ☆ピ〜ス！",
          "length": 262000
        }
      ]
    }
  ]
}
```

---

## 7. `PlaylistEntry` への影響

`playlists.json` の各エントリには既に `releaseId`（任意）が存在する。
`tracks` の追加後、`trackId` を追加して楽曲を一意に特定できるようにする。

```json
{
  "memberId": "makino-maria",
  "releaseId": "fcd58b7d-77c0-37db-9334-5f50d92b09f1",
  "trackId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "songTitle": "LOVEマシーン",
  "links": []
}
```

| フィールド | 必須 | 説明 |
| --- | --- | --- |
| `memberId` | 必須 | 選曲したメンバーの ID |
| `releaseId` | 任意 | リリースが特定できる場合に付与 |
| `trackId` | 任意 | `Track.id`（recording UUID）。収録曲が特定できる場合に付与 |
| `songTitle` | 必須 | 表示用の楽曲タイトル（`trackId` が未設定でも表示に使用） |
| `links` | 必須 | 外部リンク（YouTube 等） |

> `trackId` を任意とする理由: `tracks` データが未取得のリリースや、プレイリスト上の楽曲が特定リリースに紐付かないケース（ライブ音源等）に対応するため。

---

## 8. マルチディスク対応方針

アルバム等の複数ディスク構成（CD1・CD2）は `discNumber` フィールドで区別する。

- `discNumber` は省略可。省略時は `1` とみなす
- `trackNumber` はディスク内での連番（1始まり）
- ソート順: `discNumber ASC, trackNumber ASC`

---

## 9. 既存データへの影響

| 対象 | 変更内容 | 後方互換 |
| --- | --- | --- |
| `types/release.ts` | `tracks?: Track[]` フィールド追加 | ○ optional のため既存データは変更不要 |
| `releases.json` | `tracks` フィールドは `sync-discography` 実行後に付与 | ○ |
| `types/playlist.ts`（実装済み） | `trackId?: string` フィールド追加 | ○ |
| `scripts/sync-discography.ts` | MusicBrainz recording API を呼び出してトラックリストを取得・保存 | - |

---

## 10. バージョン位置づけ

| バージョン | 機能 | 対応 Issue |
| --- | --- | --- |
| **v0.5.0** | トラックリスト管理機能（リリース収録曲） | #341（#338・#339・#340・#344） |
| **v0.6.0** | プレイリスト管理機能 | #336（#328〜#335） |

> v0.5.0 の完成をもってプレイリスト機能（v0.6.0）の前提基盤が整う。

---

## 11. 後続 Issue との関係

| Issue | 依存内容 |
| --- | --- |
| #339 `Release` 型定義への `tracks` フィールド追加 | 本設計書の型定義に基づいて実装 |
| #347 `Release.youtubeUrl` および `ExternalLink` 共通型の追加 | 本設計書の `Release` 拡張方針に基づいて実装（※ `youtubeUrl` はその後廃止され `ExternalLink[]` ベースに移行済） |
| #340 `sync-discography` でのトラックリスト同期 | MusicBrainz フィールドマッピング（§3）に基づいて実装 |
| #350 `sync-discography` への YouTube MV URL 自動取得追加 | `Release.youtubeUrl` フィールド（#347）に基づいて実装（現実装では `Release.links` を使用） |
| #344 リリース詳細画面の画面設計書の改訂 | 本設計のトラックリスト表示要件・YouTube MV リンク仕様を反映 |
| #348 リリース詳細画面への YouTube MV リンク追加 | #347・#344 完了後に実装 |
| #330 プレイリスト機能 型定義・基盤データファイルの追加 | `PlaylistEntry.trackId` の型定義（§7）に基づいて実装 |

---

## 改訂履歴

| 版 | 更新日 | 変更内容 |
| --- | --- | --- |
| 1.7 | 2026-05-28 | `Track` インターフェースから `shortsRefetchRequested` フィールドを削除（Neon スキーマ削除 #950） |
| 1.6 | 2026-05-10 | `Track` インターフェースに `artist`・`unitId`・`artistMbid` フィールドを追記（Neon スキーマ追加 #853 に合わせてドキュメントを実態と一致させる） |
| 1.5 | 2026-05-06 | `youtube-short` 取得上限を 3 → 10 件に拡大し Instrumental を除外対象に追加（#828）。`syncTrackShortLinks` に `shortsRefetchRequested` フラグ駆動の再取得ロジックを追加（#823） |
| 1.4 | 2026-05-06 | `Track` インターフェースに `shortsRefetchRequested` フラグを追加（#824） |
| 1.3 | 2026-05-06 | `ExternalLinkType` に `youtube-short` を追加し、付与元ごとの一覧表を §4 に整備（#774） |
| 1.2 | 2026-03-19 | `PlaylistEntry.trackId` 仕様を §7 に追加（PR #353 レビュー指摘） |
| 1.1 | 2026-03-19 | `ExternalLink` 型を使った `Track.links` 設計を §4 に追加（#362・#363） |
| 1.0 | 2026-03-03 | 初版作成（#338） |
