※この記事は、Claude Codeで1人開発しているSNS運用SaaS「ThreadPost」の開発日記です。
スマホで投稿候補を確認しようとしたら、画像がはみ出てて、ボタンが押せなくて、テキストが溢れていた。
「これ使えないじゃん」って自分で思ったんだから終わってる。
僕が指示したのは1個ずつだ。
1個直したら別のところが崩れる。
気づいたらスマホの画面を直すためだけに10本のコミットを消費していた。
SNS運用を自動化しませんか?
ThreadPostなら、投稿作成・画像生成・スケジュール管理まで全てAIにお任せ。
44件のコミットと1件の新機能
今週はUIの微調整と裏側のロジック修正に全振りした。
新しい機能を作るのは楽しい。
でも、作った機能が「普通に使える」状態になるまでには泥臭い作業が無限に続く。

- 総コミット: 44件
- 新機能: 1件
- バグ修正: 0件(表向き)
- 壊れた回数: 数え切れない
- UI調整のコミット: 10本以上
10本って多いのか少ないのか、正直わからない。
ただ、直し終わったあとにスマホで開いたら「あ、普通に使える」ってなった。
その「普通」を作るのに10本かかった。
専任UIデザイナーがいれば1〜2回の修正で済む作業量だ。1人だと10本になる。
しんたろー:
10本のコミット全部UIだ。新機能ゼロ。でもこれサボると「使えないアプリ」のまま世に出る。地味だけど逃げられない。
詐欺UIとの決別:「プレミアム」と表示して実はHaikuだった件
AIモデルの判定ロジックを整理して、UIに「プレミアム」か「スタンダード」かのラベルを表示する機能を実装した。
ユーザーがどのレベルのAIを使っているか一目でわかれば体験が上がる。
Claudeに指示を出して、UIコンポーネントにラベルを追加した。
画面には見事に「プレミアム」の文字が輝いていた。

内部のデータを確認して血の気が引いた。
固定値でモデルをハードコーディングしていた。
実際には安価なHaikuモデルで生成しているのに、UI上では常に「プレミアム」と表示されていた。
完全に詐欺まがいの状態だ。
「fix: 投稿候補のAIモデル表示が常にプレミアムになるバグを修正」というコミットを打つ羽目になった。
03:06のコミットで発覚して、固定値のハードコーディングを排除し、メタデータからの動的判定へ切り替えた。
「fix: AIモデル表示の判定ロジックを修正(折り畳みヘッダー)」で、表示と実態の乖離を完全に解消した。
古いデータでも正しく「エコノミー」と表示されるようになった。
業界ではSingle Source of Truth、つまり信頼できる唯一の情報源をデータベースのメタデータに置くのが鉄則と言われている。
開発初期はついコード側にロジックを書き込みがちだ。
NetflixのABテスト基盤でも初期に同じ構造の表示バグが発生したと言われている。
- 問題: ハードコーディングによる固定値表示
- 影響: 安価なモデルでもプレミアムと表示される詐欺状態
- 解決: メタデータのclaude_modelからの動的判定
- 結果: 表示と実態が一致する状態に
「fix: 手動投稿生成でAIモデル選択機能を追加」で、ユーザー自身がモデルを選べるようにもした。
ペルソナ変更時にデフォルト設定を適用し、リクエスト値・ペルソナ設定・ユーザー設定の順で優先順位をつけた。
プラン検証付きでフォールバックも対応した。
しんたろー:
ハードコーディングは麻薬だ。とりあえず画面に出すために入れた固定値が、そのまま本番環境にデプロイされる。今回はユーザーに怒られる前に気づけた。発見まで約3時間。次はもっと早く気づきたい。たぶん。
ゾンビ画像とReact状態管理の泥沼:消したはずの画像が投稿に復活した
スレッド投稿の画像管理で、ユーザーが×ボタンを押せば直感的に画像が消えるUIを実装した。
スマホでの操作性を考えると、編集モードに入らなくてもビューモードで直接画像を外せるのが理想だ。
「fix: スレッド表示モードで画像の「外す」ボタンを追加」をコミットした。
画面上の×ボタンを押す。画像がスッと消える。完璧だと思った。
投稿テストをして絶望した。
UIからは完全に消えたはずの画像が、実際の投稿には含まれていた。
「fix: スレッド画像の×ボタンが効かない問題を修正」を慌てて投入した。
画像を除外しても、内部のthread_partsやデータベースの状態と同期していなかった。
UI上では消えたように見えて、投稿時には画像が復活するゾンビ画像が発生していた。
APIのペイロードを見るとしっかり画像のURLが存在している。
ブラウザのキャッシュを疑い、コンソールログを仕込みまくった。
原因は、表示用の配列と保存用の配列が完全に分離していたことだった。
表示用の配列から要素を削除しても、保存用の配列には一切影響を与えていなかった。
「fix: スレッド投稿の画像管理を全面改善」で、画像表示の一元化と自動同期の仕組みを作った。
さらに「fix: ビューモードの×ボタンでthread_parts内の画像も確実に除去」で、一括更新関数を実装した。
データベース・State・UIを強制的に同期させる必要があった。
Reactのステート管理において、ネストされたオブジェクトを直接操作すると参照の不一致で再レンダリングが走らないことがある。
ReduxやZustandなどの状態管理ライブラリを使わない小規模開発で最も陥りやすい非同期の罠と言われている。
useEffectによる自動同期を組み込んで対処した。
- 初期状態: ×ボタンでUIからのみ画像が消える
- 問題発生: 投稿データには画像が残り続けるゾンビ化
- 根本原因: ネストされたオブジェクトの参照不一致
- 解決策: データベースとUIの一括更新関数の実装
「fix: 予約・履歴画面のスレッド投稿画像表示を修正」で、他の画面でも重複表示されないように潰して回った。
10本のコミットを消費して、ようやくスマホでの画像操作がまともに動くようになった。
UIの細部修正に追われる1日だった。
しんたろー:
ゾンビ画像を退治するのに丸一日溶かした。UIの見た目だけ変えて裏のデータが更新されてないのはReact初心者あるあるだ。1人開発だと誰もコードレビューしてくれないから、テスト投稿で発覚するまで気づかない。まじでしんどい。
落とし穴:画像は消した、だがデータは死んでいない
APIのペイロードを開いたら、画面上で消したはずの画像URLがしっかり生きていた。
ブラウザのキャッシュを疑って、ハードリロードして、別のブラウザで試した。全部同じ結果だった。
コンソールログを10箇所に仕込んで、ようやく原因が見えた。
表示用の配列と保存用の配列が完全に別物だった。
×ボタンは表示用の配列から要素を消していただけで、保存用の配列には何も触れていなかった。
投稿ボタンを押すたびに「消したはずの画像」が復活してくる。
これを直すのに「fix: スレッド投稿の画像管理を全面改善」「fix: ビューモードの×ボタンでthread_parts内の画像も確実に除去」の2本を要した。
次からはUIと保存データを同時に更新する関数を最初から作る。たぶん。
ここまで読んだあなたに
今なら無料で全機能をお試しいただけます。設定後は完全放置でプロ品質の投稿を毎日生成。
数字で見る1人開発のリアルとコスト改善
今週の開発データをテーブルにまとめた。
| 指標 | 今週の数字 | 比較対象・意味 |
| :--- | :--- | :--- |
| スマホUI対応のコミット | 10本 | 専任UIデザイナーがいれば1〜2回の修正で済む作業量 |
| 手動生成のコスト設定 | 0.5pt | 変更前の0.1ptと比較して利益率を5倍に改善 |
| バグ修正にかかった時間 | 約6時間 | 企業チームのコードレビューありなら1時間で潰せる内容 |
| 新規実装した機能数 | 1件 | 先週の5件と比較して大幅なペースダウン |
手動生成のコストを0.1ptから0.5ptへ引き上げた。
APIコストが約0.9円かかるのに対し、0.1pt(≒1円)では利益がほぼ出ない。
サーバー代やインフラ費用を考慮すると完全に赤字だった。
投稿時に1pt回収する仕組みと合わせて、トータルで黒字になる設計に修正した。
しんたろー:
0.1ptのままユーザーが増えていたら、使われれば使われるほど赤字が膨らむ地獄の装置が完成していた。APIの原価計算はリリース前に3回は見直すべきだ。僕はリリース後に気づいた。
未解決のアスペクト比問題
「fix: 投稿候補の画像アスペクト比を維持するよう修正」を入れたが、まだ完璧ではない。
1枚画像の時は元の比率を維持できるようになったが、グリッド表示の際に特定のデバイスで画像が少し歪む現象が残っている。
CSSのobject-coverとh-autoの組み合わせが、SafariとChromeで微妙に解釈が違う。
このUIの崩れは早急に潰したい。
ThreadPost開発FAQ
Q: 手動生成のポイント消費を5倍にした根拠は?
APIコストが1回あたり約0.9円かかる。0.1pt設定では利益がほぼ出ない計算だった。
サーバー代・インフラ費用を含めると完全に赤字で、ユーザーが増えるほど損失が拡大する構造だった。
0.5ptに変更して、投稿時の1pt回収と合わせてトータル黒字になる設計にした。
Q: ゾンビ画像バグはなぜコードレビューで防げなかったのか?
1人開発なのでコードレビューが存在しない。テスト投稿で発覚するまで気づけない構造だ。
表示用と保存用の配列が分離していたのは設計段階の問題で、実装時には「動いてる」に見えた。
今回は本番リリース前に自分でテストして発見できた。ユーザーに怒られる前に気づけたのは運が良かった。
Q: SafariとChromeでCSSの解釈が違う問題はどう対処するのか?
CSSのobject-coverとh-autoの組み合わせはブラウザエンジンによって挙動が変わることがある。
現状は1枚画像では修正済みで、グリッド表示時の歪みが未解決として残っている。
次のスプリントでaspect-ratioプロパティへの切り替えを試す予定だ。
泥臭い修正の積み重ねがプロダクトを作る
10本のコミット全部UIだった。新機能は1件。でも「普通に使える」状態になった。

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