# 機能設計書 49-ClojureDocs統合

## 概要

本ドキュメントは、clojure-lspの「ClojureDocs統合」機能の設計を詳細に記載する。この機能は、clojure.coreシンボルに対してClojureDocsの情報（例文、see-also、ノート）を表示するホバー拡張機能である。

### 本機能の処理概要

**業務上の目的・背景**：ClojureDocsはClojureコミュニティによって維持される実例豊富なドキュメントサイトである。公式ドキュメント以上に実践的な使用例やコミュニティの知見が蓄積されている。この統合により、エディタを離れることなくClojureDocsの豊富な情報にアクセスできる。

**機能の利用シーン**：clojure.coreやcljs.coreのシンボル（map, reduce, filter等）にマウスをホバーした際に、標準ドキュメントに加えてClojureDocsの例文やsee-also情報が表示される。

**主要な処理内容**：
1. LSPサーバー起動時にClojureDocsデータをダウンロード・キャッシュ
2. ホバー時に対象シンボルのClojureDocs情報を検索
3. 例文、see-also、ノートを整形して表示

**関連システム・外部連携**：ClojureDocs EDNエクスポートファイル（GitHub）。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | エディタ | 主画面 | ホバー時のポップアップ表示 |

## 機能種別

情報表示 / 外部データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sym-name | String | Yes | シンボル名 | 非空文字列 |
| sym-ns | String | Yes | 名前空間 | clojure.*/cljs.* |

### 入力データソース

- ClojureDocs EDNエクスポートファイル（https://github.com/clojure-emacs/clojuredocs-export-edn）
- ローカルキャッシュ（:clojuredocs :cache）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| doc | String | ドキュメント文字列 |
| examples | Array[String] | 使用例の配列 |
| see-alsos | Array[Symbol] | 関連シンボルの配列 |
| notes | Array[String] | コミュニティノートの配列 |

### 出力先

- ホバーコンテンツの一部として表示

## 処理フロー

### 処理シーケンス

```
1. 設定確認
   └─ :hover :clojuredocs が true（デフォルト）か確認
2. キャッシュ確認
   └─ キャッシュ存在チェック
   └─ なければバックグラウンドで取得開始
3. シンボル検索
   └─ キーワード形式（:namespace/name）で検索
4. 結果整形
   └─ examples, see-alsos, notes を取得
```

### フローチャート

```mermaid
flowchart TD
    A[シンボル検索要求] --> B{ClojureDocs有効?}
    B -->|いいえ| Z[nil返却]
    B -->|はい| C{キャッシュ存在?}
    C -->|いいえ| D[バックグラウンド取得開始]
    D --> Z
    C -->|はい| E[キーワード検索]
    E --> F{ヒット?}
    F -->|いいえ| Z
    F -->|はい| G[データ返却]
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 設定有効確認 | :hover :clojuredocs がtrue（デフォルト）の場合のみ有効 | 常時 |
| BR-02 | 名前空間必須 | シンボルに名前空間がない場合は検索しない | 常時 |
| BR-03 | バックグラウンド更新 | キャッシュがない場合は非同期で取得 | 初回アクセス時 |
| BR-04 | 排他制御 | 更新中は再度の更新要求をスキップ | 更新時 |

### 計算ロジック

検索キー生成：
```clojure
(defn find-docs-for [sym-name sym-ns db*]
  (when sym-ns
    (let [full-keyword (keyword (str sym-ns) (str sym-name))]
      (get cache full-keyword))))
```

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| キャッシュ更新 | :clojuredocs :cache | UPDATE | EDNデータを格納 |
| キャッシュ参照 | :clojuredocs :cache | SELECT | シンボル情報を取得 |

### テーブル別操作詳細

#### :clojuredocs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | :cache | EDNファイル全体 | マップ形式 |
| UPDATE | :refreshing? | true/false | 更新中フラグ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | ネットワークエラー | ダウンロード失敗 | エラーログ出力、処理継続 |
| N/A | 解析エラー | EDN解析失敗 | エラーログ出力、処理継続 |

### リトライ仕様

リトライなし（次回起動時に再取得）

## トランザクション仕様

アトム操作による排他制御（swap!）。

## パフォーマンス要件

- キャッシュ取得: 起動時にバックグラウンド実行
- 検索: 即座（メモリ上のマップ検索）

## セキュリティ考慮事項

- 外部URLからのデータ取得（信頼できるソース: clojure-emacs/clojuredocs-export-edn）

## 備考

- Orchard（CIDER）の実装にインスパイアされている
- エクスポートファイルは定期的に更新される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | clojuredocs.clj | `lib/src/clojure_lsp/feature/clojuredocs.clj` | キャッシュ構造とデータ形式を理解 |

**読解のコツ**: EDNファイルの構造（キーワード -> データマップ）を把握する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | handlers.clj | `lib/src/clojure_lsp/handlers.clj` | clojuredocs-raw ハンドラ |
| 2-2 | startup.clj | `lib/src/clojure_lsp/startup.clj` | 起動時のキャッシュ更新 |

**主要処理フロー**:
- **367-370行目** (handlers.clj): `clojuredocs-raw` - 直接アクセスAPI
- **189-191行目** (handlers.clj): `initialize` での `f.clojuredocs/refresh-cache!` 呼び出し

#### Step 3: キャッシュ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | clojuredocs.clj | `lib/src/clojure_lsp/feature/clojuredocs.clj` | refresh-cache!, find-docs-for |

**主要処理フロー**:
- **18-36行目**: `refresh-cache!` - キャッシュ更新ロジック
- **38-46行目**: `find-docs-for` - シンボル検索
- **48-50行目**: `find-hover-docs-for` - ホバー用ラッパー

#### Step 4: ホバーへの統合を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | hover.clj | `lib/src/clojure_lsp/feature/hover.clj` | clojuredocs->hover-docs |

**主要処理フロー**:
- **41-67行目**: `clojuredocs->hover-docs` - ホバー表示用の整形

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

```
handlers/initialize (起動時)
    │
    └─ async/thread
           │
           └─ f.clojuredocs/refresh-cache!
                  │
                  ├─ http/test-remote-url!
                  ├─ slurp (ダウンロード)
                  ├─ edn/read-string (解析)
                  └─ swap! db* assoc :clojuredocs :cache

f.hover/hover-documentation (ホバー時)
    │
    └─ f.clojuredocs/find-hover-docs-for
           │
           └─ find-docs-for
                  │
                  ├─ (キャッシュ存在確認)
                  │
                  └─ get cache full-keyword
                         │
                         └─ {:doc :examples :see-alsos :notes}

handlers/clojuredocs-raw (直接API)
    │
    └─ f.clojuredocs/find-docs-for
```

### データフロー図

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

clojuredocs-export-edn ───▶ slurp ───▶ edn/read-string
(GitHub)                                    │
                                           ▼
                               {:clojure.core/map {...}
                                :clojure.core/reduce {...}
                                ...}
                                           │
                                           ▼
                                  :clojuredocs :cache
                                           │
         ┌─────────────────────────────────┤
         │                                 │
sym-name, sym-ns                    find-hover-docs-for
         │                                 │
         └─────────────────────────────────┤
                                           │
                                           ▼
                                 {:doc :examples
                                  :see-alsos :notes}
                                           │
                                           ▼
                          clojuredocs->hover-docs
                                           │
                                           ▼
                              ホバーコンテンツ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| clojuredocs.clj | `lib/src/clojure_lsp/feature/clojuredocs.clj` | ソース | ClojureDocs統合のメインロジック |
| hover.clj | `lib/src/clojure_lsp/feature/hover.clj` | ソース | ホバー表示との統合 |
| handlers.clj | `lib/src/clojure_lsp/handlers.clj` | ソース | LSPハンドラ |
| http.clj | `lib/src/clojure_lsp/http.clj` | ソース | HTTP通信ユーティリティ |
| settings.clj | `lib/src/clojure_lsp/settings.clj` | ソース | 設定管理 |
