No updates detected yet. GitHub releases will appear here.
Loading the full README. The saved excerpt is shown below.
訪れた都道府県・市区町村・スポットを記録し、日本地図から振り返るスマートフォン向けのライフログアプリです。 記録は自分だけのもので、他の利用者からは見えません。 • フロントエンド: Next.js 15(App Router)/ TypeScript / Tailwind CSS v4 • バックエンド: Supabase(Database / Auth / Storage / Row Level Security) • 公開想定: Vercel 1. supabase.com でプロジェクトを作成します。 2. supabase/migrations/ の SQL を番号順に SQL Editor へ貼り付けて実行します。 テーブル、RLS ポリシー、ストレージバケット photos、RPC がまとめて作成されます。 Supabase CLI を使う場合は supabase db push でも適用できます。 3. Authentication → Providers → Email を有効にし、Confirm email をオンにします。 4. Authentication → URL Configuration → Redirect URLs に {サイトURL}/auth/callback を追加します。Read the full README ↗
訪れた都道府県・市区町村・スポットを記録し、日本地図から振り返るスマートフォン向けのライフログアプリです。 記録は自分だけのもので、他の利用者からは見えません。
npm install
supabase/migrations/ の SQL を番号順に SQL Editor へ貼り付けて実行します。
テーブル、RLS ポリシー、ストレージバケット photos、RPC がまとめて作成されます。
Supabase CLI を使う場合は supabase db push でも適用できます。Confirm email をオンにします。{サイトURL}/auth/callback を追加します。.env.example をコピーして .env.local を作成します。
cp .env.example .env.local
| 変数 | 用途 |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabase プロジェクトの URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | anon(公開)キー |
NEXT_PUBLIC_SITE_URL | 確認メールやパスワード再設定リンクの戻り先 |
GOOGLE_PLACES_API_KEY | Google Places API(New)のサーバー用キー(任意。未設定なら検索欄は出しません) |
メール送信はアプリからは行いません(確認メール・パスワード再設定は Supabase Auth が送ります)。
サービスロールキーはクライアント側でもサーバー側でも使用しません。アカウント削除は
delete_own_account()(SECURITY DEFINER の RPC)経由で行います。
環境変数が未設定のまま起動した場合は /setup に手順が表示されます。
npm run dev # http://localhost:3000
npm run typecheck # 型チェック
npm run lint # ESLint
npm run build # 本番ビルド
./scripts/verify-rls.sh # RLS と RPC をローカルの PostgreSQL で検証(Supabase 不要)
node scripts/verify-supabase.mjs # 実 Supabase プロジェクトでの動作確認
verify-rls.sh は、素の PostgreSQL に Supabase 相当の土台を作って
supabase/migrations/*.sql を適用し、公開範囲とアプリが前提にしている挙動を118項目確認します。
verify-supabase.mjs は、新規登録・確認メール・ログイン・公開範囲・写真・アカウント削除を
実際のプロジェクトに対して順に確認します。
| 画面 | パス |
|---|---|
| ホーム | /home |
| SNS(フレンドと今日の写真を共有) | /sns /sns/new /sns/[photoId] |
| 日本地図(地方選択) | /map |
| 地方地図(都道府県選択) | /map/[region] |
| 都道府県地図(市区町村の境界 + 検索・一覧) | /map/[region]/[pref] |
| 市区町村詳細(スポット一覧) | /map/[region]/[pref]/[muni] |
| スポット詳細 | /spots/[spotId] |
| スポット登録・編集 | /spots/new /spots/[spotId]/edit |
| 訪問履歴の追加・編集 | /visits/new /visits/[visitId]/edit |
| 旅行の作成・詳細・設定 | /trips/new /trips/[tripId] /trips/[tripId]/settings |
| 記録(タイムライン / 旅行 / スポット / カレンダー) | /records |
| お気に入り / また行きたい場所 | /mypage/favorites /mypage/wishlist |
| おでかけレベル・EXP履歴 | /mypage/exp-history |
| おでかけコイン | /mypage/coins |
| そうび(獲得したアクセサリー・称号) | /mypage/gear |
| マイページ | /mypage /mypage/profile /mypage/account |
ログイン後の主要画面には、画面下部に「ホーム / SNS / 地図 / 追加 / 記録 / マイページ」の固定ナビゲーションを表示します。 「追加」は中央に配置しています。
画像を貼り付けるのではなく、地理データから生成した SVG パスを使用しています。
src/lib/geo/prefecture-paths.json — 47都道府県の輪郭(scripts/build-prefecture-paths.mjs で生成)src/lib/geo/map-insets.json — 離島を寄せて描く枠(同スクリプトで生成)src/lib/geo/municipalities.json — 全国 1,894 件の市区町村マスタ(scripts/build-municipalities.mjs で生成)src/lib/geo/municipality-paths/{都道府県コード}.json — 市区町村の境界(scripts/build-municipality-paths.mjs で生成)src/lib/geo/regions.ts — 8地方の区分政令指定都市の区と東京23区も、それぞれ独立した地域選択の単位として扱っています。
地図の塗り分けは縮尺によって異なります。
| 地図 | 塗り分け |
|---|---|
| 日本地図・地方地図 | 未訪問 / 訪問済みの2段階 |
| 都道府県地図・エリア地図 | 訪問回数に応じた5段階(shadeLevel() が 0〜4 を返します) |
本土から離れた島(沖縄本島・先島諸島・大東諸島・小笠原諸島)は、そのままの位置に描くと
地図が横に広がって本土が小さくなるため、破線の枠に入れて海の余白へ寄せています
(src/lib/geo/map-insets.json。画面にも注記を出しています)。
奄美群島と伊豆諸島は実際の位置に描いています。
生成スクリプトの再実行例:
node scripts/build-prefecture-paths.mjs path/to/japan.geojson src/lib/geo
node scripts/build-municipalities.mjs path/to/latest.csv src/lib/geo/municipalities.json
node scripts/build-municipality-paths.mjs path/to/N03-21_210101.json src/lib/geo/municipality-paths
出典データ
japan.geojson市区町村の境界は都道府県ごとにファイルを分け、開いている県の分だけを サーバー側で読み込みます(全国で約2MB。端末へは表示中の県の分だけが届きます)。
記録の置き場所はひとつだけで、ホームと記録画面の上に名前が出ます。
既定は「自分の旅」で、マイページ →「プロフィールを編集」→「自分の旅の名前」から
変更できます(profiles.space_name。空にすると既定へ戻ります)。
旅行(trips)は、日程のある旅をまとめたいときだけ作るものです。
訪問記録は必ずどれかの旅行に属し、旅行を1つも持っていない利用者には
「自分のおでかけ」が自動で1件だけ作られます。
おでかけレベル(EXP)とは別に、コインがたまります。もらえるのは次の2つです。
| もらい方 | 量 |
|---|---|
| レベルアップ報酬(到達レベルごとに1回) | Lv.2〜5 は100枚 / Lv.6〜10 は150枚 / Lv.11〜15 は200枚 / Lv.16〜20 は250枚 / Lv.21〜25 は300枚 / Lv.26〜29 は400枚 / Lv.30 は1,000枚 |
| 歩数報酬(1日ごと・最大70枚) | 3,000歩で10枚、5,000歩で+10枚、8,000歩で+15枚、10,000歩で+15枚、15,000歩で+20枚 |
/mypage/coins)が開き、
所持コイン・着せ替えプレビュー・コインの使い道(ガチャ/ショップ)・もらい方・履歴が並びます。coin_events と残高 user_coins に保存します。
付与キー(level:{レベル} / steps:{日付})で重複付与を防ぎ、歩数は同じ日の差分だけ動きます。src/lib/coins.ts と supabase/migrations/0011_odekake_coins.sql の両方に書いてあります。
変えるときは必ず両方を揃えてください。Lv.2〜30のレベルアップ報酬(src/lib/exp.ts の LEVEL_REWARDS)のうち、
種類が accessory(首輪・バンダナ・帽子・リュック・クラウン)と title(称号)のものは、
/mypage/gear(「そうび」画面)でいつでも見返して、装着・解除できます。
supabase/migrations/0012_user_equipment.sql の set_equipped_item()
(SECURITY DEFINER の RPC)が行い、そのレベルに到達していない報酬は装着できません。kind: "motion" | "expression")は装着の操作なしに、解放済みならおさんぽ中の
フレブルが自動で使います。お部屋(kind: "room")は今後のお部屋づくり機能で使う想定で、
いまは一覧に出るだけです。主なテーブルは profiles / trips / spots / visit_records / visit_photos /
categories / tags / visit_record_tags です。
記録はすべて非公開で、Row Level Security により利用者ごとに分離しています。
ポリシー内の再帰を避けるため、権限判定は can_access_trip() / is_trip_owner() /
can_read_visit() / can_read_spot() の SECURITY DEFINER 関数に集約しています。
Supabase Storage の非公開バケット photos に保存します。
tmp/{user_id}/{下書きID}/ ← 保存前(一時領域)
users/{user_id}/profile/
trips/{trip_id}/cover/
trips/{trip_id}/visits/{visit_record_id}/
写真は保存ボタンを押す前にアップロードするため、いったん一時領域へ置き、 保存時に本来の場所へ移します。保存せずに画面を離れた写真は一時領域に残るだけで、 12時間を過ぎたものはアプリ起動時(1日1回)にまとめて削除します。
src/lib/errors.ts)。localStorage に下書き保存し、画面を閉じても復元できます。
文字の入力欄は FormDraft が DOM から復元し、場所・評価・写真のように React 側が
値を持つ入力は各コンポーネントが自分で保存します(useDraftState)。仕様書で「後回しでもよい」とされている項目は未実装です。
src/lib/places/ に提供元を足せば有効になります)直近の変更内容は docs/changes-6.md と
docs/changes-5.md に、
そのほかの制限事項は docs/notes.md にまとめています。