はじめに
2026年3月、GDG on Campus(Google Developer Group on Campus)のハッカソンに参加しました。
チーム3人で約1週間、在庫管理×家計簿Webアプリ 「俺金欠」 を開発した記録です。

リンク
どんなアプリを作ったか
「また同じもの買ってきちゃった…」
家族や同居人と暮らしていると、誰もが経験するこの問題。
冷蔵庫にもう牛乳があるのに買ってきてしまう。
洗剤がまだあるのに「なくなりそうだった気がする」で2本目を買ってしまう。
俺金欠は、グループ内で購入した商品・在庫をリアルタイムに共有し、二重買いをなくすことを目指した在庫管理×家計簿アプリです。
主な機能
- グループ在庫管理: 冷蔵庫・パントリー・洗面所など保管場所ごとに在庫を整理・共有
- AI自動タグ付け(Gemini搭載): 商品画像やテキストからAIが検索用タグを自動生成、カテゴリも提案
- 家計簿機能: 購入記録から月次支出を自動集計、カテゴリ別・メンバー別の支出をグラフで可視化
- 在庫アラート: 残量が少ない商品を検出し、買い忘れを防止
- 招待コードによるグループ管理: 承認制メンバー管理でセキュアに運用
チーム体制
| メンバー | 担当 |
|---|---|
| バックエンド担当 (私) | API設計・DB設計・インフラ・AI連携・Docker運用 |
| フロントエンド担当 ×2 | React + TypeScript によるSPA開発・UI/UXデザイン |
計 3名 。バックエンド1人、フロントエンド2人という構成でした。
しかし終盤になって フロント・バック間でAPIエンドポイントの認識がずれており その修正でバックの私もフロントエンドにかなり手を加えました。
技術スタック
| レイヤー | 選定技術 |
|---|---|
| フロントエンド | React 19 + TypeScript 5.9 + Vite 6 + MUI 7 + Tailwind CSS 4 |
| バックエンド | Go 1.25 + Gin + GORM |
| データベース | MySQL 8.0(本番)/ SQLite(開発) |
| AI | Google Gemini API |
| セキュリティ | JWT認証 + Cloudflare Turnstile |
| インフラ | Docker on LXD、running on GCE |
GDGのイベントということもあり、Googleエコシステムの活用が推奨されていた ためAIには Google Gemini を採用し、インフラには Google CloudのVM であるGCEを利用しました。
gemini-3.1-flash-lite-previewという最近出たばっかりのモデルを使ってました…!
開発タイムライン
Day 1(3/14)— 設計とプロジェクト始動
初日は仕様書の作成からスタート。
バックエンド・フロントエンドそれぞれの仕様書を書き起こし、API設計とDB設計を固めました。
この段階ではプロダクト名は 「KaiMono」 で、リポジトリ名は 「icetea」 でした。
プロダクト名もリポジトリ名も仮のものなので何でもよかったのですが、メンバーがアイスティーが好きらしいのでじゃあiceteaでいいか、となりました。シンプル。
仕様書案を作成 → フロントの仕様書を作成 → 脆弱性対策で仕様を変更
初日のうちに フロントエンドの初期構築 (init_front)と バックエンドのベース も完成。
Day 2〜5(3/15〜3/19)— 機能実装の怒涛
コア機能を一気に実装していった期間です。
- 在庫のCRUD、購入・消費記録
- グループ管理・メンバー招待
- JAN検索API(楽天API)の連携
- Tailwind CSSへの移行
- AIタグ生成・カテゴリ提案(Gemini連携)
ここでの一番の苦労は フロントエンドとバックエンドのAPI接合 でした。双方の認識合わせに苦心しました。
JAN検索APIは使う方向でしたが 終盤時間が足りなかったため断念 しました…
バーコードを読み取ると自動で商品情報を入力する ような機能を実装しようとしていました。
Day 6(3/20)— UI大改修とマージ地獄
フロントチームの UIの大幅な刷新 (feature/niceUIブランチ)をマージ。
ホーム画面を一新し、ランディングページも整備。
しかし、ここで ブランチ間のコンフリクトが多発 し、「危ういので一旦」というコミットで緊急退避する場面も。
GitHub CopilotにもPRを出してもらい、自動修正を活用しました。
Day 7(3/21)— 最終日の怒涛の追い込み
最終日は1日で 20コミット以上 を積み上げる怒涛のラストスパート。
- プロダクト名を「KaiMono」から 「俺金欠」 に正式リネーム
- ランディングページに「お金の天使」アニメーションを追加
- AGPL-3.0ライセンス表記をフッターに追加
- ロゴがファミレスの看板みたいにくるくる回る機能を実装
- ロゴクリックで パチンコ確変演出 が発動する隠し機能を実装
- 光過敏性への配慮として警告ダイアログを追加
- 確変演出にお金の天使を左右に2体配置
- Cloudflare Turnstileによるボット対策を導入
- 在庫の低在庫しきい値管理を追加
- セキュアCookieの設定を整備
- README.mdの作成とスクリーンショットの追加
「俺金欠」という名前は最終日に思いつきました。
ドメインの取得日を見てもおわかりいただけるかと思います。
インフラ運用について
インフラ運用については、先程紹介した通り Docker on LXD でGCE上で運用していました。リージョンは 大阪リージョン でした。
なぜLXDにしたのか
ハッカソン当日の発表中、LXDについて少し言及していると多くの方が興味深そうに聞いていたことが印象に残っています。
LXDはDockerやKubernetesといった主流のコンテナ技術と比べると知名度が低いため、初耳の方が多かったのではと思います。
LXDは コンテナと仮想マシンの良いとこ取り をしたような技術です。
Dockerは アプリケーション単位 でコンテナを起動しますが、LXDは OS単位 でコンテナを起動します。
そのため、Dockerよりも多くのリソースを消費しますが、その分多くの機能を利用できます。
厳密な例えではありませんが、初心者向けに言うとVPSの上でまた複数のVPSを運用するイメージです。
しかもメモリやリソースは基本各々のコンテナで配分などを考えずに合計でホストが出せる分まで使えるので、柔軟に運用できます。
また移行についてもlxc moveコマンドですぐできます。
私はハッカソンで開発したものであっても、来年参加する人の参考になればいいと思い 極力長く公開する という方針です。
ハッカソンの終了後一段階ついたら既存で運用しているVPSに移行する予定でした。
私は自鯖サービスは全てLXDで運用しているためちょうど都合もよかったです。
移行予定のVPSは書いていないのですが、当方が運用しているインフラについてはこちらにまとめています。
当サイトの運用インフラ構成図
当サイトはニューヨーク・バッファローの1Uサーバで動いています😊
そのため、LXDだと ホスト間でコンテナをスムーズに移行できる かつ上記のような柔軟性もあるため採用しました。
なぜこんな名前にしたのか…?
ハッカソン当日にも質問いただきました。
これも理由はシンプルで、メンバーで名前を考えている時に「ドメイン取らんとあかんな〜、最近円安やしきついな」と思っていて、私が唐突に「俺金欠」と発言しました。
何を思ったのか覚えやすい名前なのでこれでいいじゃんと即決になりました。
当Webアプリは節約や効率化を目的としていますし、名前もシンプルで覚えやすい!となりあっさり俺金欠に決定しました笑
俺金欠という名前でバカ真面目なデザインにするのはかえって不自然と考え、最終日に 遊び感を持たせたデザイン にしました。
ドメイン取得代は俺持ちなのでまじで金欠でした笑
スライドも かなり派手 でした。
他のチームの発表も見ていましたが思ったより異色感が際立ちました。
スライド案を数個作ってその中でメンバーで投票したのですが、私以外全員賛成 だったのでこちらのスライドになりました…
もともとチーム内のノリで作ったスライドでしたが印象には残りやすいものでした。

技術的に面白かったポイント
1. Gemini APIによるAI自動タグ付け
在庫を追加するとき、商品名や画像をGemini APIに投げて 検索用タグを自動生成 する仕組みを実装しました。
さらに カテゴリ提案 もAIが行い、ユーザーの入力負荷を大幅に軽減。
ストリーミングレスポンス にも対応し、AIの応答をリアルタイムで表示できるようにしました。
2. マルチバックエンド対応のファイルストア
ファイルアップロードのバックエンドを、ローカルファイルシステム・AWS S3・Google Cloud Storage の3種類から切り替え可能に設計。
filestoreパッケージとしてインターフェースを切り、環境変数一つで切り替えられる ようにしました。
3. JWT認証のリフレッシュトークン設計
アクセストークン(15分)+ リフレッシュトークン(168時間) の2段階認証を実装。
リフレッシュトークンは HttpOnly Cookie に格納し、XSS攻撃からの保護を実現しました。
4. 確変演出(イースターエッグ)
最終日Code Freeze(提出期限)に追い詰められ、何を思ったのかロゴをクリックするとパチンコの確変演出が始まるという機能を実装しました。
天使を触ると「コケコッコー」と吹き出しが出るよう謎の実装したのもこの頃でした。
光過敏性てんかんへの配慮として事前に警告ダイアログを表示するという、妙にしっかりした作りになっています。
実際もっと凝りたかったとは思っていますが、警告ダイアログを表示しても目が敏感な方などがどうなるかなどに配慮する必要があると考え、この程度に留めました。
利用した音源は 「P牙狼GOLD IMPACT」のBATTLE BONUS 3000獲得音 です。
私はパチンコをやった事が一度もないのですが、こちらの音源はメーカー様が商用・非商用を問わず利用してよい旨公開されていたため利用しました。
この場をお借りして株式会社サンセイアールアンドディ様に感謝申し上げます。
ダウンロードリンクはこちらになります。
苦労した点・反省点
フロントとバックの連携
チーム内でバックエンド1人・フロントエンド2人という構成だったため、API仕様の認識齟齬が何度か発生しました。。
API仕様書を先にしっかり書いておいたものの、実装段階で齟齬が出るという、あるあるな問題に直面しました。
フロントエンド・バックエンド共に1週間で完成度の高いWebアプリを開発するべく AIにも頼っていました 。
私自身バイト等で忙しく、またメンバー1人が初期から体調を崩し開発ができず、終盤AIによるpushを連発していました。
確認漏れがあったと反省しています。
ブランチ管理の混乱
最終日に向けてブランチが乱立し、マージコンフリクトの解消に時間を取られました。
少人数チームでもブランチ戦略は重要 だと痛感しました。
最終日にはコンフリクトが起きないよう僕一人でdevelopに直pushしていました。
時間に余裕を持って開発するべきだったと思っています。
時間配分
確変演出に思った以上の時間を使ってしまいました(光過敏性対策まで含めて 計8コミット )。
楽しかったので後悔はしていません。
コミットが汚い
前述通り。
数字で振り返る
| 項目 | 数値 |
|---|---|
| 開発期間 | 約1週間 |
| 総コミット数 | 144 |
| コントリビューター | 3名 |
| バックエンドのハンドラー数 | 17ファイル |
| フロントエンドのページ数 | 約20ページ |
| APIエンドポイント数 | 30以上 |
| 最終日のコミット数 | 20+ |
おわりに
1週間 という短い期間でしたが、Go + React + Gemini AI という技術スタックで、在庫管理・家計簿・AI自動タグ付けまで盛り込んだ フルスタックアプリを完成 させることができました。
最終日の怒涛の追い込み(プロダクト名変更→確変演出→セキュリティ強化→README作成を1日でやる)はハッカソンの醍醐味そのものでした。
そして何より、「俺金欠」 というプロダクト名はやはりネーミングセンスが良かったと思っています。
在庫管理アプリなのにお金がない感じが全面に出ている。確変演出もある。
矛盾しているようで、「金欠だからこそ二重買いをなくしたい」という切実な動機がこの名前に込められています。
このアプリは GNU Affero General Public License v3.0 で公開しました。