※この記事は、Claude Codeで1人開発しているSNS運用SaaS「ThreadPost」の開発日記です。
SNS運用を自動化しませんか?
ThreadPostなら、投稿作成・画像生成・スケジュール管理まで全てAIにお任せ。
重複予約バグを3回直した。3回出た。
「修正」というコミットメッセージがゲシュタルト崩壊した。AIにコードを書かせれば一瞬で終わるはずだった自動化システム。結果的に、1日の半分を同じバグとの格闘に費やした。動くコードを書くのは簡単だ。信頼できるシステムを作るのは地獄だ。

今週の全体像
Inngestを用いた自動投稿システムを構築した。総コミット数は25件だ。

新機能は1件だけだ。バグ修正が3件。残りはひたすら既存コードの微調整とデバッグだ。Vercelのcron制限を回避して完璧な自動化を目指した。AIの生成コードと実環境の乖離に苦しめられた。
自動化で楽をするはずが、タイムゾーンの罠にハマる
自動化で楽をするぞ。そう意気込んでInngestを導入した。Vercel Hobbyのcronは1日1回しか動かせない。SNS運用SaaSで1日1回の投稿なんて役に立たない。ジョブキューで投稿を管理する仕組みを作った。
これで寝ていてもシステムが回るはずだった。「07:58 - 自動予約のスロット重複チェックを修正」。最初は軽い気持ちで修正した。JST基準の計算がずれていた。既存予約のデータ計算をJSTに統一し、同じ時間枠に複数予約が入る問題を直した。
これで完璧に動く。そう確信していた。しかし、現実は甘くなかった。同じ時間枠に重複予約が入る。「08:07 - 緑ボタン予約のスロット重複問題を修正」。連続予約時のレースコンディションが発生した。ローカルキャッシュで予約済みスロットを管理するコードを追加した。
分散システムにおける冪等性の問題だ。決済システムで最も恐れられる二重払い事故と同じ構造だ。イベント駆動型のアーキテクチャでは、ステップ実行が再試行される前提で設計しないといけない。外部APIへの重複リクエストやDBの二重書き込みが頻発する。
僕はAIに丸投げして、実環境でこのバグを踏み抜いた。Inngestはサーバーレス環境でも長時間実行される処理を安全に管理できる。VercelのHobbyプランでは関数の実行時間が10秒に制限されている。AIのAPIを叩いて、結果をDBに保存し、SNSに投稿する。この一連の流れを10秒で終わらせるのは不可能だ。
だからステップ実行という概念が必要になる。各ステップの状態を保存し、失敗したらそこから再開する。しかし、この再開が曲者だ。ステップ内で外部APIを叩いた直後にタイムアウトした場合。API側では処理が成功しているのに、Inngest側では失敗と判定される。そして無慈悲に再試行が行われる。これが重複投稿の根本原因だ。「08:32 - 自動予約で同じ時間枠に重複予約される問題を修正」。また重複予約が出た。予約ループ内で実際に予約した時刻を記録するように変更した。AIは毎回自信満々にコードを出力する。僕はそれを信じてデプロイし、またバグの通知を受け取る。
しんたろー:
1時間で3回同じバグを直した。いや、直せていなかった。修正のたびにコードが複雑になっていく。AIは文句を言わずにコードを書き直すが、根本的な設計ミスには気づいてくれない。
たまらずテストコードを書いた。「08:33 - AutoScheduleServiceのテストを追加」。手動でテストするには限界があった。追加したテスト項目は空きスロット計算の正確性、既存予約との重複回避、連続予約での重複防止、1日あたりの上限チェック、12月18日に起きたバグの再現だ。
夜になってもまだJSTベースの計算を直していた。「20:53 - 自動予約のスケジュール枠計算をJSTベースに修正」。既存予約のキーをJST時間で統一した。曜日形式の変換も追加した。DBでは1から7で管理している曜日を、JSの0から6に合わせる処理だ。Inngestのようなオーケストレーターは強力だ。しかし、再試行の制御を間違えると地獄を見る。「21:33 - Prevent duplicate logs in Inngest and React Strict Mode」。最終的にログまで二重に出力され始めた。ステップコードはメモ化される。しかし外側のコードは関数リプレイのたびに実行される。Inngestの仕様を完全に理解していなかった僕のミスだ。だから僕は即座に対策を打った。「22:05 - prevent retries for permanent errors inside step」。永続的なエラーに対する再試行を禁止した。
バックエンドの深刻なバグと闘いながら、フロントエンドの微調整も並行して行う。「08:46 - 自動予約のposting_modeカラム読み込み修正 + UI修正」。自動予約のモード設定が正しく読み込まれていなかった。関連性グレード表示の後方互換性も追加した。展開時の右寄せ維持など、細かいスタイルの調整だ。1人SaaS開発のリアルだ。スケジュールの調整も難航した。「12:16 - Update candidate generation schedule to 06:00 and 18:00 JST」。しかし、すぐに元に戻した。「12:17 - Revert candidate generation to 3-hourly schedule (09,12,15,18,21,00,03,06 JST)」。3時間ごとのスケジュールの方が、ユーザーにとって使い勝手がいいと判断したからだ。「12:19 - Remove dependency on missing last_active_at column」。存在しないカラムへの依存を削除した。AIが勝手にクエリに含めていた。「12:23 - Revert 'Remove dependency on missing last_active_at' to restore inactivity check functionality」。しかし、非アクティブチェックの機能が壊れたため、すぐにリバートした。AIが書いたコードを消すと別の機能が壊れる。ジェンガを引き抜くような作業だ。
AIに任せた炎上リスク判定が、まさかの論理崩壊
なぜ動かないんだ。泥沼のデバッグ作業でメンタルが削られていく。自動投稿システムには炎上リスク判定という重要な機能がある。AIが自動で投稿する以上、ヤバい内容をそのまま流すわけにはいかない。ここは僕が一番慎重に触った部分だ。Claudeに丸投げせず、自分で設計した。しかし、実装フェーズでAIにコードを書かせたのが間違いだった。「17:49 - 完全自動モード炎上リスク判定ロジック修正、管理画面登録日時表示改善」。炎上リスク判定でA(低リスク)が誤って弾かれていた。論理が完全に逆転している。低リスクの安全な投稿がすべてゴミ箱行きになっていた。
LLMはもっともらしいコードを書くのは得意だ。しかし、ビジネスロジックの厳密な境界値には弱い。否定形や条件分岐のネストが深くなると、あっという間に論理的ノイズが混入する。人間なら絶対にやらないような、奇妙なバグだ。LLMを使った感情分析やリスク判定は、出力が常に揺らぐ。JSONフォーマットで返却するように指示しても、たまに余計なテキストを混ぜてくる。AIが生成した判定ロジックは、この揺らぎを考慮していなかった。文字列の完全一致で判定しようとしていたのだ。結果として、少しでもフォーマットが崩れるとすべて判定不能として弾かれる。安全側に倒す設計としては正しい。しかし、これでは自動投稿システム自体が機能しない。AIが書いた複雑な条件式を読み解くのは苦痛だった。結局、人間がロジックを書き直す羽目になった。正しく低リスクは通すロジックに変更した。「21:15 - robust error detection for Google AI errors and cleanup scripts」。Google AIのエラーに対する堅牢な検出機能も追加した。
しんたろー:
AIに炎上リスク判定のコードを書かせたら、AI自身が作った安全な投稿を全部ブロックし始めた。優秀な警備員を雇ったら、社長の僕まで会社に入れなくなった気分だ。
自動予約処理にデバッグログを追加した。「21:12 - 自動予約の詳細ログをapp_logsに保存」。AIの挙動を監視するためだ。動いていることと、信頼できることは違う。
ここまで読んだあなたに
今なら無料で全機能をお試しいただけます。設定後は完全放置でプロ品質の投稿を毎日生成。
落とし穴
重複予約を直すというタスクに挑んだ。修正したはずのコードが、別の場所で全く同じ挙動を再現した。ローカルで直したと思ったら、本番環境のInngestで再発する。JST変換を直せば、今度はレースコンディションが起きる。レースコンディションを直せば、今度はログが二重に出る。修正というコミットメッセージが、もはやまたやらかしましたという懺悔の言葉になっていた。テスト環境では完璧に動いていた。モックデータを使った単体テストは全てグリーンだった。しかし、実環境の非同期処理とネットワークの遅延が絡むと、途端にシステムは牙を剥く。
今日の数字
今日のコミットは25件だ。そのうち約40%が同一バグの再発防止と関連する修正だった。
| 項目 | 数字 | 比較対象 |
|------|------|----------|
| デバッグ回数 | 3回 | 通常は単体テストで1回で潰すべき |
| 実行頻度 | 15分毎 | Vercelのcronなら1日1回 |
| 月間実行回数 | 約11,400回 | 修正前は約97,800回 |
| 実装時間 | 15時間 | AIの爆速実装なら1時間 |
AI生成の爆速実装には1時間しかかからなかった。しかし、バグ修正と信頼性担保に費やした時間は15時間に及ぶ。企業開発なら、QAチームが数週間かけてテストする規模のシステムだ。1人で開発していると、このデバッグコストが重くのしかかる。
しんたろー:
月間実行回数を97,800回から11,400回に減らした。Hobbyプランの5万回制限を余裕で超えるところだった。自動化は便利だが、クラウド破産の足音がすぐそこまで来ていた。
だから僕は実行頻度を調整した。「21:41 - cronジョブの頻度を15分毎に変更(Inngest実行回数削減)」。頻繁なポーリングは外部サービスからのBANリスクを高める。15分という間隔は、ユーザー体験を損なわず、サーバー負荷を許容範囲に収める妥協点だ。
FAQ
Q: AI生成コードの運用コストは実際どうなのか?
初期実装は圧倒的に早いが、保守コストは跳ね上がる。意図を理解せずに書かれたコードは、境界値のテストで容易に崩壊する。人間がコードの意図を読み解く時間に多大なコストを払う。
Q: 泥沼のデバッグ中、開発者のメンタル管理はどうしているか?
コミットメッセージを細かく刻んで、前に進んでいる錯覚を作る。同じバグが3回出たら、PCを閉じて物理的に距離を置く。AIに怒りをぶつけてもコードは直らない。
Q: 1日15時間かけて自動化する費用対効果はあるのか?
短期的な費用対効果は完全にマイナスだ。しかし、この仕組みが安定稼働すれば、毎日の手作業がゼロになる。システムへの信頼性が担保された瞬間に、すべての投資が回収される。
まとめ
動いていることと、信頼できることは全くの別物だった。ThreadPostは今日も進化した。

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