Hosokawa Lab
HomeAboutSkillsLogProjectsBlogContactLogin
Projects
Project

やりくり献立

2026-09-255 min read
ExpoReact NativeTypeScriptSupabaseTanStack Query
サイトを見る

概要

1週間の献立計画、買い物リスト、レシピ、食材の在庫をまとめて管理するアプリです。設計・実装からApple審査への提出、公開までを1人で行いました。

App Storeで公開中:やりくり献立

技術スタック

レイヤー技術
フレームワークExpo SDK 57 / React Native 0.86 / React 19.2
言語TypeScript 6(strict)
ルーティングExpo Router(ファイルベース、Typed Routes、NativeTabs)
コンパイラReact Compiler
サーバー状態管理TanStack Query v5
BaaSSupabase(Auth / Postgres / RLS / Edge Functions)
サーバーレスSupabase Edge Functions(Deno)
アニメーションReanimated 4 + Worklets
ネイティブAPIexpo-secure-store, expo-haptics, expo-image, expo-symbols (SF Symbols), expo-glass-effect
暗号化aes-js(AES-256-CTR)+ react-native-get-random-values
ビルド・配信Xcode(Mac上でローカルビルド)→ App Store Connect
静的解析ESLint 9(eslint-config-expo)

App Storeで公開済み

Tip

試作で終わらせず、App Storeの審査を通して公開しました。ネイティブプロジェクトをXcodeで直接ビルドし、署名・Archive・アップロードまで自分で行っています。

審査の要件にも対応しています。

  • アプリ内からアカウントを削除できる
  • 権限の利用目的(ローカルネットワークなど)を日本語で説明

セキュリティを意識した設計

  • セッションの暗号化保存:SecureStoreは1値2048バイトまでの制限があり、Supabaseのセッションはそれを超えます。そこでAES-256の鍵だけをKeychainに置き、暗号化したセッションをAsyncStorageに保存しています。
  • 全テーブルにRLSを設定:user_id = auth.uid() を条件に、select/insert/update/deleteのポリシーを1つずつ定義しています。
  • アカウント削除はEdge Functionで実行:service roleキーはアプリに含めず、サーバー側で利用者本人のJWTを確認してから削除します。関連データは on delete cascade でまとめて消えます。

使い始めやすい認証の流れ

  • ゲストとして開始(Anonymous Sign-In)でき、あとからメールアドレスを紐づけて本登録できます。
  • アプリがフォアグラウンドに戻ったときにセッションを更新し、JWT関連の問題を防いでいます。
  • ディープリンク(kitchenjournal://)でメール確認後にアプリへ戻ります。

独自のドメインロジック

  • 食材の使い回しスコア:今週の献立ですでに使っている食材を多く含むレシピを優先し、食材を余らせにくくします。
  • 賞味期限アラート:期限3日以内の在庫を警告し、その食材を使うレシピを提示します。
  • 材料費の見積もり・予算管理:在庫の単価から原価を推定し、月の予算内に収まるように管理できます。
  • 買い物リストの自動集計、YouTubeレシピのサムネイル表示も備えています。

保守しやすい構成

  • 機能ごとに分割(features/{meal-plan,recipes,inventory,shopping,settings})。各機能はSupabaseとの通信(api.ts)、Queryフック(use-*.ts)、型、純粋関数のロジックに分かれています。
  • Route Groupsの (auth) と (app) で、未ログイン時とログイン後の画面を分けています。
  • DBの変更はSQLマイグレーションで管理しています。

ネイティブらしいUI/UX

  • NativeTabsで本物のネイティブタブバーを使い、SF Symbolsを表示。
  • iOSではPlatformColor(UIKitのセマンティックカラー)を使用。
  • ハプティクスや borderCurve: 'continuous' など、細部までAppleのヒューマンインターフェースガイドラインに沿った作り込みをしています。