OpenSakura
MekaHime's first AI companion, now open source. 26 emotions, her real voice, real-time replies and memory, running on your own PC. Discord mode coming soon.
吃音を持つ人たちが、弱さや挑戦を分かち合い、吃音を深める小さな村
Translation pending
SocialGitHub @Masahiko-LesOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗吃音を持つ人たちが暮らす、小さなオンラインの村。競争・ランキングを持たず、 弱さや苦労を分かち合うことを中心に置いた MVP です。
既存の「吃音村」DB とは完全に独立した、新しい Supabase プロジェクトを前提としています。
npm install
grant select/insert/... を入れてあるので、ONでもOFFでもどちらでも問題ない)anon public キーservice_role キー — 絶対にブラウザに公開しないこと.env.local.example を .env.local にコピーし、値を埋めてください。
cp .env.local.example .env.local
NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=... # 今回のMVPでは未使用。将来のサーバー専用処理向け
supabase/migrations/ 以下の SQL を、Supabase 管理画面の SQL Editor に
ファイル名の順番通り貼り付けて実行してください(supabase CLI がある場合は
supabase db push でも可)。
| ファイル | 内容 |
|---|---|
20250101000001_extensions.sql | 拡張機能・共通トリガー関数 |
20250101000002_profiles.sql | 住民票(profiles) |
20250101000003_bonfire.sql | 焚き火(bonfire_posts) |
20250101000004_garden.sql | 農園(種・水やり・収穫・作物配布・water_seed RPC) |
20250101000005_shrine.sql | 祠(村の生命力・お供え・make_offering / get_village_status RPC) |
20250101000006_desert.sql | 砂漠(desert_stories) |
20250101000012_crop_gifts.sql | 焚き火での作物ギフト(crop_gifts・gift_crop RPC) |
20250101000014_own_field.sql | 自分の家の畑(garden_seeds.kind・water_own_field_seed RPC) |
20250101000017_desert_bloom.sql | 砂漠の開拓の水やり・開花(desert_waterings・flower_catalog・desert_blooms・user_flowers・water_desert_story RPC) |
20250101000018_library.sql | 図書館(book_catalog・library_reviews・flower_gifts・gift_flower RPC) |
20250101000019_soft_delete_rls_fix.sql | 焚き火・砂漠・図書館の論理削除RLS修正 |
20250101000020_library_book_swap.sql | 図書館の本の入れ替え |
20250101000021_cinema.sql | 映画館(movie_catalog・cinema_reviews・cinema_flower_gifts・gift_flower_to_cinema_review RPC) |
Supabase 管理画面 → Authentication → Email Templates → Confirm signup の
リンクを以下の形式に変更してください(@supabase/ssr を使った Next.js の
標準的な確認フローです)。
{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email&next=/onboarding
開発中にメール確認をスキップしたい場合は、Authentication → Providers → Email の "Confirm email" をオフにしても構いません。
npm run dev
http://localhost:3000 を開いてください。
user_id は auth.users に 1:1。ログイン済みユーザーのみ閲覧可、編集は本人のみ。deleted_at)。kindがcommunityなら苦労を植えた農園の種(status: seed → growing → harvested)、own_fieldなら自分の家の畑で自分の「できたこと」を植えた種(harvest_count・last_watered_dateで1日1回・最大10収穫を管理)。unique(seed_id, user_id) で二重水やりを禁止。直接 INSERT する
RLS ポリシーは存在せず、water_seed() RPC 経由でのみ作成される(own_field は自分専用のためwateringsは使わず、garden_seeds.last_watered_dateで日次制限する)。is_active を切り替えることで後から増減可能。water_seed()内のアプリケーションロジックで保証)、own_field の種は水やりのたびに複数回発生し得るためseed_idはuniqueにしていない。unique(user_id, harvest_id) で二重配布を禁止。offered_at が
埋まっていればお供え済み。経過日数 × daily_vitality_decay を都度計算する方式。unique(user_crop_id) で同じ作物の二重奉納を禁止。status(story → blooming → bloomed)で水やりの進捗を管理する。投稿内容(本文3項目)は本人がいつでも編集可能だが、status/bloomed_at は列レベルの権限制限により water_desert_story() 経由でしか変更できない。unique(story_id, user_id) で二重水やりを禁止。waterings と同型で、water_desert_story() RPC 経由でのみ作成される。crop_catalog と同型。is_active で後から増減可能。harvests と同型で、story_id は一生に1回だけ開花する(water_desert_story() 内のアプリケーションロジックで保証)。すべてのテーブルで RLS を有効化しています。特にゲームの根幹となる処理 (水やり3回での収穫判定・作物のランダム決定・複数人への配布・お供えによる 生命力更新)はフロントエンドに任せず、SECURITY DEFINER の Postgres 関数内で 行 (row) ロックを使い、トランザクションとして原子的に処理しています。
| 関数 | 説明 |
|---|---|
water_seed(p_seed_id uuid) | 指定した種に水をやる。自分の種には不可、二重水やりも DB 制約で禁止。水やりが harvest_water_count 回に達すると、その場でランダムな作物を収穫し、種を植えた人+水をやった全員に配布する。 |
get_current_vitality() | 村の現在の生命力(0〜100)を計算して返す。書き込みはしない。 |
get_village_status() | 生命力を4段階の状態(tier 1〜4)とメッセージに変換して返す。数値自体はクライアントに公開しない。 |
make_offering(p_user_crop_id uuid) | 自分の未奉納の作物を祠にお供えする。現在の生命力を再計算し、offering_recovery を加算して max_vitality でクランプ、その値を新しい基準値として保存する。 |
get_offering_history() | 祠の裏で表示する、全村人のお供え履歴(誰が・何を・いつ)を返す。user_crops は本人しか SELECT できないため、この関数を介さず直接テーブルを結合すると他人の記録が見えなくなる。 |
water_own_field_seed(p_seed_id uuid) | 自分の家の畑で、自分の種に水をやる。植えた当日から1日1回まで。水をやるたびに即座にランダムな作物を1個収穫し、自分だけに配布する。harvest_countが10に達すると、その種は収穫終了になる。 |
gift_crop(p_user_crop_id uuid, p_recipient_id uuid, p_bonfire_post_id uuid) | 自分の未奉納の作物を、焚き火の投稿を通じて他の村人に渡す。user_crops.user_id を書き換えて所有者を移し、crop_gifts に記録を残す。 |
water_desert_story(p_story_id uuid) | 砂漠の記録に水をやる。自分の記録には不可、二重水やりも DB 制約で禁止。harvest_water_count(農園と共通)回に達すると、その場でランダムな花を咲かせ、記録した人+水をやった全員に配布する。 |
gift_flower(p_user_flower_id uuid, p_recipient_id uuid, p_library_review_id uuid) | 自分の花を、図書館の感想を通じて他の村人に渡す。user_flowers.user_id を書き換えて所有者を移し、flower_gifts に記録を残す。 |
gift_flower_to_cinema_review(p_user_flower_id uuid, p_recipient_id uuid, p_cinema_review_id uuid) | 自分の花を、映画館の感想を通じて他の村人に渡す。gift_flower と同じ処理を cinema_flower_gifts に記録する。 |
/ ログイン前トップ
/login ログイン
/signup 新規登録
/onboarding 初回村人登録
/village 村マップ
/town-hall 村役場(自分の住民票・編集リンク・村人一覧リンク)
/town-hall/edit 住民票の編集
/residents 村人一覧
/residents/[id] 住民票(他の村人)
/bonfire 焚き火
/garden 農園
/shrine 祠
/shrine/back 祠の裏(お供え履歴)
/desert 砂漠
/library 図書館(本の一覧)
/library/[id] 本の詳細・感想投稿・花のギフト
/library/[id]/reviews/[id]/edit 感想の編集
/cinema 映画館(映画の一覧)
/cinema/[id] 映画の詳細・感想投稿・花のギフト
/cinema/[id]/reviews/[id]/edit 感想の編集
研究所・掲示板・フォロー・DM・ランキング・いいね・複雑な通知・課金・ Google ログイン・Realtime・高度なアニメーション・管理者画面・AI 機能は 今回のスコープ外です(後から追加できる設計にはしています)。
crop_cataloguser_cropsoffered_atcrop_catalog/flower_catalog と同型。is_active で後から増減可能。bonfire_posts と同型(論理削除)に加えて book_id を持つ。本人はいつでも編集・削除できる。crop_gifts の最終形(harvest_id 相当として bloom_id を持つ)と同じ構造で、誰が・誰に・どの感想を通じて渡したかを記録する。book_catalog と同型。library_reviews と同型(book_id の代わりに movie_id)。本人はいつでも編集・削除できる。flower_gifts と同型(library_review_id の代わりに cinema_review_id)。