# 画面設計書 9-更新履歴ページ

## 概要

本ドキュメントは、OpenCodeウェブサイトの更新履歴ページの設計仕様を定義する。

### 本画面の処理概要

更新履歴ページは、OpenCodeの製品リリース履歴・更新情報を表示するページである。GitHubのリリース情報を取得し、各バージョンの変更内容（ハイライト、セクション別変更点）を時系列で表示する。

**業務上の目的・背景**：ユーザーが製品のアップデート内容を確認し、新機能や修正点を把握できるようにする。開発チームの透明性を示し、製品の継続的な改善をアピールする役割も担う。

**画面へのアクセス方法**：フッターの更新履歴リンク、またはURL `/changelog` に直接アクセス。

**主要な操作・処理内容**：
1. GitHubリリース情報の非同期取得
2. リリースバージョン一覧の表示
3. 各リリースのハイライト（動画/画像付き）表示
4. セクション別変更点のアコーディオン表示
5. コントリビューター（GitHub）へのリンク表示

**画面遷移**：
- 遷移元：フッター、各種リンク
- 遷移先：GitHubリリースページ（外部）、コントリビューターGitHubページ（外部）

**権限による表示制御**：特になし（公開ページ）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 56 | 国際化 | 主機能 | 多言語対応（i18n.t関数による翻訳） |

## 画面種別

公開ページ / 更新履歴

## URL/ルーティング

`/changelog` - 更新履歴ページ

## 入出力項目

| 項目名 | 入力/出力 | 型 | 必須 | 説明 |
|--------|----------|------|------|------|
| - | - | - | - | この画面では入力項目なし |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|------|------|
| ヘッダー | コンポーネント | サイトナビゲーション |
| ヒーローセクション | セクション | ページタイトル・サブタイトル |
| リリース一覧 | リスト | バージョン別リリース情報 |
| リリースバージョン | リンク | GitHubリリースへのリンク |
| リリース日 | 日付 | リリース公開日（ローカライズ済み） |
| ハイライトセクション | セクション | 主要な変更点（動画/画像付き） |
| セクション別変更点 | アコーディオン | 変更カテゴリ別の詳細リスト |
| コントリビューター名 | リンク | 変更を行ったGitHubユーザーへのリンク |
| フッター | コンポーネント | サイトフッター |
| 法的表示 | コンポーネント | 利用規約等へのリンク |

## イベント仕様

### 1-リリース情報取得

ページ読み込み時にGitHubからリリース情報を取得する処理。

処理フロー：
1. `createAsync(() => changelog())` でサーバーサイドクエリを実行
2. `loadChangelog()` でGitHub APIからリリース情報を取得
3. `parseMarkdown()` でリリース本文をパース
4. `parseHighlights()` でハイライト情報を抽出
5. 整形されたリリースデータを画面に表示

### 2-セクション展開/折りたたみ

ユーザーがセクション見出しをクリックした際の処理。

処理フロー：
1. `CollapsibleSection` コンポーネントのボタンがクリックされる
2. `setOpen(!open())` で開閉状態をトグル
3. `Show` コンポーネントで表示/非表示を切り替え

### 3-日付フォーマット

リリース日をユーザーのロケールに合わせて表示する処理。

処理フロー：
1. `formatDate(dateString, locale)` が呼び出される
2. `Date.toLocaleDateString()` でロケールに応じた日付文字列を生成
3. フォーマット: `year: "numeric", month: "short", day: "numeric"`

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | この画面ではデータベース更新は行わない |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| changelog.title | タイトル | ページタイトル | 常時 |
| changelog.meta.description | メタ | ページ説明 | 常時 |
| changelog.hero.title | 見出し | ヒーロータイトル | 常時 |
| changelog.hero.subtitle | 説明 | ヒーローサブタイトル | 常時 |
| changelog.empty | 情報 | リリース情報がない場合のメッセージ | リリース0件時 |
| changelog.viewJson | リンク | JSON形式で表示 | リリース0件時 |

## 例外処理

| 状況 | 処理内容 |
|------|---------|
| GitHub API取得失敗 | 空のリリース配列を返す（ok: false） |
| リリースが0件 | 代替メッセージとJSONリンクを表示 |
| JSONパース失敗 | 空のリリース配列を返す |

## 備考

- GitHub APIから最新20件のリリース情報を取得
- APIキャッシュ: Cloudflareエッジで5分間キャッシュ
- ハイライトは `<highlight>` タグで定義された特別な変更点
- セクションは `##` で始まるMarkdown見出しで分割
- コントリビューター名は `(@username)` 形式で抽出
- 「Thank you」で始まる行はスキップされる
- サーバーサイドでデータを取得（`"use server"` ディレクティブ）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

リリースデータの型定義とパース処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | changelog.ts | `packages/console/app/src/lib/changelog.ts` | ChangelogRelease型定義（27-34行目） |
| 1-2 | changelog.ts | `packages/console/app/src/lib/changelog.ts` | HighlightGroup型定義（22-25行目） |
| 1-3 | changelog.ts | `packages/console/app/src/lib/changelog.ts` | loadChangelog関数（41-72行目） |

**読解のコツ**: `ChangelogRelease` には `tag`, `date`, `highlights`, `sections` が含まれる。`HighlightGroup` は動画または画像付きの主要変更点。

#### Step 2: エントリーポイントを理解する

メインのChangelogコンポーネントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.tsx | `packages/console/app/src/routes/changelog/index.tsx` | Changelogコンポーネント（101-176行目） |

**主要処理フロー**:
1. **102-105行目**: useI18n, useLanguage, createAsyncの取得
2. **109-111行目**: メタ情報設定
3. **117-120行目**: ヒーローセクション
4. **122-167行目**: リリース一覧セクション
5. **129-166行目**: 各リリースのレンダリング

#### Step 3: サブコンポーネントを理解する

ヘルパーコンポーネントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.tsx | `packages/console/app/src/routes/changelog/index.tsx` | formatDate関数（14-21行目） |
| 3-2 | index.tsx | `packages/console/app/src/routes/changelog/index.tsx` | ReleaseItem コンポーネント（23-45行目） |
| 3-3 | index.tsx | `packages/console/app/src/routes/changelog/index.tsx` | HighlightSection コンポーネント（47-73行目） |
| 3-4 | index.tsx | `packages/console/app/src/routes/changelog/index.tsx` | CollapsibleSection コンポーネント（75-91行目） |

### プログラム呼び出し階層図

```
Changelog (index.tsx)
    │
    ├─ useI18n() ──────────────────> I18nContext
    │      └─ i18n.t() (翻訳)
    │
    ├─ useLanguage() ──────────────> LanguageContext
    │      ├─ language.route() (多言語ルート生成)
    │      └─ language.tag() (ロケールタグ取得)
    │
    ├─ createAsync(() => changelog()) ─> changelog.ts
    │      └─ loadChangelog()
    │             ├─ fetch() (GitHub API)
    │             ├─ parseMarkdown()
    │             │      └─ parseHighlights()
    │             └─ ChangelogRelease[]
    │
    ├─ formatDate() ──────────────> 日付フォーマット
    │      └─ Date.toLocaleDateString()
    │
    ├─ HighlightSection ──────────> ハイライト表示
    │      └─ video/img (メディア)
    │
    ├─ CollapsibleSection ────────> アコーディオン
    │      └─ createSignal(open)
    │
    ├─ ReleaseItem ───────────────> 変更項目
    │      └─ コントリビューターリンク
    │
    ├─ Header ────────────────────> header.tsx
    │
    ├─ Footer ────────────────────> footer.tsx
    │
    └─ Legal ─────────────────────> legal.tsx
```

### データフロー図

```
[入力]                      [処理]                          [出力]

GitHub API               loadChangelog()                 ChangelogRelease[]
(releases) ─────────────▶ parseMarkdown() ──────────────▶ 整形済みリリースデータ
                               │
                               └─ parseHighlights() ────▶ ハイライト抽出

リリース日               formatDate()                    ローカライズ日付
(ISO文字列) ────────────▶ toLocaleDateString() ──────────▶ 表示用日付文字列

アコーディオン           createSignal(open)              表示/非表示切り替え
(クリック) ─────────────▶ setOpen(!open()) ─────────────▶ CollapsibleSection
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.tsx | `packages/console/app/src/routes/changelog/index.tsx` | ソース | 更新履歴ページコンポーネント（177行） |
| index.css | `packages/console/app/src/routes/changelog/index.css` | スタイル | 更新履歴ページ専用スタイル |
| changelog.ts | `packages/console/app/src/lib/changelog.ts` | ソース | GitHub APIからのリリース情報取得・パース（147行） |
| header.tsx | `packages/console/app/src/component/header.tsx` | ソース | ヘッダーコンポーネント |
| footer.tsx | `packages/console/app/src/component/footer.tsx` | ソース | フッターコンポーネント |
| legal.tsx | `packages/console/app/src/component/legal.tsx` | ソース | 法的表示 |
| locale-links.tsx | `packages/console/app/src/component/locale-links.tsx` | ソース | 多言語リンク |
| i18n.tsx | `packages/console/app/src/context/i18n.tsx` | ソース | 国際化コンテキスト |
| language.tsx | `packages/console/app/src/context/language.tsx` | ソース | 言語コンテキスト |
