# 画面設計書 23-シェア詳細

## 概要

本ドキュメントは、OpenCodeエンタープライズアプリケーション（enterprise）におけるシェア詳細画面の設計を定義する。共有されたAIセッションの詳細を表示する画面であり、メッセージタイムライン、コード差分レビュー、メタデータ表示などの機能を提供する。

### 本画面の処理概要

この画面は、共有されたセッションの詳細を外部ユーザーが閲覧できる画面である。セッション内のメッセージ履歴、ファイル変更差分、使用されたモデル情報などを表示する。

**業務上の目的・背景**：エンタープライズ環境において、AIとの対話セッションを社内外のステークホルダーと共有することは、ナレッジ共有、コードレビュー、意思決定の透明性確保などに重要である。本画面により、共有リンクを受け取った者がセッションの全内容を確認できる。

**画面へのアクセス方法**：`/share/{shareID}`形式のURLに直接アクセス。shareIDは8文字の一意識別子で、セッション共有時に生成される。

**主要な操作・処理内容**：
1. 共有データの取得（サーバーサイドクエリ）
2. セッション情報の表示（タイトル、バージョン、日時）
3. メッセージタイムラインの表示（ユーザー・アシスタントメッセージ）
4. ファイル変更差分のレビュー表示（unified/split view）
5. モデル情報・プロバイダー情報の表示
6. メッセージ間ナビゲーション
7. OGP画像の動的生成（ソーシャルシェア用）

**画面遷移**：
- この画面から遷移可能：OpenCodeホームページ（ロゴクリック）、GitHub（外部リンク）、Discord（外部リンク）
- この画面に遷移してくる：共有リンク経由の直接アクセス

**権限による表示制御**：なし。共有IDを知っている誰でもアクセス可能。ただし、共有が無効化されている場合は404ページを表示。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | セッション共有 | 主機能 | 共有されたセッションの詳細表示 |

## 画面種別

詳細表示

## URL/ルーティング

- パス: `/share/[shareID]`
- ファイル: `packages/enterprise/src/routes/share/[shareID].tsx`
- パラメータ: `shareID` - 共有識別子（8文字）

## 入出力項目

### 入力項目（URLパラメータ）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| shareID | string | はい | 共有識別子（セッションID末尾8文字） |

### サーバーサイド取得データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| sessionID | string | 元のセッションID |
| shareID | string | 共有ID |
| session | Session[] | セッション情報配列 |
| session_diff | FileDiff[] | ファイル差分データ |
| session_diff_preload | PreloadMultiFileDiffResult[] | プリロード済み差分（unified） |
| session_diff_preload_split | PreloadMultiFileDiffResult[] | プリロード済み差分（split） |
| session_status | SessionStatus | セッションステータス |
| message | Message[] | メッセージ配列（セッションIDでグループ化） |
| part | Part[] | メッセージパーツ（messageIDでグループ化） |
| model | Model[] | 使用モデル情報 |

## 表示項目

| セクション | 項目名 | 表示内容 | 説明 |
|-----------|--------|----------|------|
| ヘッダー | ロゴ | OpenCodeマーク | クリックでホームページへ |
| ヘッダー | GitHubリンク | GitHubアイコン | 外部リンク |
| ヘッダー | Discordリンク | Discordアイコン | 外部リンク |
| タイトル | バージョンバッジ | "v{version}" | セッション作成時のバージョン |
| タイトル | プロバイダーアイコン | プロバイダーロゴ | Anthropic, OpenAI等 |
| タイトル | モデル名 | モデル表示名 | "Claude 3.5 Sonnet"等 |
| タイトル | 日時 | 作成日時 | "dd MMM yyyy, HH:mm"形式 |
| タイトル | セッションタイトル | タイトル文字列 | AIが生成したセッションタイトル |
| メインコンテンツ | メッセージナビ | メッセージ切替UI | 複数メッセージ時のみ表示 |
| メインコンテンツ | SessionTurn | メッセージ表示 | ユーザー・アシスタントメッセージ |
| サイドパネル | SessionReview | 差分表示 | ファイル変更のdiff表示 |
| フッター | ロゴ | OpenCodeロゴ | 透過表示 |

## イベント仕様

### 1-ロゴクリック

OpenCodeホームページ（`https://opencode.ai`）へ遷移。

### 2-GitHubアイコンクリック

GitHubリポジトリ（`https://github.com/anomalyco/opencode`）を新しいタブで開く。

### 3-Discordアイコンクリック

Discordサーバー（`https://opencode.ai/discord`）を新しいタブで開く。

### 4-メッセージ選択

MessageNavコンポーネントでメッセージを選択すると、該当メッセージの詳細表示に切り替え。activeMessageステートが更新される。

### 5-タブ切替（モバイル）

モバイル表示時、「Session」と「Files Changed」タブを切り替えて表示内容を変更。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ読み込み | share | SELECT | 共有情報の取得 |
| ページ読み込み | share_compaction | SELECT | コンパクション済みデータ取得 |
| ページ読み込み | share_event | SELECT | イベントデータ取得 |

### テーブル別更新項目詳細

#### share（読み取り専用）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id | shareIDで検索 | 共有IDによる取得 |
| SELECT | sessionID | - | 元セッションID |
| SELECT | secret | - | 認証用シークレット |

## メッセージ仕様

| メッセージ種別 | 表示条件 | メッセージ内容 |
|---------------|----------|---------------|
| エラー | セッションデータ取得失敗 | "Unable to render this share." |
| エラー | shareIDが存在しない | 404ページを表示 |
| 情報 | 正常表示 | セッションタイトル |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|-----|----------|---------|
| SessionDataMissingError | shareIDが無効、またはセッションが見つからない | 404ページ（NotFound）を表示 |
| その他のエラー | 予期しないエラー | エラー詳細とスタックトレースを表示 |

## 備考

- SSR（サーバーサイドレンダリング）とクライアントサイドハイドレーションのハイブリッド構成
- 差分表示コンポーネントはクライアントサイドで遅延読み込み（clientOnly）
- OGP画像はsocial-cards.sst.devで動的生成
- robots metaタグで検索エンジンのインデックスを防止（noindex, nofollow）
- レスポンシブ対応：md以上で2カラム、それ以下でタブ切替UI

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | share.ts | `packages/enterprise/src/core/share.ts` | Share.Info, Share.Dataの型定義 |
| 1-2 | @opencode-ai/sdk/v2 | 外部パッケージ | Session, Message, Part, FileDiff等の型 |

**読解のコツ**: zodスキーマによる型定義パターンを理解する。`z.infer<typeof Schema>`で型を導出。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | [shareID].tsx | `packages/enterprise/src/routes/share/[shareID].tsx` | ページコンポーネント全体構造 |

**主要処理フロー**:
1. **49-147行目**: `getData`クエリ関数 - サーバーサイドでのデータ取得とプリロード
2. **149-157行目**: `useParams`でshareID取得、`createAsync`で非同期データ取得
3. **163-472行目**: エラーバウンダリとメインUI構造
4. **184-187行目**: セッション情報の取得とマッチング
5. **225-312行目**: タイトルセクションのレンダリング

#### Step 3: データ取得ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | share.ts | `packages/enterprise/src/core/share.ts` | Share.get(), Share.data()の実装 |

**主要処理フロー**:
- **54-56行目**: `get()` - shareIDによるシェア情報取得
- **87-131行目**: `data()` - コンパクション処理を含むデータ取得

#### Step 4: UIコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SessionTurn | `@opencode-ai/ui/session-turn` | メッセージターンの表示 |
| 4-2 | SessionReview | `@opencode-ai/ui/session-review` | 差分レビュー表示 |
| 4-3 | MessageNav | `@opencode-ai/ui/message-nav` | メッセージナビゲーション |

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

```
[shareID].tsx (Share Detail Page)
    │
    ├─ getData() [Server Side]
    │      │
    │      ├─ Share.get(shareID)
    │      │      └─ Storage.read()
    │      │
    │      └─ Share.data(shareID)
    │             ├─ Storage.read() - compaction
    │             ├─ Storage.list() - events
    │             └─ preloadMultiFileDiff() - diff preload
    │
    ├─ useParams() - shareID取得
    │
    ├─ createAsync() - 非同期データバインディング
    │
    └─ UI Components
           ├─ ErrorBoundary
           │      └─ NotFound (404)
           │
           ├─ ClientOnlyWorkerPoolProvider
           │
           ├─ DiffComponentProvider
           │
           ├─ CodeComponentProvider
           │
           ├─ DataProvider
           │
           ├─ Header
           │      ├─ Mark (Logo)
           │      └─ IconButton (GitHub, Discord)
           │
           ├─ Title Section
           │      ├─ Version Badge
           │      ├─ ProviderIcon
           │      └─ DateTime
           │
           ├─ MessageNav (conditional)
           │
           ├─ SessionTurn (For each message)
           │
           ├─ SessionReview (diff view)
           │      ├─ Unified view
           │      └─ Split view
           │
           └─ Tabs (mobile)
                  ├─ Session tab
                  └─ Review tab
```

### データフロー図

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

URL: /share/{shareID}
         │
         ▼
    useParams() ──────▶ shareID抽出
         │
         ▼
    getData() [SSR] ───▶ Share.get() ──▶ 共有情報取得
         │                    │
         │                    ▼
         │              Share.data() ──▶ セッションデータ取得
         │                    │
         │                    ├──▶ session
         │                    ├──▶ messages
         │                    ├──▶ parts
         │                    ├──▶ diffs (preloaded)
         │                    └──▶ models
         │
         ▼
    createAsync() ─────▶ リアクティブデータ
         │
         ▼
    UI Rendering
         │
         ├──▶ タイトル・メタ情報 ──▶ 画面上部表示
         │
         ├──▶ メッセージ一覧 ──────▶ SessionTurn表示
         │
         └──▶ 差分データ ─────────▶ SessionReview表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| [shareID].tsx | `packages/enterprise/src/routes/share/[shareID].tsx` | ソース | シェア詳細ページコンポーネント |
| share.tsx | `packages/enterprise/src/routes/share.tsx` | ソース | 親レイアウトコンポーネント |
| share.ts | `packages/enterprise/src/core/share.ts` | ソース | シェアデータ管理ロジック |
| storage.ts | `packages/enterprise/src/core/storage.ts` | ソース | ストレージアクセス層 |
| [...404].tsx | `packages/enterprise/src/routes/[...404].tsx` | ソース | 404ページ（エラー時表示） |
| session-turn | `@opencode-ai/ui/session-turn` | 外部 | メッセージターンコンポーネント |
| session-review | `@opencode-ai/ui/session-review` | 外部 | 差分レビューコンポーネント |
| message-nav | `@opencode-ai/ui/message-nav` | 外部 | メッセージナビゲーション |
| tabs | `@opencode-ai/ui/tabs` | 外部 | タブコンポーネント |
| diff-ssr | `@opencode-ai/ui/diff-ssr` | 外部 | SSR用差分コンポーネント |
