🎯 概要

このシステムは、はてなブックマークの人気エントリーを自動収集し、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 19App Router Server Components
言語TypeScript型安全な開発
スタイリングCSS Modules + CSS Variablesコンポーネント固有スタイル
データベースNeon PostgreSQLエントリー・コメント・画像(Blob)保存
ベクトル検索pgvector (halfvec)記事概要のベクトル化保存 (3072次元)
データ収集rss-parser + axiosRSSフィードと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 を直接取得して表示しています。常に最新のドキュメントがサイト上に反映されます。
  • レンダリング:
    • react-markdownremark-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. 記事選定: 直近1週間の人気エントリーを抽出
    2. 情報深掘り: Tavily APIを使用して、各ニュースの背景情報をリサーチ
    3. 台本作成: Gemini 3 Flash Preview が、パーソナリティ2人の掛け合い台本を生成
    4. 音声合成: Gemini 2.5 Flash (TTS) を使用し、マルチスピーカー設定で音声を生成
    5. 配信: 生成された音声データはVercel Blobに保存され、専用のRSSフィードで配信されます。