GitHubのPR差分からドキュメントを自動更新するAI SaaS「Diff Note」を個人開発しました
はじめに
個人開発や小規模チームで開発をしていると、コードを書く速度にドキュメントの更新が追いつかないことがよくあります。 機能を追加してPRをマージしても、READMEは古いまま、アーキテクチャの変更理由(ADR)はどこにも残っていない。結果として、数ヶ月後の自分が「なぜこの実装にしたんだっけ?」と頭を抱えることになります。
この問題を解決するために、GitHubのPR差分を解析し、READMEの更新やADRの作成を全自動で行うSaaS「Diff Note」を開発しました。
本記事では、Next.js + Supabase + LLMで構築したSaaSのアーキテクチャと、個人開発特有の「実装しない勇気(Human API)」を取り入れた決済フローについて紹介します。
作ったもの:Diff Note
Diff Noteは、GitHub Appとして動作するドキュメント自動生成ツールです。 リポジトリにインストールするだけで、以下のフローを自動化します。
- PR作成・更新:GitHub Webhookを検知
- 差分解析:コードの変更点(diff)を取得し、LLMが「コードの意図」を解析
- ドキュメント生成:
ターゲットは個人開発者および小規模なスタートアップです。月10PRまでは無料で利用でき、それ以上は月額2,980円のProプランを用意しました。
サービスURL: Diff Note (※ここに実際のURLを入れてください)
技術スタック
開発期間を短縮しつつ、SaaSとして最低限の堅牢性を確保するために以下の構成を採用しました。
- Frontend / Backend: Next.js (App Router)
- Infrastructure: Vercel
- Database: Supabase (PostgreSQL)
- AI: Anthropic Claude 3.5 Sonnet / OpenAI GPT-4o
- Payment: Stripe Payment Links
アーキテクチャのポイント
開発において特に注力した、あるいは工夫したポイントを3つ紹介します。
1. Webhookの冪等性(Idempotency)の担保
GitHubのWebhookは、タイムアウトや通信エラーが発生した場合に同一のイベントを再送してくる仕様があります。また、誤って二重にクリックしてしまった場合など、短時間に重複したリクエストが飛んでくることもあります。
LLMのAPIコールはコストがかかるうえ、同じPRに対して2回コメントが投稿されるのはUXとして致命的です。また、今回は従量制限(月10回)を設けているため、二重カウントは絶対に避ける必要がありました。
そこで、Supabase上に webhook_events と pr_operations という2つのテーブルを用意し、以下のロジックで冪等性を担保しています。
- 受信時:GitHubからの
X-GitHub-Deliveryヘッダー(UUID)を主キーとしてイベントを保存。DBのユニーク制約により、物理的に重複データの挿入を弾く。 - 処理開始前:
repo_id+pr_number+commit_shaの組み合わせで検索し、すでにstatus: successなレコードが存在すれば処理をスキップして200 OKを返す。 - 処理完了後:処理結果をDBに書き込み、コミットハッシュに対する処理済みフラグを立てる。
これにより、Vercelのサーバーレス環境でも安心してWebhookを処理できる構成としました。
2. LLMによる「意図」の抽出
単にコードのdiffをLLMに投げて「要約して」と頼むと、「auth.tsの10行目が変更されました」といった、エンジニアにとっては無益な説明が出力されがちです。
本プロダクトでは、プロンプトエンジニアリングにおいて以下の点を徹底しました。
- シニアエンジニアのペルソナ:レビュワーに対して説明する立場であることを明示。
- HowではなくWhy:「何をしたか」ではなく「なぜ変更したか、何が変わったか(Impact)」に焦点を当てる。
- ノイズの除去:ロックファイルやフォーマット変更など、意味のない差分は前処理で除外。
これにより、「認証ロジックが変わった」だけでなく「トークン有効期限の管理方式が変更され、クライアント側の再ログインが必要になる可能性がある」といった、ドキュメントとして価値のある出力を目指しました。
3. Stripe Payment Linksと「Human API」による決済実装
個人開発SaaSにおいて、決済機能の実装は最も工数がかかり、かつバグが許されない鬼門です。 今回はMVP(Minimum Viable Product)としてのリリース速度を優先し、StripeのAPIをコードに組み込むことをやめました。
代わりに採用したのが Stripe Payment Links です。
- Stripeのダッシュボードで「支払いリンク」を発行する。
- 制限(月10回)を超えたユーザーには、コード上でそのリンクを案内する。
- ユーザーが決済すると、Stripeから通知が来る。
- 管理者が手動でSupabaseのデータを書き換えてProプランにする。
いわゆる「Human API(手動運用)」です。 コードを書く時間をゼロにし、まずは「価値に対して対価が支払われるか」を検証することを最優先しました。自動化は、手動対応が追いつかなくなるほどユーザーが増えてからでも遅くありません。
今後の展望
現在はMVPとして「PRコメントによるテキスト提示」までを実装していますが、今後は以下の機能を予定しています。
- リポジトリへの直接コミット機能(ドキュメントの自動マージ)
- Slack通知連携
- チーム向けプランの拡充
おわりに
ドキュメント作成は重要ですが、開発の勢いを削ぐ作業でもあります。Diff Noteは、そんな「面倒だけど重要」なタスクをAIにオフロードするためのツールです。
現在は月10PRまで無料で利用できますので、もしよろしければ個人のリポジトリなどで試してみてください。