📈

PullLogを作った話 – ガチャ履歴を記録・分析するWebアプリとAIエージェント活用開発

に公開

PullLogとは

PullLog は、スマホゲームの ガチャ履歴を記録・分析・共有できるWebアプリ です。
「いつ」「どのくらい」「何を引いたか」を記録し、課金額やレア排出率を自動で集計。さらにSNS用の履歴画像をダウンロードしてシェアすることもできます。

PullLog統計画面

技術スタック

PullLog の構成は以下の通りです。

  • フロントエンド: Nuxt 3 + TailwindCSS + PrimeVue + Chart.js
  • 状態管理: Pinia
  • 日付処理: Luxon
  • バックエンド: Laravel 12 + PostgreSQL 14
  • インフラ: Cloudflare Workers + R2

データベースでは logs テーブルをユーザーごとにハッシュパーティショニングし、大量データの効率的な集計を意識しています。
フロントエンドは SSR/CSR の切り替えや軽量化に気を配りつつ、Chart.js を使った可視化を中心に設計しています。

開発後に直面した課題

PullLog はリリース後も継続的に機能追加や修正を行っていますが、個人開発のため「人手と時間」がボトルネックになります。
特に細かいバグ修正やリファクタリングに追われると、新機能の実装に時間を割けないという課題がありました。

Codexとの協働開発

そこで導入したのが AIエージェント Codex です。
単にコードを自動生成してくれるだけでなく、仕様の曖昧さを徹底的に洗い出してくれる のが特徴です。

実例: CSVインポートの「null」問題

あるとき、CSVインポート機能で「特定の項目が空欄のときに "null" という文字列が入ってしまう」という簡単そうな不具合がありました。
軽微な修正だと思っていたのですが、Codexは次のように問いかけてきました(一部抜粋ではなく、実際のIssueコメント全文です)。

  • 要確認: "null" 判定は大小文字の違い(例: "NULL", "Null")も空として扱うか(現状は「"null" のみ」明示)。
    • 回答: 大小文字の区別はせず、"NULL" も "Null" も空として扱う。
  • 要確認: インポート時に "undefined" のみのセルも空として扱うか(現状指定なし)。
    • 回答: "undefined" (大小文字区別なし)も空として扱う。
  • 要確認: エクスポート時、DB内に既に "null" 文字列がある場合はそのまま出力か、空へ正規化するか(現状はインポート時に空化で良い想定)。
    • 回答: DB内の既存値 "null" についてはそのまま出力で構わない。
  • 要確認: " null " のように前後に空白がある場合も、trim後に "null"/"undefined" 判定して空扱いでよいか。
    • 回答: trim後に "null"/"undefined" 判定して空扱いでよい。
  • 要確認: 往復時の整合性(DBに "null" 文字列がある行をエクスポート→再インポートすると "" に置換される)が許容か。
    • 回答: 許容する。
  • 要確認: クオート方針は「常に全列クオート」か「必要時のみクオート」か(現状は「クオートあり」まで)。
    • 回答: 「常に全列クオート」でOk。
  • 要確認: 行区切りは LF 固定で問題ないか(Windows環境での CRLF 変換を抑止する運用可否)。
    • 回答: 基本的に LF 固定で構わないが、もしエクスポート時にユーザーの環境を判別できるのであれば、Windows環境であればCRLFで、それ以外はLFで出力できると良い。インポート時は改行コードが LF でも CRLF でもどちらでも許可されるようにして欲しい。
  • 要確認: OS判定の方法(クライアント/サーバどちらで判定し、どの閾値でCRLF出力に切替えるかの具体仕様)。
    • 回答: クライアントで判定。ブラウザのUAによるOS判定で構わない。
  • 要確認: OS判定が不能な場合のフォールバック改行コード(LFで問題ないか)。
    • 回答: フォールバックはLFでOk。
  • 要確認: エクスポート処理は常にクライアント側で実行される前提で問題ないか(UA判定のため)。
    • 回答: エクスポートは常にクライアント側で実行される。
  • 要確認: インポート対象のCSVヘッダ順(列順)を固定とするか、ヘッダ名マッチで順不同許容とするか。
    • 回答: ヘッダ順は固定。
  • 要確認: 固定ヘッダ順の正確な並び(仕様書 or 既存エクスポート実装の並びを正とするか)。
    • 回答: 既存エクスポート実装の並びを正とする。
  • 要確認: ヘッダ固定順の厳密な並びリストを明文化するか(コード内定数化)。
    • 回答: コード内定数化をしてください。
  • 要確認: ヘッダ不一致時の挙動(エラーで中断/ユーザー通知の具体メッセージ方針)。
    • 回答: エラーで中断。エラーメッセージは「エクスポートデータの生成に失敗しました」で i18n で多言語化してください。
  • 要確認: ヘッダ不一致エラーの文言はインポート時にも「エクスポートデータの生成に失敗しました」で確定か(「インポートに失敗しました」の方が自然に見えます)。
    • 回答: インポート時のエラーは「インポートに失敗しました」でOk。
  • 要確認: 固定ヘッダ配列の正確な並び(コードに定数として明示します)。
    • 回答: 固定ヘッダ配列の並びは次の通り: [ 'date', 'totalPulls', 'dischargeItems', 'expense', 'dropDetails', 'tags', 'freeText' ]
  • 要確認: trimは判定目的のみで、実際の値は原則として元の空白を保持で良いか。
    • 回答: 実際の値もtrim適用後の文字列でOk。

一見シンプルな不具合修正のはずが、ここまで仕様を掘り下げられるとは思いませんでした。
ただ、そのやり取りを通じて「そうか、ここは明確にしておかないといけなかったんだ」と自分自身の気づきが得られ、最終的に設計の整理につながりました。

AIエージェント導入で得られたこと

  • 仕様の曖昧さを洗い出せる: 人間同士の開発では流されがちな部分を突っ込んでくれる
  • リファクタの信頼性が高まる: 明文化した仕様に基づいて修正が進む
  • 開発者として思考が整理される: 「指示を出す側」としても鍛えられる感覚

PullLog は単なる「ガチャ履歴アプリ」であると同時に、AIを活用した新しい個人開発の実験場 でもあります。

まとめ

  • PullLogは「ガチャ履歴を記録・分析・共有するWebアプリ」
  • Nuxt 3 + Laravel 12 + Cloudflare Workers で構築
  • Codexを導入することで、リリース後の開発効率と品質が大幅に向上
  • 特に「仕様を突き詰める相棒」としてのAI活用は想像以上に効果的だった

もし同じように 個人開発×Webアプリ×AI活用 に関心がある方がいれば、ぜひPullLogやリポジトリを覗いてみてください。

サイト: https://pulllog.net/ja
GitHub: https://github.com/magicmethods/pulllog-frontend

Discussion