Workshop 2 — Lives Summary Edition

今日作るもの:学長ライブまとめビューア

YouTube ライブの視聴メモを Claude Code に渡すだけで、構造化された JSON データと、そのまま読める HTML カードビューアが完成します。コードは1文字も書きません。

作るものJSON データ + HTML ビューア
所要時間約 90 分
必要スキルWS1 完走済
Hands-on 5 Steps Sonnet 1ショット対応
1
骨子JSON
2
要約抽出
3
アクション化
4
HTML化
5
複数本一覧
📁 開始前の準備
1
エピソード骨子を JSON で作る
タイトル・日付・トピックの構造化
何をするか:視聴したライブの基本情報 (タイトル/日付/主要トピック) を Claude にまとめてもらい、`episode.json` というファイルに保存します。
メモが手元にない場合は、Claude にサンプルメモから生成してもらえば OK。
Claude Code に貼り付けるプロンプト
このフォルダに `episode.json` を **1ファイルだけ** 作ってください。他のファイルは作らないでください。

JSON 構造 (この通りに):
```json
{
  "episode_id": "2026-04-25-investment-basics",
  "title": "投資の基本 — 新NISA 活用編",
  "broadcast_date": "2026-04-25",
  "duration_minutes": 60,
  "source_url": null,
  "topics": ["新NISA", "インデックス投資", "長期運用"],
  "summary": "新NISA の3つの口座を使い分けるための基礎知識を整理する回",
  "key_takeaways": [],
  "action_items": [],
  "related_terms": [],
  "notes_md": ""
}
```

`summary` は1行30〜50字 (Step5 の一覧画面で使います)。

入力素材 (このどちらかを使う):
A) 自分が視聴したライブのメモがあれば、メモを元に上の JSON を埋める
B) メモがなければ、サンプルとして「両学長 投資の基本」をテーマに自由に内容を埋める

ルール:
- `episode_id` は `YYYY-MM-DD-トピック英単語` 形式 (例: `2026-04-25-investment-basics`)
- `topics` は3〜5個 (テーマを表す短い日本語キーワード)
- `summary` は1行30〜50字程度の短文 (Step5 の一覧表示で使用)
- `key_takeaways` / `action_items` / `related_terms` / `notes_md` はこの Step では空配列・空文字のままでOK (Step2-3 で埋めます)
- 文字コードは UTF-8、改行は LF
- JSON として valid であること (末尾カンマ禁止、ダブルクォートのみ使用)

作成後、ファイル全体を表示して確認させてください。
✓ できたら確認
  • フォルダに episode.json ができている
  • ファイルを開くと JSON 構造になっている (波括弧 + キーバリュー)
  • topics に3〜5個のキーワードが入っている
詰まったとき
JSON が壊れている (パースエラー)
`episode.json` を再生成してください。末尾のカンマ、シングルクォート使用、未閉じカッコがないか確認して、最も単純な JSON 構造に書き直してください。生成後、以下のいずれかで valid か確認してください:
- `cat episode.json | python3 -m json.tool` (macOS / Linux)
- `node -e "JSON.parse(require('fs').readFileSync('episode.json', 'utf8')); console.log('valid')"`
- どちらも無ければファイル全体を表示して、ダブルクォート・カンマ・カッコの位置を目視確認
episode.json が確認できたら押してください
2
キーポイント抽出
key_takeaways に3〜5件埋める
何をするか:動画の重要ポイントを Claude に抽出してもらい、`episode.json` の `key_takeaways` 配列を埋めます。
「こう言ってた」「これが大事」と思うフレーズを、自分の言葉で短く要約する形に。
Claude Code に貼り付けるプロンプト
`episode.json` を更新してください。**新しいファイルは作らないでください**。

変更範囲: `key_takeaways` 配列のみ。**他のフィールド (title/topics/summary/etc) は1文字も変更しないこと**。

`key_takeaways` 配列に **3〜5件** の重要ポイントを追加してください。

抽出ルール:
- 1件あたり40字以内 (短く自分の言葉で)
- 「〜が重要」「〜すべき」のような行動につながる表現を優先
- 単なる事実列挙ではなく、「だから何?」が分かる形
- 教材として **断定や煽り表現は避ける** ("一択" "ほぼ正解" "絶対" は禁止、"〜が選択肢として有力" 等に)

例 (新NISA トピックの場合):
```
"key_takeaways": [
  "新NISA は年360万円までの非課税投資枠を3つの口座で使い分ける",
  "つみたて投資枠は信託報酬の低いインデックスファンドが選択肢の中心",
  "成長投資枠は個別株より高配当ETF が初心者向けの選択肢として扱いやすい"
]
```

入力素材:
- Step1 で `topics` に書いたテーマに沿った内容にしてください
- メモが手元にあればその内容、なければ Step1 で書いた topics の延長で常識的な範囲で生成

完了後:
1. JSON 全体が valid か確認 (Step1 の recovery と同じ方法で)
2. `episode.json` の `key_takeaways` 部分だけ抜粋して表示
✓ できたら確認
  • episode.jsonkey_takeaways に3〜5件入っている
  • 各要素が文字列で、40字程度に収まっている
  • JSON として壊れていない (Step1 同様の確認)
詰まったとき
key_takeaways が長文すぎる
`key_takeaways` の各要素が長すぎます。1件あたり40字以内、能動態の文末で書き直してください。「〜が大切です」のような受け身ではなく「〜が重要」「〜すべき」のような直接表現を優先してください。
3
アクションアイテムと関連用語
行動につながる項目に変換
何をするか:視聴して終わりではなく、1週間以内に試せる行動関連する学習用語 に変換します。「学んだ」を「やる」に橋渡しする工程。
Claude Code に貼り付けるプロンプト
`episode.json` を更新してください。**新しいファイルは作らないでください**。

変更範囲: `action_items` と `related_terms` の2配列のみ。**他のフィールド (title/topics/summary/key_takeaways/etc) は1文字も変更しないこと**。

2つの配列を埋めてください:

1. `action_items` (3件): **1週間以内に実行可能** な具体的行動
   - 動詞で始まる (例: 「証券口座の手数料一覧を確認する」)
   - 具体的・測定可能 (例: 「1日10分」「3社比較」)
   - 抽象論禁止 (例: 「投資について学ぶ」は NG)

例:
```
"action_items": [
  "現在の証券口座の手数料体系を確認し、移管が必要か判断する",
  "つみたて投資枠で買えるインデックスファンドを3本ピックアップして比較表を作る",
  "毎月の積立額を家計から計算し、無理なく続けられる金額を決める"
]
```

2. `related_terms` (3〜5件): エピソードで触れた **専門用語** や **関連する学習トピック**
   - 短い日本語または英語
   - 後で別のエピソードと関連付けるため

例:
```
"related_terms": ["新NISA", "つみたて投資", "インデックスファンド", "信託報酬", "ドルコスト平均法"]
```

完了後、`action_items` と `related_terms` を抜粋表示してください。
✓ できたら確認
  • action_items 3件 — 1週間以内に動詞で始まる行動
  • related_terms 3〜5件 — 短い用語
  • 「投資について学ぶ」のような抽象アクションが含まれていない
詰まったとき
アクションが抽象的すぎる
`action_items` を見直してください。各項目に「いつまで・何を・どう測るか」が含まれているか確認し、抽象的なものは具体的な行動に書き換えてください。「学ぶ」「理解する」「考える」は禁止語、代わりに「確認する」「比較する」「計算する」「書き出す」を使ってください。
4
HTML ビューアを作る
JSON を読み込んでカード表示
何をするか:`episode.json` の内容を綺麗な HTML カードとして表示する `viewer.html` を作ります。
ブラウザで開くだけで読める形になり、後で他のエピソードを追加する基盤になります。
Claude Code に貼り付けるプロンプト
このフォルダに `viewer.html` を **1ファイルだけ** 作ってください。`episode.json` は触らないでください。

DOM 構造 (この通りに):
```html
<body>
  <input type="file" id="json-input" accept=".json">
  <article id="episode-card" hidden>
    <header>
      <span id="ep-date"></span>
      <h1 id="ep-title"></h1>
      <div id="ep-topics"></div>
    </header>
    <section>
      <h2>💡 キーポイント</h2>
      <ul id="ep-takeaways"></ul>
    </section>
    <section>
      <h2>✅ アクションアイテム</h2>
      <ul id="ep-actions"></ul>
    </section>
    <section>
      <h2>🔗 関連用語</h2>
      <div id="ep-terms"></div>
    </section>
  </article>
</body>
```

動作仕様:
1. `#json-input` の change イベントで FileReader を使って JSON を読む (`fetch` は file:// で動かないので使わない)
2. JSON.parse() で構造化、各要素を該当 DOM に挿入:
   - `#ep-date` ← `broadcast_date`
   - `#ep-title` ← `title`
   - `#ep-topics` ← `topics` 配列を `<span class="chip">` で並べる
   - `#ep-takeaways` ← `key_takeaways` 配列を `<li>` で
   - `#ep-actions` ← `action_items` 配列を `<li>` で
   - `#ep-terms` ← `related_terms` 配列を `<span class="term">` で
3. JSON 読み込み完了後、`#episode-card` の hidden を外して表示

セキュリティ:
- 各文字列は **必ず textContent で挿入** してください (innerHTML 禁止、XSS 対策)
- topics/related_terms のチップは createElement + textContent で組み立てる

CSS 装飾:
- 全体をクリーム系背景 (#f5f1e8)、カード白 (#ffffff)、角丸 14px
- タイトル 1.8rem、本文 1rem、行間 1.65
- topics/related_terms のチップは pill 型 (border-radius: 999px、background: 薄色)
- セクション間に 1.5rem の余白
- max-width: 720px で中央寄せ

`file://` で開いて動くこと。外部 fetch なし。
✓ できたら確認
  • viewer.html をブラウザで開ける
  • 「ファイルを選択」で episode.json を選ぶとカードが表示される
  • title / takeaways / actions / terms が揃って見える
詰まったとき
JSON 読み込みでエラー
JSON 読込エラーが出ます。原因候補を3つに絞って:
1. JSON.parse のエラーメッセージを console.log で確認
2. FileReader.readAsText の実行タイミング (onload 内で処理しているか)
3. ファイル選択キャンセル時のガード (e.target.files[0] が undefined のケース)

3つすべてを最もシンプルに書き直してください。エラーハンドリングは try-catch で「JSON が壊れています」とユーザーに表示するだけで OK。
カードのレイアウトが崩れる
レイアウトが崩れています。CSS をシンプルな単一カラム (flexbox 不要、display: block ベース) に書き直してください。アニメーション・transform は全部外してください。
5
複数エピソードを一覧表示
配列で複数エピソードを管理
何をするか:1本だけのエピソードビューアから、複数本まとめて閲覧できる一覧に拡張します。フィルタリング (topics で絞り込み) も追加。これで自分専用のミニ「学長ライブまとめサイト」が完成します。
Claude Code に貼り付けるプロンプト
この Step では **2つのファイル** を扱います:
- `viewer.html` を更新 (既存ファイル)
- `episodes.json` を **新規作成** (これは新規 OK、それ以外のファイルは作らない)

## 1. `episodes.json` の作成手順

ステップ:
- まず Step1-3 で作った `episode.json` の中身を **1件目** としてコピーする
- 2件目・3件目は、Step1-3 と同じ schema で **サンプルとして** Claude に生成させる
- 全エピソードが同じ schema (episode_id, title, broadcast_date, summary, topics, key_takeaways, action_items, related_terms) を持つこと

`episodes.json` の **完全な valid JSON サンプル** (この通りの構造にしてください、`{ ... }` のような略記は使わない):
```json
{
  "episodes": [
    {
      "episode_id": "2026-04-25-investment-basics",
      "title": "投資の基本 — 新NISA 活用編",
      "broadcast_date": "2026-04-25",
      "duration_minutes": 60,
      "source_url": null,
      "topics": ["新NISA", "インデックス投資", "長期運用"],
      "summary": "新NISA の3つの口座を使い分けるための基礎",
      "key_takeaways": ["年360万円の非課税枠を3口座で使い分ける"],
      "action_items": ["証券口座の手数料体系を確認する"],
      "related_terms": ["新NISA", "つみたて投資"],
      "notes_md": ""
    },
    {
      "episode_id": "2026-04-18-tax-strategy",
      "title": "節税の基本",
      "broadcast_date": "2026-04-18",
      "duration_minutes": 55,
      "source_url": null,
      "topics": ["節税", "iDeCo", "ふるさと納税"],
      "summary": "会社員でもできる3つの節税の入口",
      "key_takeaways": ["iDeCo は所得控除で節税効果が見込める"],
      "action_items": ["源泉徴収票で課税所得を確認する"],
      "related_terms": ["iDeCo", "ふるさと納税"],
      "notes_md": ""
    },
    {
      "episode_id": "2026-04-11-side-income",
      "title": "副業の選び方",
      "broadcast_date": "2026-04-11",
      "duration_minutes": 50,
      "source_url": null,
      "topics": ["副業", "ライティング", "時間管理"],
      "summary": "本業に支障を出さない副業の3条件",
      "key_takeaways": ["最初は時給ではなく経験値を取りに行く"],
      "action_items": ["週に使える時間を時間単位で書き出す"],
      "related_terms": ["時給単価", "経験曲線"],
      "notes_md": ""
    }
  ]
}
```

## 2. `viewer.html` の変更点

DOM 構造:
```html
<body>
  <input type="file" id="json-input" accept=".json">
  <div id="filter-bar"></div>
  <div id="episode-list"></div>
</body>
```

**重要**: Step4 のカードレイアウトを再利用しますが、**1ページ内に複数のカードが並ぶため、単一 ID (#ep-title など) を使い回さないでください**。各エピソードカードは `class="ep-title"` のように **クラス名** に変えるか、`data-episode-id` 属性で識別してください。

状態管理 (JavaScript 冒頭で初期化):
```javascript
let episodes = [];
let activeFilter = "";   // 空 = 全件表示
let expandedId = null;   // 展開中のエピソードID (episode_id を使用)
```

動作仕様:
1. `#json-input` change で FileReader (fetch は禁止、file:// で動かない)
2. JSON.parse 後、`episodes = data.episodes || [];` で代入
3. **再描画前に必ず `replaceChildren()` で中身を空に** してから子要素を append (重複表示防止)
4. `#filter-bar`: 全エピソードの `topics` の和集合をチップ化、クリックで `activeFilter` 更新+再描画
5. `#episode-list`: `activeFilter === ""` なら全件、そうでなければ `topics.includes(activeFilter)` のみ表示
6. 各カードは `data-episode-id=""` を持つ親 div、中に title/date/topics/summary を表示
7. カードクリックで `expandedId` 更新+再描画 (展開時は key_takeaways/action_items/related_terms も表示)
8. 「1行サマリ」は `episode.summary` を使う (Step1 で追加済み)

セキュリティ:
- すべての文字列挿入は **textContent**
- すべての要素生成は **createElement**
- **innerHTML 禁止**

ブラウザで開いて、絞り込みとカード展開が動くことを確認してください。
✓ 完成チェック
  • episodes.json に3本のエピソードが入っている
  • viewer.html で読み込むと一覧が表示される
  • topics 絞り込みボタンで該当エピソードだけ残る
  • カードクリックで詳細が展開する
詰まったとき
絞り込みが反映されない
topics 絞り込みが効きません。activeFilter の更新タイミング、フィルタ後の再描画、初期状態 (空フィルタで全件表示) の3点を確認して、最もシンプルな実装に書き直してください。

🎉 完成おめでとうございます!

自分専用の学長ライブまとめビューアができました。episodes.json に新しいエピソードを追加するだけで永遠に拡張できます。

📄
viewer.html
ブラウザで動くカードビューア
📊
episodes.json
エピソードDB (追加可能)
💡
JSON 構造の知識
他の学習素材にも転用できる

次のチャレンジ: 自分の興味分野 (FP3級・読書・ポッドキャスト) の素材を同じ構造でまとめてみる

プロンプトハブを見る →