はじめに
🤔「Google マップの評価が 4.5 なのに、自分には合わなかった…」
😥「この店、点数は低いけど自分はかなり好きなんだよな…」
🫠「結局、"みんなの平均" は自分の好みとは別物では…?」
グルメサイトの評価は平均値なので、これは当然のことです。
100 人の平均点が自分に合う保証はどこにもありません。
そこで、味の好みが近い人の「美味しかった」だけを頼りに探せるサービスを作りました。
あじぴた といいます🍜
2026 年 4 月に開発を始めて、現在はリリース済み・運用中です🚀
個人開発ですが、4,300 コミット / ADR 36 本 / テスト 2,200 ケース超の規模になりました。
この記事は、あじぴたの技術的な中身を書いていくシリーズの入口です📖
全体像を先に置いて、各論の記事へリンクしていきます。
シリーズの各記事は単体で読んで完結するように書きます。
この記事を読んでいないと分からない、という構成にはしません👍
どんなサービスか
味の好みが近い"ぴた友"の「美味しかった」を頼りに、あなた好みの一皿に出会える食のマッチングサービス。
一般的なグルメサイトとの違いは 2 つあります。
1. 評価の単位を「店」ではなく「料理」にした
「店全体としては普通だが、この一品だけは抜群」という情報は、
店単位で評価すると平均に溶けて消えます😢
そこで評価の単位を料理にしました。
これはマッチングにも効いています📈
同じ店が好きな 2 人でも、食べているものが違えば味覚が近いとは限りません。
料理単位なら「同じ一皿をどう感じたか」で比べられるので、一致したときの意味が強くなります。
2. 公開するのは「美味しかった」だけ🙊
あじぴたに低評価を投稿する機能はありません。
正確には「自分には合わなかった」を記録する機能はありますが、
これは誰にも公開されません🔒
機能の都合ではなく、作りたかったものがそうだったというのが理由です。
グルメサイトの低評価は、書く側にとっては数分の作業でも、
内容によってはお店を閉店に追い込んでしまうことさえあります。
この非対称性がずっと気になっていました。
それに、自分に合う一皿を探すのに他人の低評価は必要ありません🙅
店の点数が低かろうが「自分はこれが好き」が守られるべきだと考えています。
では「合わなかった」を何に使っているかというと、マッチングの精度です🔍
A さんと B さんの、公開されている「美味しかった」が 10 品中 8 品一致
→ 👀 味覚が近そうに見える
しかし別の 10 品で正反対の評価をしていたら?
→ 🙅 実際には全く似ていない
公開情報だけを見ていると、この裏側のズレが観測できません😇
非公開の「合わなかった」を内部で持つことで、見かけ上似ているだけのユーザーを除外できます✨
そしてこの「非公開データを絶対に漏らさない」という要件が、
結果的にインフラの選定まで決定づけました。この話は別記事で扱います📝
規模
「個人開発」という言葉から想像される規模とズレることがあるので、数字を置いておきます。
| 指標 | 値 |
|---|---|
| コミット数 | 4,300+(アプリ本体 3,500+ / 運営コンソール 420+ / LP 280+ / 拡張 56 / 運用 51) |
| 設計判断の記録(ADR) | 36 本 |
| DB マイグレーション | 185 本 |
| テスト | 3 層・2,200+ ケース |
| API エンドポイント | 49 本 |
| リポジトリ | 6 |
テストの内訳は以下の通りです。
| 層 | 手段 | ファイル | ケース |
|---|---|---|---|
| 単体 | Vitest | 72 | 838 |
| DB ロジック | pgTAP | 85 | 1,255 アサーション |
| E2E / API | Playwright | 44 | 165 |
開発は Claude Code と進めています🤖
AGENTS.md・ADR・カスタムスキルで文脈を渡す仕組みを整えていて、このあたりも記事にする予定です👀
技術スタック
| 領域 | 使用技術 |
|---|---|
| フロントエンド | Next.js 16 / React 19 / TypeScript / Tailwind CSS 4 |
| バックエンド・DB | Supabase(PostgreSQL / Auth / Storage / RLS) |
| 店舗データ | HotPepper グルメサーチ API(主経路)+ Google Places API (New)(0 件のときだけ) |
| 地図 | Google Maps JavaScript API |
| ホスティング | Vercel(アプリ本体)/ Netlify(運営コンソール・LP) |
| バッチ | pg_cron + Supabase Edge Functions |
| 監視 | Sentry(エラー + Web Vitals) |
| 分析 | GTM + GA4(同意管理付き)/ 運営コンソールの分析ページ(KPI・時系列グラフ) |
6 リポジトリ構成
1 つのサービスですが、リポジトリは 6 つに分かれています。
| リポジトリ | 役割 | ホスティング |
|---|---|---|
| アプリ本体 | ユーザーが使う Web アプリ | 💰 Vercel(有料) |
| 運営コンソール | 運営スタッフ用の管理画面 | 🆓 Netlify(無料枠) |
| サービスサイト | LP。アプリへの導線 | 🆓 Netlify(無料枠) |
| 拡張 | 運用効率化のための Chrome 拡張 | — |
| 運用・グロース | 施策・数字・資金調達の管理。コードは置かない | — |
| 記事 | 技術記事の執筆管理。コードは置かない | — |
下 2 つはコードを置かず、施策や記事の下書きをファイルで管理しています📂
コードと同じく、Claude Code にそのまま作業してもらえる形にするためです。
ホスティングを 2 社に分けた一番の理由は、コストです💰
個人開発なので、無料で使えて商用利用もできることを最優先にしました。
Netlify にはその条件を満たす無料枠があるため、アプリ本体以外はこちらに載せています。
あわせて、管理画面や LP のビルドでアプリ本体の枠を圧迫しない効果もあります。
注目してほしいのは、アプリ本体と運営コンソールで、同じ DB を触る流儀が異なる点です👀
- アプリ本体: BFF を経由し、RLS で行レベルに保護された状態で触る🔒
- 運営コンソール: 管理者権限で、RLS をバイパスして触る🔑
同じ DB に対して非対称な作りになっています。これは意図的な判断で、理由は別記事で扱います📝
全体構成
赤が課金の発生する箇所、緑が無料で運用している箇所です。
個人開発で最もリスクが高いのは従量課金で、図では Google Places と Geocoding が該当します💸
試算したところ MAU 5,000 で月 $1,440 に達することが分かったため、
8 層の防壁を設けて抑え込みました🛡️
この 8 層の防壁は、別の記事で詳しく書きました🔥
🔗 Google Places APIで月$1,440の請求が来る前に — 個人開発で従量課金を「呼ばない」8層の防壁
解剖ドキュメントを公開しています📚
記事とは別に、あじぴたの中身を淡々と記述したドキュメントを GitHub に置いています。
記事が「特定のテーマを深掘りする」のに対し、こちらは全体を通して読める解剖図です🔬
| 章 | 内容 |
|---|---|
| 1. 全体構成 | 6 リポジトリ・ホスティング・同じ DB を 2 つの流儀で触る設計 |
| 2. プロダクト設計 | なぜ作ったか・料理単位・サイレントネガティブ |
| 3. フロントエンド | ディレクトリ設計・状態管理・パフォーマンス改善の実録 |
| 4. バックエンド・データ | BFF・RLS・3 層のテスト・退会処理 |
| 5. インフラ・CI/CD | 3 層の環境・CI の切り分け・監視 |
| 6. コスト | 固定費の内訳・8 層の防壁・試算 |
| 7. 開発プロセス | ブランチ・ADR・AI との協業 |
書いている目的は、自分の理解を補強するためです💪
実装中の判断は数が多く、時間が経つと忘れてしまいます。
それを他人に説明できる形へ昇華させることで、使える知識として身につけていく。
その積み重ねで知見が広がり、エンジニアとして強くなれると考えています。
記事は、このドキュメントから特に書きごたえのある部分を抜き出して深掘りする形で書いていきます✍️
シリーズの予定
公開したものから順にリンクを追記していきます。
| # | 記事 | 内容 | 状態 |
|---|---|---|---|
| 1 | この記事 | 全体像 | ✅ 公開 |
| 2 | Google Places API で月 $1,440 の請求が来る前に | 従量課金 API と付き合う設計 | ✅ 公開 |
| 3 | Next.js 16 で Web Vitals を測って直した実録 |
loading.tsx を足して LCP が倍になった話 |
🔜 準備中 |
| 4 | 1 つのサービスを 6 リポジトリで運用する | 同じ DB を 2 つの流儀で触る設計 | 🔜 準備中 |
| 5 | App Router のディレクトリ設計を半年運用してみた | 過去記事の答え合わせ | 🔜 準備中 |
| 6 | 「店ではなく料理を評価する」がインフラ選定まで決めた話 | プロダクトの核 | 🔜 準備中 |
| 7 | RLS を「サービスの信頼性の根幹」として設計する | 非公開データをどう守るか | 🔜 準備中 |
| 8 | 個人開発のデプロイと CI/CD | 3 層の環境を GitHub Actions で回す | 🔜 準備中 |
| 9 | AI と個人開発を回す | スキル・ADR で文脈を渡す | 🔜 準備中 |
まとめ
- あじぴたは、**味の好みが近い人の「美味しかった」**を頼りに一皿を探すサービスです🍜
- 個人開発ですが、4,300 コミット / ADR 36 本 / テスト 2,200 ケース超の規模です📊
- 6 リポジトリ構成。ホスティングはコストを最優先に Vercel と Netlify へ分けています💰
- アプリ本体と運営コンソールで、同じ DB を異なる流儀で触る設計にしています🔑
- 従量課金 API は、8 層の防壁でコストの上振れを抑えています🛡️
- 中身を記述した 解剖ドキュメント も公開しています📚
8 層の防壁の詳細は、こちらの記事で書いています💸
Places に限らず、LLM API でも決済 API でも同じ構造が使える内容になっています🔥
サービス自体も、よろしければ触ってみてください🍜
🔗 あじぴた
参考になれば幸いです🙏
