紹介
2020年から、タテカリという割り勘アプリを運営しています。
グループ間で、だれがだれに、いくら支払ったかを記録して、最後に一括で最適な精算方法を計算するWebアプリです。
似たような割り勘アプリは多く存在しますが、タテカリでは特に
- スマホ一画面で全体が把握できること
- ページ遷移なしで入力・確認が完結すること
- LINEで簡単に共有ができること
を重視して設計しています。
テーマ
この記事では、
- 割り勘アプリの5年間の運用の進捗
- 生成AI(Copilot / Claude)を導入して変わった開発スタイルと紛れ込んだバグ
について、実際のコードとともに紹介します。
個人開発でWebサービスを運用している方の参考になれば幸いです。
特に2025年以降はClaude Codeを導入したことで、
- Core Web Vitals改善の実装 (表示時間を早くするなど)
- Content Layout Shiftの改善 (画面表示後に一瞬レイアウトがずれること)
- SEOメタタグの整備
- sitemap生成
- ロゴ、フォントなどデザインの改善
などの開発速度が大きく向上しました。
割り勘アプリの5年間の開発過程
2020年からのGitコミットログから、主要な変更点と時期を簡潔にまとめました。
(CodeXに、過去のコミットから主要な変更履歴を列挙してもらったものを編集しています。とても便利)
| 時期 | カテゴリ | 変更内容 |
|---|---|---|
| 2020年 | Core機能 | 割り勘記録・精算計算などの基本機能を実装 |
| 2023年12月 | 開発体制 | Github Copilot導入(まだ大半は手動実装)。個人ごとの支出合計表示機能を追加 |
| 2024年1月 | UI/UX | フォントカラー・ロゴ更新、input type="number"導入による入力UX改善 |
| 2025年1月 | SEO・機能 | Claude導入。Sitemap.xml追加、トップページ軽量化、LINE共有機能追加 |
| 2025年2月 | パフォーマンス | Lazy Load導入、画像サイズ明示によるCore Web Vitals改善 |
| 2025年9月 | 機能追加 | 過去のグループページ閲覧機能を追加 |
| 2025年11月 | 機能追加 | 支払い記録の編集機能を追加 |
| 2025年12月 | UI/UX・SEO | レイアウトシフト削減、コントラスト改善、34通貨対応、コピー機能追加、ブログ展開開始 |
2020年からの月毎のコミット数。生成AIにかなり助けられているのがわかります。
AIでうまくいったこと
特にAIの恩恵を受けた開発内容はここでしょうか。
- 画像の遅延読み込み
- 通貨の拡充
- フォントカラーの一括調整
人間の思い描く新しい機能を作るよりは、既存のコードを横展開する方向、一括編集が得意なように思います。
AIでうまくいかなかったこと
プロンプト次第で結果が変わりやすい箇所については、何度も修正のやりとりが必要でした。
AIの変更の中で、致命的なミスをいくつか紹介します。
1. メタタグ構文ミス
やりたかったこと
- SNSでシェアした時に表示される、OGPタグを追加したかった
発生した問題:
- HTML上で、OGPタグとcanonicalリンクの引用符が欠落
- 誤:
<meta property="og:url" content=https://tatekari.site/> - 正:
<meta property="og:url" content="https://tatekari.site/">
この問題は、ブラウザでは問題なく表示されるため気付きにくく、
SNS共有時にのみ不具合として表面化しました。
# 修正前(誤)
html = html.replace(
'<meta property=og:url content=https://tatekari.site/ >',
f'<meta property="og:url" content="{full_url}">'
)
# 修正後(正)
html = html.replace(
'<meta property="og:url" content="https://tatekari.site/">',
f'<meta property="og:url" content="{full_url}">'
)
2. tatekari.site/en// という謎ページの生成
やりたかったこと
SEO施策として、例えばtatekari.siteとtatekari.site/の2つを作るのではなく、全てのページにtrailing slash("/")をつけるように統一したかった。
発生した問題
tatekari.site/en//というページができてしまった。
# 修正前
# trailing slash強制のロジック
if original_path != '/' and not original_path.endswith('/'):
new_url = original_path + '/'
return HttpResponsePermanentRedirect(new_url)
# ↑ '/en//' は '/' で終わるのでこのif文に入らない
# 結果:'/en//' がそのまま処理される → 200 OK
# 修正後
ダブルスラッシュを検出して正規化するロジックを追加:
# Normalize double slashes (e.g., /en// -> /en/)
if '//' in original_path:
normalized_path = '/' + '/'.join(filter(None, original_path.split('/'))) + '/'
if normalized_path == '//':
normalized_path = '/'
# Preserve query parameters
if request.GET:
normalized_path += f"?{request.GET.urlencode()}"
return HttpResponsePermanentRedirect(normalized_path)
実際は if normalized_path == '//'という条件式を使っていることで、スパゲッティコードの様相を呈していますが、まずは動くバージョンを作ることを優先し、このままデプロイしました。
Claude Codeを使っていてもsyntax errorは発生しうるし、明示的にinstructionを与えないと簡単にスパゲッティコードを生成してしまうようです。
学び
生成AIは非常に強力な開発補助ツールですが、
- syntax errorを含むコードを生成することがある
- 最終的な品質は開発者のレビューに依存する
ということを、月並みですが、実感しました。
個人開発においては、完璧さよりも継続的な改善の方が重要と考えています。
とても早くリリースをするというスタイルには生成AIはとても合っているので、状況に応じて技術的負債も受け入れる必要があるのではないかとも思います。
今後もタテカリの改善を続けていきたいと思います。


