🎯 概要
このシステムは、はてなブックマークの人気エントリーを自動収集し、Vercel上のNext.js App Router Server Componentsによる動的レンダリングで配信するWebアプリケーションです。
主な機能
- 🔄 データ収集 - RSSフィードを毎時確認し、最新の人気エントリーを自動収集
- 🤖 AI要約生成 - Gemini APIによる高速・高精度な記事要約文の生成
- 🖼️ 画像処理 - Favicon/サムネイルの自動取得と、API経由での最適化配信
- 💬 注目コメント表示 - はてなスター数の上位コメントを表示
- 📊 統計ダッシュボード - 直近14日間の傾向とカテゴリー別分析をグラフ表示
- 🔍 ベクトル検索対応 - 記事概要をベクトル化 (
text-embedding-004等) し、意味的検索の基盤を提供 - 📡 RSS配信 - サイト独自のRSSフィードを生成・配信
- 🌙 ダークモード対応 - ライト/ダークモード切替機能
- 📱 レスポンシブデザイン - PC・スマートフォン対応
技術スタック
| カテゴリ | 技術 | 用途 |
|---|---|---|
| フロントエンド | Next.js 16 + React 19 | App Router Server Components |
| 言語 | TypeScript | 型安全な開発 |
| スタイリング | CSS Modules + CSS Variables | コンポーネント固有スタイル |
| データベース | Neon PostgreSQL | エントリー・コメント・画像(Blob)保存 |
| ベクトル検索 | pgvector (halfvec) | 記事概要のベクトル化保存 (3072次元) |
| データ収集 | rss-parser + axios | RSSフィードとHatena APIから取得 |
| AI統合 | gemma-3-27b | 記事要約生成 |
| 画像処理 | Sharp | 画像リサイズ・最適化 |
| 定期実行 | Inngest | サーバーレスバックグラウンドジョブ |
| ログ監視 | Axiom + next-axiom | ログ収集・分析 |
🏗️ アーキテクチャ
サービス連携図
Vercelを中心とし、Inngestがジョブを駆動し、Neonや各APIと連携する構成です。
graph LR Inngest["Inngest<br/>(Job Scheduler)"] --> Vercel subgraph Vercel ["Vercel (Next.js)"] API["API Routes"] App["App Router"] end subgraph Data ["Data & AI Services"] Neon[("Neon<br/>(PostgreSQL)")] Gemini["Gemini API<br/>(AI Models)"] Hatena["Hatena API/RSS<br/>(Source)"] Axiom["Axiom<br/>(Logging)"] end API -- Fetch --> Hatena API -- Summarize --> Gemini API -- Read/Write --> Neon API -- Log --> Axiom App -- Read --> Neon
システム処理フロー
1. 毎時処理 (Check Job)
graph LR A["Inngest Job<br/>毎時 25分/55分"] --> B["check-job"] B --> C["RSS取得 &<br/>メタデータAPI取得"] C --> D{新規/既存} D -- 新規 --> E["AI要約 & ベクトル化<br/>& 画像DL & DB登録"] D -- 既存 --> F["日付更新 &<br/>コメント更新"]
2. 日次処理 (Create Job)
graph LR G["Inngest Job<br/>毎日 00:00"] --> H["create-job"] H --> H1["日次履歴保存"] H1 --> H2["コメント再取得"] H2 --> H3["RSS生成"] H3 --> I["クリーンアップ &<br/>キャッシュクリア"] I --> J["前日の日付ページ生成"] I --> K["統計ページ生成"] I --> L["トップページ生成"]
3. Podcast作成処理 (Podcast Job)
graph LR M["Inngest Job<br/>毎週金曜 03:00"] --> N["podcast-job"] N --> O["対象期間・記事選定"] O --> P["Tavily詳細情報付与"] P --> Q["Gemini台本生成"] Q --> R["Gemini音声合成"] R --> S["メタデータDB保存"]
🔍 技術詳細
📅 日付ページ (/[date])
過去の人気エントリーを日付ごとに表示する機能です。
- 表示条件/並び順:
- 指定された日付に
latest_dateが記録されているエントリーを表示します。 - 並び順: その日付時点でのブックマーク数が多い順に降順ソートします。
- 指定された日付に
- データ取得と処理:
- ブックマーク数: 日本時間(JST)を基準に集計します。また、前日までのブックマーク数を右横に表示しています。
- Favicon: ドメイン毎に収集されたキャッシュ画像を使用し、欠損時はGoogle Favicon APIにフォールバックします。
- 記事要約: AIによって生成された3行程度の要約文を表示します。未生成の場合は自動的にバックグラウンド生成キューに入ります。
- 注目コメント:
- 各エントリーのはてなスター(カラースターを含む)の総数が多い上位コメントを抽出し、最大5件表示します。
ℹ️ Aboutページ (/about)
プロジェクト自身のドキュメント(README)を動的に表示するページです。
- コンテンツソース:
- GitHub API経由でリポジトリの
README.mdを直接取得して表示しています。常に最新のドキュメントがサイト上に反映されます。
- GitHub API経由でリポジトリの
- レンダリング:
react-markdownとremark-gfmを使用し、GitHub Flavored Markdownを忠実に再現しています。- Mermaid対応: 記事内のダイアグラム(Mermaid記法)をクライアントサイドでSVG画像としてレンダリングします。
- スタイリング:
github-markdown-cssを採用し、GitHubライクな見やすいスタイルを提供しています。
📊 統計ページ (/stats)
サイト全体のトレンドやカテゴリー比率を可視化するダッシュボードです。
- グラフ描画 (Recharts):
Rechartsライブラリを使用し、レスポンシブ対応のSVGグラフを描画しています。
📡 RSSフィード (/rss)
RSSリーダーユーザー向けに、サイト独自のRSSフィードを配信しています。
- 生成技術:
rssライブラリを使用し、RSS 2.0準拠のXMLを生成します。
🎙️ Podcast自動生成 (/podcast/rss)
週に一度、人気エントリーを元にAIが会話形式のポッドキャストを自動生成・配信します。
- 生成フロー:
- 記事選定: 直近1週間の人気エントリーを抽出
- 情報深掘り: Tavily APIを使用して、各ニュースの背景情報をリサーチ
- 台本作成: Gemini 3 Flash Preview が、パーソナリティ2人の掛け合い台本を生成
- 音声合成: Gemini 2.5 Flash (TTS) を使用し、マルチスピーカー設定で音声を生成
- 配信: 生成された音声データはVercel Blobに保存され、専用のRSSフィードで配信されます。