TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
家族の予定・リスト・育児をまとめて管理するアプリ
Translation pending
ProductivityTypeScript · PLpgSQLGitHub @daizoooOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
夫婦で育児タスク・記録・スケジュールを共有するWebアプリケーション。 • フロントエンド: Next.js (App Router) + React + TypeScript • スタイリング: Tailwind CSS • UI/アイコン/グラフ: lucide-react, recharts • バックエンド/DB: Supabase (PostgreSQL, Auth, Storage) • ホスティング: Vercel 詳細な設計方針は基本設計書を参照してください。 http://localhost:3000 を開くとアプリが表示されます。Read the full README ↗
夫婦で育児タスク・記録・スケジュールを共有するWebアプリケーション。
詳細な設計方針は基本設計書を参照してください。
npm install
cp .env.local.example .env.local
# .env.local に Supabase の値を設定
npm run dev
http://localhost:3000 を開くとアプリが表示されます。
.env.local)| 変数名 | 用途 |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabaseプロジェクトの URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabaseの公開anonキー |
src/
app/
page.tsx # トップページ(SukusukuAppを読み込み)
login/ # ログイン・サインアップ画面
family-setup/ # 家族の作成・招待コード参加画面
auth/confirm/ # メール確認リンクのコールバック
components/sukusuku/
SukusukuApp.tsx # アプリ本体(状態管理・タブ/モーダルの組み立て)
tabs/ # ホーム/予定/記録/保活/設定の各タブ
modals/ # タスク追加・詳細の各モーダル
lib/
dateUtils.ts / uiUtils.ts / seedData.ts
nursingTimer.ts # 母乳の左右別ストップウォッチ + 経過時間のお知らせ
feedingSchedule.ts # 次の授乳の目安(前回の授乳 + 間隔)の計算
alarm.ts # ビープ音の合成・バイブ・画面スリープ抑止のラッパー
supabase/client.ts # ブラウザ用Supabaseクライアント
supabase/server.ts # サーバー用Supabaseクライアント
types/app.ts # ドメイン型定義
supabase/migrations/
0001_init_schema.sql # テーブル定義 + RLSポリシー
0002_storage.sql # 書類箱用Storageバケット + ポリシー
0010_calendar_fields.sql # カレンダー用カラム(日付・時刻・ラベル・リマインダー)
src/types/supabase.ts)/login, /family-setup)記録タブで残せるのはミルク(授乳)・おむつ・搾乳の3つ。
飲ませる量は「どの搾乳を使ったか」で決まるため、残量を1つの数字で持たず、ためた搾乳を 1パックずつ持つ。ミルクの記録で「搾乳」を選ぶと、まだ使っていないパックの一覧から使うものを 選び、選んだパックの合計がそのまま記録する量になる。
details.pumpedFrom に搾乳の記録のid)。
搾乳の記録そのものは書き換えないので、授乳の記録を消せばその搾乳はストックに戻る。care_logs の type = 'pumping'(ためた分)と
type = 'milk' かつ details.method = 'pumped'(飲ませた分)で表す。睡眠(ねんね計測)の記録は取り止めた。すでに保存されている type = 'sleep' の行は
DBに残したまま、アプリ側では取得しない。
授乳中は手が離せず画面を見られないため、母乳の左右別ストップウォッチ
(src/lib/nursingTimer.ts)に、一定間隔で音とバイブを鳴らす仕組みを載せている。
画面を狭くしないよう、間隔・音・バイブを切り替える表示は記録画面から外してあり、
端末に控えてある設定(なければ既定の5分間隔・音とバイブON)でそのまま鳴る。
unlockAudio() を呼んでいる。navigator.vibrate。iOS Safariは非対応なのでボタンを無効化し、音でお知らせする。
ブラウザは画面が消えている/裏に回っている間の振動要求を無視するため、鳴らし損ねた分は
控えておき、アプリに戻ってきた時点(visibilitychange)で振動させ直す。
ユーザー操作起点で鳴らすときは、音の準備を待つ前に先に振動させる。setInterval)で動かし、SukusukuApp から
useNursingAlarmWatcher() で起動する。記録タブを開いていなくても鳴り、読み込み直後に
計測が残っていた場合も再開する。画面を消している間はサーバーから鳴らす。 上の回避策を重ねてもなお、画面が消えている・
アプリを閉じている間は端末内のタイマーだけでは鳴らせない(iPhoneは振動もできない)。
そこで鳴らす基準を nursing_alarms に預けておき、端末が鳴らせなかった分を
Edge Function send-nursing-alarms が Web Push で鳴らす。計測そのものは今までどおり
端末内で完結していて、預けるのは「いつ・何分ごとに鳴らすか」だけ。
通知をオンにしていない端末では預け先が無いので、これまでどおり端末内でだけ鳴る。
→ docs/notifications.md
授乳が終わったころには次が何時だったか分からなくなり、夫婦で「次はいつだっけ?」と 確かめ合うことになる。前回の授乳の記録から一定の間隔をおいた時刻を「次の目安」として 画面に出し、その時刻に通知する。
NextFeedingCard)。目安の時刻・残り時間・
前回からの進み具合のバー・前回の時刻を1枚にまとめている。ホームのカードはタップすると
記録タブへ移る。type = 'pumping')は飲ませた記録ではないので数えない。feeding_settings)。夫婦で違う目安が出ては意味がないため。
設定タブで2〜4時間を30分刻みで選ぶ。既定は3時間。listRecentMilkLogs)。パートナーの端末で記録された分を拾えるよう、
アプリに戻ってきた時点(visibilitychange)で取り直す。目安の時刻に通知する。 家族のうち通知をオンにしている端末すべてへ、
Edge Function send-feeding-reminders が Web Push で送る(設定でオフにできる。
オフにしても画面の表示は出る)。定期実行が1分おきなので、目安の時刻と同じ分のうちに届く。
授乳中(母乳のストップウォッチを計測中)の家族には送らない。記録は授乳が終わってから
保存されるため、飲ませている最中に「そろそろ次の授乳」が届いてしまうのを避けている。
→ docs/notifications.md
src/proxy.ts(Next.js 16のmiddlewareはproxyに名称変更): 未ログイン時は/loginへ、family_id未設定時は/family-setupへリダイレクト/login: メール/パスワードでのサインアップ・ログイン(Supabase Auth)/family-setup: 家族の新規作成(familiesにINSERT→自分のusers.family_idを更新→定番ToDoを一括投入)、または招待コード(家族のUUID)を入力して既存家族に参加src/lib/api/tasks.ts: tasksテーブルのCRUDとDB行⇔アプリ型のマッピング。SukusukuAppから呼び出し、楽観的UI更新+失敗時ロールバックを行うsrc/lib/api/account.ts: usersテーブルのうち自分の役割(パパ/ママ)・表示名の取得と更新auth.usersへのINSERTをトリガーにpublic.usersへ空プロフィール行を自動作成(0005_auth_user_trigger.sql)AccountSection)があり、役割(パパ/ママ)の変更・表示名の変更・招待コードの再確認・ログアウトができる。家族参加時に役割を選び間違えた場合はここで修正するサインアップ確認メールのリンクはSupabaseの/auth/v1/verifyを経由し、そこでメールアドレスの確認が完了してからアプリの/auth/confirmへcode=付きでリダイレクトされます。
codeをセッションに交換する処理(PKCE)には、登録操作を行ったブラウザに保存されたcode_verifierが必要です。そのため、登録した端末と別の端末やメールアプリ内のブラウザでリンクを開くと交換に失敗します。このときメール確認自体は成功しているため、以前は「確認リンクが無効か、有効期限切れです」と表示されるのに登録自体は完了している、という食い違いが起きていました。
現在の/auth/confirmはこの2つを区別します。
| 状況 | 遷移先 | 表示 |
|---|---|---|
| セッション交換に成功 | /(そのままログイン状態) | — |
Supabase側の検証に失敗(error/error_code付き。期限切れ・使用済みリンク) | /login?error=confirm_failed | 「確認リンクが無効か、有効期限切れです」 |
| 検証は成功したがセッション交換に失敗(別ブラウザで開いた等) | /login?message=email_confirmed | 「メールアドレスの確認が完了しました。…ログインしてください」 |
端末をまたいでもそのままログイン状態にしたい場合は、Supabaseダッシュボードの Authentication > Email Templates で確認メールのリンクを
{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email&next=/
に変更してください。token_hash形式はcode_verifierに依存しないverifyOtp()フローを使うため、どの端末で開いてもその場でログイン状態になります(/auth/confirmは両方の形式に対応済み)。
この開発環境(サンドボックス)はネットワークポリシーにより*.supabase.coへの直接アクセスがブロックされているため、ブラウザから実際にサインアップ〜家族作成〜タスク登録までの動作確認は行えていません(npm run build / next lint / tsc --noEmit は通過済み、DBスキーマとRLSポリシーはSupabase側で適用・Advisorでの警告なしを確認済み)。Vercelへのデプロイ後、またはローカル環境(npm run dev)で一度実際にサインアップ〜家族作成〜予定追加の一連の流れをご確認ください。
daizooo / プロジェクト名: sukusuku / リージョン: ap-northeast-1(東京).env.local に設定してくださいsupabase/migrations/ を上から順に適用したものと同一です(apply_migration で反映済み)src/types/supabase.ts はこのプロジェクトから generate_typescript_types で生成した型です。スキーマ変更後は再生成してください
nursing_alarms の型は手で書き足したあと、マイグレーション適用後の再生成結果と
一致することを確認済みですVercel Platform にこのリポジトリを接続し、上記の環境変数を設定してデプロイします。
vercel.json で "regions": ["hnd1"](東京)を指定しています。この設定を外さないでください。
このアプリはミドルウェアとServer Componentの両方からSupabaseへアクセスするため、初回表示あたり
複数回のサーバー→Supabase往復が発生します。Supabaseプロジェクトは ap-northeast-1(東京)にあるため、
Vercel側の実行リージョンが既定の iad1(米国バージニア)のままだと往復1回ごとに太平洋横断の
レイテンシ(RTT 約150〜200ms)が上乗せされ、起動が体感で1秒近く遅くなります。
getUser() ではなく getClaims() を使う。getUser() は毎回Authサーバーへの
ネットワーク往復を伴うが、getClaims() はJWTが非対称鍵で署名されていればWebCrypto+
キャッシュ済みJWKSでローカル検証が完結する(このプロジェクトの署名鍵は ES256)。
getSession() は署名を検証しないため認可判断には使わない。next/dynamic で遅延ロードする。特に LogTab は成長グラフのために
recharts(単体で約350KB)を持ち込むため、静的importに戻すと初期バンドルへ混入する。loading.tsx を置き、サーバー側の認証・プロフィール取得を待つ間も
白画面にならないようにする。mobile/)Expo(React Native)で作り直しているネイティブ版が mobile/ にある(このNext.jsとは独立した
プロジェクト。Vercelは今までどおりルートだけを見る)。進め方は
docs/native-app-rewrite.md、動かし方は
mobile/README.md を参照。