個人開発のアイデアをAIで深掘りするツールを作った話 — Next.js + Supabase + Claude Code
はじめに
個人開発のアイデアって、なぜか外にいるときに思いつく。
電車の中、昼休み、散歩中。でも家に戻るころにはほとんど忘れている。かろうじてメモしても、後で見返すとコンテキストが薄くて「あれ、これ何がしたかったんだっけ」となる。
そしていざAIに相談しようとすると、アイデアが散らばっていてプロンプトをまとめるだけで時間がかかる。
この流れをなんとかしたくて IdeaPosting を作りました。
IdeaPostingとは
「お題(テーマ)」と「メモ(アイデア)」の2階層でアイデアを整理するWebアプリです。
主な機能:
- お題 × メモ管理: テーマごとにアイデアを紐づけて整理
- AIヒント: メモ内容をもとにClaude Haikuが深掘りのヒントを提案
- AI前提情報: お題ごとに背景・制約をAIに渡せる(プロジェクトの文脈を記憶させる)
- MDエクスポート: 整理したアイデアをMarkdownで出力 → そのままAIへの指示プロンプトになる
- ステータス管理: todo / done / rejected でメモを分類
- ドラッグ&ドロップ並び替え
- モバイル対応(外でさっとメモできる)
技術スタック
| カテゴリ | 採用技術 |
|---|---|
| フレームワーク | Next.js 16 (App Router) / React 19 / TypeScript 5 |
| DB | Supabase (PostgreSQL + RLS) |
| 認証 | Supabase Auth (メール/パスワード) |
| DBクライアント | @supabase/supabase-js v2 + @supabase/ssr (SSR/クライアント分離) |
| AI | Anthropic Claude Haiku (claude-haiku-4-5-20251001) + Vercel AI SDK |
| スタイリング | Tailwind CSS v4 + shadcn/ui (Radix UI) |
| ドラッグ&ドロップ | @dnd-kit (core / sortable / utilities) |
| アイコン | Lucide React |
| CI/CD | GitHub Actions Self-hosted Runner |
| デプロイ | Ubuntu + PM2 + Nginx + Cloudflare Tunnel |
実装で面白かった点
1. ユーザーごとにAnthropicのAPIキーを管理する
「アプリ側でAPIキーを持つ」のではなく「ユーザーが自分のキーを登録して使う」設計にしました。
理由: 個人開発ツールなのでサーバー側のAPI費用を持ちたくなかった。
CREATE TABLE public.user_settings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID UNIQUE REFERENCES auth.users(id),
anthropic_api_key TEXT,
updated_at TIMESTAMPTZ DEFAULT now()
);
ALTER TABLE public.user_settings ENABLE ROW LEVEL SECURITY;
CREATE POLICY "owner_only" ON public.user_settings
FOR ALL USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
RLSで他ユーザーのキーが見えないようにしつつ、Route Handler側でサーバーから取得して使う:
// app/api/ai-hint/route.ts
const supabase = await createServerSupabaseClient();
const { data: settings } = await supabase
.from('user_settings')
.select('anthropic_api_key')
.single();
const anthropic = createAnthropic({ apiKey: settings.anthropic_api_key });
const { text } = await generateText({
model: anthropic('claude-haiku-4-5-20251001'),
prompt: ...,
maxTokens: 120,
});
クライアントにAPIキーを露出させずに済む点がポイントです。
2. お題単位の「AI前提情報」
AIにヒントをもらうとき、プロジェクトの背景を毎回書くのが面倒。そこでお題ごとに前提情報を設定できる機能を追加しました。
// ヒント生成時のプロンプト
const prompt = topicContext
? `【前提情報】\n${topicContext}\n\n【お題】${topicTitle}\n【メモ】${content}`
: `【お題】${topicTitle}\n【メモ】${content}`;
topics.context カラムに保存し、AIヒント・AIエクスポートの両方で参照します。
3. モバイルでのドラッグ&ドロップ対応
@dnd-kitの PointerSensor だとモバイルでclickイベントが消えてしまう問題があったので、MouseSensor + TouchSensor に分けました:
const mouseSensor = useSensor(MouseSensor, { activationConstraint: { distance: 8 } });
const touchSensor = useSensor(TouchSensor, {
activationConstraint: { delay: 250, tolerance: 5 },
});
delay: 250ms の長押しでドラッグ開始、短タップはclickとして通す設定です。
デプロイ構成
MAP-E接続の自宅サーバーにデプロイしています。外部ポート開放なしでHTTPS公開できるCloudflare Tunnelが便利でした。
外部 → Cloudflare (HTTPS) → Cloudflare Tunnel → Nginx :80 → PM2/Next.js :3000
CI/CDはGitHub ActionsのSelf-hosted Runnerで、masterマージ → 自動デプロイしています。
今後やりたいこと
- オンボーディング改善(初回ログイン時にサンプルデータを用意)
- フィードバック機能
- Product Hunt への出品
おわりに
使ってみてもらえると嬉しいです: https://www.naozi.jp
感想・フィードバックはXのDMまたは記事のコメントで歓迎します。
