※この記事は、Claude Codeで1人開発しているSNS運用SaaS「ThreadPost」の開発日記です。
SNS運用を自動化しませんか?
ThreadPostなら、投稿作成・画像生成・スケジュール管理まで全てAIにお任せ。
核心回答
LINEのメニューボタンを少し見栄え良くする。ただそれだけの簡単なUI修正のつもりだった。気づけば27回のコミットを重ね、配信基盤そのものを丸ごと作り直していた。

泥沼の連鎖と無双の15時間
最初は本当に些細な修正だった。「02:49 - LINEユーザー管理画面のフォロー日時表示改善」から作業を始めた。僕が最初に作ったメニューは3ボタンで、色がバラバラだった。ユーザーが何を押せばいいかわからない状態だ。
Claude Codeにボタンを2つに絞って色を統一するよう指示した。すんなり動くコードが出てきた。ここまでは平和だった。問題は、直すたびに欲が出たことだ。「配信機能もここから繋げたい」と思い始めた。
「13:17 - trigger diagnosis from rich menu instead of auto-send」で自動送信をやめた。診断機能をリッチメニューから起動するように変更した。すると、裏側の配信ロジックが破綻し始めた。
LINEのMessaging APIは、UIとバックエンドが密結合になりやすい。リッチメニューのタップイベントをWebhookで受け取り、状態に応じてメッセージを返し分ける必要がある。気づいたら画像アップロードからセグメント配信まで全部繋がっていた。
「03:19 - LINE配信システムの大幅拡張」で、14種類のセグメント条件を実装した。登録日数、SNS連携状態、ペルソナ作成状態、プラン、投稿実績。これらを組み合わせて配信できるエンジンをゼロから作った。「03:37 - LINE配信機能の拡張(画像アップロード・セグメント条件・Broadcast API対応)」でAPIエンドポイントも一新した。メニュー1個のはずが、配信システム全体を触ることになっていた。
一般的なSaaS企業で14種類のセグメント配信機能を実装するとなれば大仕事だ。要件定義からデータベース設計、バッチ処理の実装まで最低でも2週間はかかる。それを僕は、AIとの壁打ちだけで数時間で組み上げた。
Claude Codeはコードベース全体のコンテキストを保持している。UIの変更に伴うAPIエンドポイントの修正を瞬時に推論する。データベースクエリの最適化も同時に提案してくる。僕の「直したい」がそのままシステム全体を書き換える連鎖を生んだ。
しんたろー:
リッチメニュー直してたはずが、気づいたらインフラエンジニアになってた。14種類のセグメント条件、テストするだけでも気が狂いそう。AIのコード生成速度に人間の確認作業が追いついてない。
ただ、無双状態には必ず代償がある。セグメント条件を複雑にするほど、クエリの実行計画が重くなる。LINEのBroadcast APIは、対象者が0人のセグメントに配信リクエストを送るとエラーを返す。このエラーハンドリングを忘れると、配信キュー全体が詰まる。
「14:42 - LINE通知テンプレート改善 & ぽすたまタウン招待通知追加」でテンプレートを整理した。見た目は完璧になった。だが、裏側のロジックは肥大化し、爆弾を抱えた状態になっていた。「11:33 - Add comprehensive notification logging and unify email templates」でログの仕組み自体を再構築した。
一部分だけを綺麗にすることはできない。全部直すか、全部諦めるかの二択だった。「03:37 - LINEカルーセル修正(画像/URL対応、3秒遅延)」で3秒の待機を入れた。あいさつメッセージと同時に送ると、LINEの仕様で順番が前後することがあるからだ。非同期処理のタイミング調整に神経をすり減らした。
データベース設計の壁と2段階クエリ
UIが綺麗になったので、次は管理画面のデータ表示を整えようとした。「16:55 - ユーザー管理画面に紹介者情報を追加」に着手した。LINE経由で登録したユーザーの紹介者情報を、管理画面の一覧に表示したかった。
データベースのテーブルをJOINするだけの、簡単なクエリ追加で終わるはずだった。コードを実行すると、無情にもエラーが返ってきた。Supabaseのアーキテクチャの壁に激突した瞬間だった。
partnersテーブルのuser_idは、auth.usersテーブルを参照している。しかし、セキュリティ上の理由から、public.usersとauth.usersは直接JOINできない。PostgreSQLのRow Level Securityとスキーマ分離の制約だ。
「16:58 - 紹介者情報の取得を2段階クエリに修正」で妥協せざるを得なかった。referralsからpartnersを取得する。そして別クエリでusersを取得してアプリケーション層でマージする。1段階のクエリで済むはずの処理が、2段階の非同期処理に分断された。
「17:07 - LINE紹介者をコードではなく名前で表示」を実装する頃には、コードの複雑さは倍増していた。マルチテナントSaaS開発では、この「認証スキーマの分離」が常について回る。セキュリティを担保するためには必要な設計だ。しかし、データ取得のコストは跳ね上がる。N+1問題を引き起こさないよう、取得したIDの配列を使って一括でIN句検索をかける。
単純なJOINなら数行で終わる処理だ。それに数十行のロジックを書く羽目になった。「17:03 - ユーザー管理画面にLINE紹介コードとアプリ紹介者を両方表示」で表示を分けた。LINE紹介は緑、アプリ紹介はオレンジで区別する。モバイル表示も両方対応させた。
しんたろー:
Supabaseのスキーマ分離、頭では理解してるけど実装のたびに発狂しそうになる。1クエリで取れないもどかしさ。AIも最初は普通にJOINするコード書いてきて見事にエラー吐いた。
「17:14 - LINE友だち追加時のオーガニック流入を紹介コードnullに変更」でデータの整合性を担保した。紹介リンク経由でない場合はnullにする。サインアップリンクのみデフォルトコードを使用する。泥沼の修正合戦の末、ようやく画面に紹介者の名前が表示された。
「16:33 - LINE友だち統計をビジネス視点に改善」で統計カードも整理した。LINE友だちからアプリユーザーとブロックを引いて、見込み客を計算する。「16:52 - LINE友だち統計に詳細表示を追加」で折りたたみ式の詳細表示も入れた。システム記録とLINE公式データを比較できるようにした。UIの微調整から始まった1日は、データベースの制約との格闘で幕を閉じた。
ここまで読んだあなたに
今なら無料で全機能をお試しいただけます。設定後は完全放置でプロ品質の投稿を毎日生成。
落とし穴
LINEのメニューボタンを整理しようとした。整理するつもりが、配信システム全体のAPI設計を書き換えることになった。掃除を始めたら部屋の壁を壊して増築していたという、DIYあるあるの極致だ。
UIとバックエンドの密結合は、変更時の影響範囲を指数関数的に増大させる。ボタンを1つ減らしただけで、それに紐づくWebhookのハンドラーが不要になる。不要になったハンドラーを消すと、今度はそれを前提としていたログ記録のロジックが壊れる。
「09:41 - Show recipient column on mobile in notification logs」でスマホ表示を直した。「09:53 - Add icons to distinguish app name vs LINE name in notification logs」でアイコンも追加した。アプリ登録名とLINE表示名が違う問題を、アイコンで視覚的に解決した。結局、一部分だけを切り取って綺麗にすることは不可能だった。全部直すしかなかった。
今日の数字
| 指標 | 結果 |
| --- | --- |
| 総コミット数 | 27件 |
| 新機能 | 3件 |
| バグ修正 | 2件 |
| 実装したセグメント条件 | 14種類 |
| 開発時間 | 約15時間 |
15時間。一般的な開発会社なら、仕様策定からテストまで2週間はかかる分量だ。14種類のセグメント配信機能の実装コストを、手動管理と比較して90%削減した。手動でスプレッドシートを管理し、CSVをエクスポートして配信ツールにインポートする作業が、自動化によりゼロになった。
しんたろー:
15時間ぶっ通しはさすがに腰が死んだ。でも月間20時間の作業がゼロになるなら安い投資。AI代は数ドル。外注したら数十万は飛んでる。
「18:20 - LINEメニューを2ボタンに最適化し収益化コミュニティ画像を更新」で最終的な調整を終えた。「18:30 - LINEメニューのボタン色を青系に統一」で、結局色は青になった。ぽすたまコーラルはどこへ行ったのか。僕にもわからない。
FAQ
Q1. LINEのセグメント配信で最も注意すべき技術的落とし穴は?
APIのレート制限と、対象者0人によるリクエストエラーのハンドリングだ。条件を複雑にするほどクエリの実行計画が重くなり、配信遅延を招くリスクがある。対象者がいないセグメントを事前に弾くロジックを挟まないと、配信キュー全体が停止する。
Q2. 認証スキーマ分離によるデータ取得の遅延をどう回避するのか?
Supabaseのauthスキーマとpublicスキーマは直接JOINできないため、中間テーブルを介したアプリケーション層でのマージが必要になる。この際、ループ内で都度クエリを発行するとN+1問題が発生し、データベースのコネクションを枯渇させる。取得したIDを配列にまとめ、IN句を使って一括取得するのがベストプラクティスだ。
Q3. Webhook経由の非同期処理でデータの整合性をどう担保するのか?
LINEからのイベントは順不同で到達する可能性があるため、処理の冪等性を確保することが必須だ。重複チェックのロジックを必ず挟む必要がある。ログテーブルのユニーク制約とトランザクションを組み合わせることで、二重送信を防いでいる。
終わらない修正合戦
小さな「直したい」が、システム全体を書き換える連鎖を生んだ15時間だった。

この記事が参考になったら、ThreadPostを試してみませんか?
投稿作成・画像生成・スケジュール管理まで、全てAIにお任せできます。
ThreadPostをもっと知る