本文へスキップ
nomunomu0504.dev

BLOG #NEXTJS

みんなの生ビールマップ: 「銘柄から店を探す」だけに絞った地図アプリの作り方

Hiroki Nomura 4 MIN READ nextjs supabase postgis indie-dev
目次

ひとつの体験だけ

「黒ラベルの生が飲める、新宿駅から徒歩 5 分以内の店」を 3 秒で見つけて、メニューの写真でいま飲めるかを確かめる。みんなの生ビールマップ(愛称みんなま)の MVP は、この 1 文だけを実現するために作った。

だから入れなかったものが多い。いいね、フォロー、フィードのような SNS 機能はない。ランキングも信頼スコアもない。店舗管理、予約、決済、クーポンもない。店名からではなく、いま飲みたい銘柄から店を探す。店と銘柄の情報は、利用者が写真と一緒に持ち寄って育てる。

minnama.beer のトップページ
minnama.beer。トップにあるのは「銘柄から店を探す」の導線だけ

作り

  • Next.js(App Router)と Tailwind、TanStack Query。PWA としてインストールでき、ネイティブアプリは作らない
  • Supabase。Postgres に PostGIS を足して半径検索、Auth は Google のみ、画像は Storage の変換機能で配信、全テーブルに RLS
  • 地図は MapLibre GL JS と OSM タイル
  • Vercel に配信。投稿と通報は Slack に通知

投稿はログインなしでもできる。Google でログインすると、お気に入り、自分の投稿の編集、投稿履歴だけの公開ページが使える。閲覧と検索はログイン不要。

みんなの生ビールマップの画面 3 枚
左から、地図 / エリアページ / 店舗ページ。PWA なので画面は Web そのもの

鮮度を見せる

ビール地図の価値は「いま飲めるか」に尽きる。1 年前の情報を頼りに行って置いていなかった、が一度あれば二度と使われない。

そこで店舗ごとに「最後に確認された日」からの経過を 4 段階で色分けした。30 日以内、31〜90 日、91〜365 日、1 年超。一覧は新しい情報が多い店から並ぶ。情報が間違っていたら、実際に訪問した人の投稿が最新として上書きする。正しさを運営が保証するのではなく、いつの情報かを隠さずに見せる、という設計にした。

情報の鮮度を 4 段階で示す説明
最終確認日からの経過を 4 段階で色分けする

Google Places の規約を守る

店名の入力を楽にするために Google Places Autocomplete(New)を使っている。ただし Places API のレスポンスをそのまま保存するのは規約違反だ。規約を読んで、保存と表示のルールをこう切った。

データ 扱い
place_id 永続保存してよい(規約の明示的な例外)
店名・住所・座標 利用者が確認・編集した値として保存する
Places のレスポンスそのもの 保存しない

投稿フローでは、候補を選ぶとフォームに仮入力され、利用者がそれを確認・編集してから投稿する。この時点で「利用者が提供したコンテンツ」になる。画面に出すのは DB に保存した値だけで、Places 由来のデータは表示しない。Google の帰属表示は候補を出すときにだけ付ける。地図に Places 由来の情報を出さないので、タイルは OSM でよい。

Places の解釈が変わったときのために、入力補助の部分は抽象化して Nominatim に差し替えられるようにしてある。

運営の設計

お酒を扱うサービスなので、最初から入れたものがある。

  • フッターに「20 歳未満の飲酒は法律で禁じられています」を常時表示し、初回投稿で年齢確認のチェックと同意時刻を記録する
  • 通報は 5 カテゴリで、Slack に飛ぶ。対応は role = admin のユーザーだけが入れる管理画面から
  • アカウント削除は匿名化で行う。投稿自体は残し、投稿者との紐付けだけを外す
  • 銘柄マスタは勝手に増やせない。利用者は「提案」として pending に入れ、管理者が昇格と表記ゆれの統合をする

これから

いまは 70 前後の銘柄が登録され、銘柄ごとの歴史や味わいを書いたコラムも並んでいる。投稿の編集と削除、E2E テストが未着手。ネイティブアプリは PWA で代替する方針のまま。minnama.beer

  1. LaterHub: 「あとで読む」をチームのナレッジにするために作ったもの 5 min
  2. Cherimo: 大切な人の「小さなこと」を覚えておくアプリを、利用データから作り直した話 6 min
  3. Stacky: iOS でクリップボード履歴アプリを作るとき、OS の制約から逆算した話 7 min
Hiroki Nomura @nomunomu0504 · CTO, MIRAI STUDIO

Flutter / AWS / 自宅サーバー。個人開発と OSS をいくつか。設計相談や協業の話は X の DM か About から。 About

COMMENTS · GISCUS