はじめに
いくつか家計簿アプリを試していたんですが、どれも「あと一歩」が足りず、結局長続きしませんでした。
特にSuicaまわりとクレジットカードの扱いがしっくり来なくて、
「これ自分の使い方に合わせて作った方が早いのでは?」と思い、Next.js + Supabaseで一から作ることにしました。
実装はかなりの部分をClaudeに手伝ってもらっていますが、設計や細かい挙動は自分で詰めています。
既存アプリでハマったポイント
モバイルSuicaの入力がだるい
電車に乗るたびに履歴を手で入力するの、最初の数日でやめました。
とはいえiPhoneだとSuicaの利用履歴を自動取得するのは難しく、
「完全自動は無理でも、せめて楽にはしたい」という状態でした。
クレジットカードのズレ問題
これが一番ストレスでした。
- 購入日で記録 → 残高とズレる
- 引落日で記録 → いつ使ったか分からない
どっちに寄せても気持ち悪い。
「発生」と「支払い」を分けて扱わないとダメだな、という結論に至りました。
混合買い物のモヤモヤ
スーパーで色々まとめて買ったとき、
食費?日用品?全部食費でいいのか…?
みたいな状態になりがちで、毎回ちょっと気持ち悪かったです。
どういう仕様にしたか
こんな感じで割り切りました。
| やりたいこと | 方針 |
|---|---|
| Suicaの入力を楽にする | コピペでまとめて取り込み → あとは自動処理 |
| クレカのズレ解消 | 購入日で計上 + 引落予定を別管理 |
| 混合買い物 | 1取引を複数カテゴリに分割 |
| どこでも使いたい | Webアプリ + PWA |
「完全自動」よりも現実的に続くラインを優先しています。
技術スタック
個人開発なので「楽」と「無料」を重視しました。
| 技術 | |
|---|---|
| フロント | Next.js 15 / Tailwind CSS |
| DB | Supabase(PostgreSQL) |
| ホスティング | Vercel |
Firebaseにするかは結構迷ったんですが、
- リレーショナルでちゃんと組みたかった
- SQLを直接触りたかった
という理由でSupabaseにしています。
この構成だと今のところ完全無料で動いてます。
データ設計(ここが一番大事)
今回の肝はここです。
「1取引 = 1カテゴリ」をやめて、分割できるようにしました。
transactions(取引)
└── transaction_splits(内訳)
└── categories(カテゴリ)
credit_liabilities(引落予定)
└── cards(カード)
例えば:
イオンで ¥4,500
これを
- 食費 ¥2,800
- 日用品 ¥1,200
- 趣味 ¥500
みたいに分けて持てるようにしています。
これだけで「混ざってる問題」はほぼ解決しました。
実装で工夫したところ
Suica取込(半自動)
完全自動は諦めて、こうしました:
履歴をコピー → 貼り付け
↓
あとは全部自動処理
内部では:
- 種別判定(電車 / バス / 物販 / チャージ)
- カテゴリ自動割り当て
- チャージはスキップ
をやっています。
「週1でコピペするだけ」なので、かなり現実的になりました。
クレジットカードの扱い
発生と支払いを分けて管理しています。
- 購入時 → 支出として記録
- 同時に → 「引落予定」を生成
さらに:
- 引落日を自動計算(例:翌月○日)
- 土日なら前営業日に調整
- 起動時に自動精算
このあたりは地味ですが、かなり効いてます。
PWA対応
これはかなり簡単でした。
app/manifest.tsを置くだけで、iPhoneのホーム画面に追加できます。
見た目もほぼネイティブアプリになるので、普通に使いやすいです。
できるようになったこと
・収支の登録 / 編集 / 削除
・1取引の分割入力
・日別 / 月別の一覧
・クレジットカード管理
・引落予定の自動処理
・Suica履歴の取り込み
・レポート表示
・PWA対応
・無料運用
必要なものは一通り揃いました。
作ってみて思ったこと
実装自体はかなりClaudeに任せています。
ただ、
- データ構造どうするか
- どこで責務分けるか
- どういう体験にするか
このあたりは普通に人間が考えないと破綻します。
「コードを書くコスト」は減ったけど、
「設計の重要度」はむしろ上がった感覚があります。
おわりに
既存サービスに合わせるより、
自分の使い方に合わせて作った方がストレスがない、というのは実感しました。
まだ使いながら細かい違和感は出てきそうなので、
その都度ゆるく改善していく予定です。
同じように「家計簿アプリ微妙に合わないな…」と思っている人の参考になれば嬉しいです。