---
title: "アマチュアが AI 駆動 + フルスタック 1 人で Floatia ロードマップを完走させた話"
description: "アマチュア (独学数年) のプログラマが、Claude (Opus 4.7) を使った AI 駆動 + フルスタック 1 人体制で「Floatia (旧 Drift)」 — 280字の手紙を瓶に詰めて流す一期一会の匿名 SNS — を作っている話。git 開始から 10 日で β 公開水準。世界観の哲学、技術選定 (Go + chi + pgx、ORM なし、最新 framework 採用、セルフホスト + CF Tunnel)、ロードマップ 4 軸 (削除廃止 / 抽選最適化 / 経年表現 / 整合性) を 2026-04-26 にまとめて完走させた経緯、AI 駆動の盲点と CLAUDE.md 性能規約まで掘り下げる。"
url: https://ryuuneko.com/blog/floatia-roadmap-completed
published: 2026-05-03 04:18:37.659482
updated: 2026-06-16 09:16:43.899016
---
最初に立場を明らかにしておくと、私は **アマチュア (独学で数年) のプログラマ** で、職業エンジニアではない。普段はぜんぜん別の仕事をしていて、コードを書くのは完全に趣味。アマチュア無線家やアマチュアスポーツ選手と同じ温度感、と思ってもらえれば。
そのアマチュアが、Floatia (旧 Drift。匿名で瓶を海に流すコミュニケーション体験) を **ほぼ全部 Claude (Opus 4.7) を使った AI 駆動開発で書いている**。仕様の議論・設計・実装・テスト・レビューまで、人間 (= 私) は方向決めとレビュー観点の提示が中心で、コード自体は AI が書く。
しかも **フルスタック 1 人体制**: Frontend (Next.js + React) / Backend (Go) / DB (Postgres) / Infra (Docker Compose + Cloudflare Tunnel + セルフホスト) / 認証 / 観測 / 監査 / 世界観コピー / アニメーション まで全レイヤを 1 人 + AI で書いている。チームメンバーはいない、デザイナーもいない、SRE もいない。**AI 駆動だからこそ、アマチュア 1 人でこれを全部回せている**。
**2026-05 時点で β 公開中** →
:::callout{type="info" title="この記事の要約"}
- アマチュアが AI 駆動 + フルスタック 1 人で β SNS をローンチした
- git 開始から **10 日** で β 公開水準
- backend ロードマップ 4 軸 (削除廃止 / 抽選最適化 / 経年表現 / 整合性) を 2026-04-26 に完走
- 一番の学び: **AI に書かせる前提で `CLAUDE.md` を整備するのが最大の投資先**
:::
## Floatia とは — 「誰かの海へ、手紙を」
**Floatia は「280字の手紙を瓶に詰めて海に流す、一期一会の匿名 SNS」**。
- 流すと瓶は海を漂う
- 別の誰かが海辺を歩いていて、たまたま拾う
- 封を開けて読む。書き足して再び流すこともできる
- そして二度と同じ瓶には会えない (= 一期一会)
それだけ。リプライツリーも、フォローも、いいねも、通知もない。
### 一期一会を仕様に落とす
「一期一会」を世界観コピーで語るだけでなく、**仕様レベルで強制している**:
- **通知なし** — 「あなたの瓶に返信が」「新着があります」を一切作らない
- **新着バッジなし** — 戻ってきても何が増えたかわからない
- **活動フィードなし** — 自分の足跡をたどる動線を持たない
- **続きを追えない設計** — 自分が拾ったあとに別の人が書き足すと、その瓶はもう自分には読めない。「あのとき読んだ続き」を追うことはできない
「現代の SNS が当然のように持っている機能」を **意図的に持たない**。これは制約ではなく、**それこそが体験の核**。
## 開発スケジュール — ざっくりアジャイル
git history で追える範囲のマイルストーン:
| 日付 | やったこと |
|---|---|
| 2026-04-23 | `Drift v0.1 — initial prototype` 公開 git 開始。同日に **SQLite → Postgres 16 移行** |
| 2026-04-24 | **Node/TS → Go 全書き換え** + cut-over + 安定化。Next.js 14 → 16 bump、admin / feedback / announcements を一気に積む |
| 2026-04-26 | **4 軸ロードマップ A/B/C/D 完走** |
| 2026-04-27 | 5 段ワークフロー (プラン → red テスト → 実装 → green テスト → レビュー) を恒常化 |
| 2026-04-30 | **drift → Floatia リネーム**、dual-host 開始 |
git 開始から **10 日** で β 公開水準。git 開始前にローカルで数日の試作期間があったので、実際の総開発期間は **2 週間ちょっと** (試作の詳細は後述「移行履歴」)。
「アジャイル」と書いたが、実際の運用は:
- **5 段ワークフロー** をタスク単位で踏む。durable に固定
- sprint は無い。「今日はここまで」を毎晩決める
- 機能の優先度は「世界観に効くか / scale に効くか / セキュリティに効くか」の 3 軸で都度判定
- AI に **「規模 S / M / L」** で見積もりを出させて、L だと当日中に着手しない
AI 駆動の利点は **「実装の見積もりが正確になる」** こと。AI が「規模 S なら 30 分、L なら半日」と出してくれて、それが結構当たる。人間の見積もりは楽観バイアスが乗るが、AI は淡々と「これは N 箇所触るから L」と判断するので、スケジュールが意外とブレない。
もう一つ大きいのは **「レイヤ間の context switch コストが激減する」** こと。普通フルスタック 1 人でやると「Go の `pgx` 構文 → Next.js の Server Component → Docker Compose の env_file」で 1 日中ヘッドが切り替わって疲弊する。AI 駆動だと AI 側が各レイヤの細部を保持してくれるので、人間は **「世界観としてどうあるべきか / scale としてどうあるべきか」** という抽象度の高い判断だけに集中できる。
## 技術選定 — 「趣味だからできた」自由度
**最初に断っておくと、この技術選定は「趣味で作っているからこそできた」**。仕事のプロダクトだったら絶対に通らない判断 (出てすぐの最新 framework / library を採用 / ORM を入れない / セルフホスト / 軽量にインフラ集約) が並んでいる。「AI に書かせやすい」「自分が試したい」「手数を減らせる」を最大化していて、**保守性や引き継ぎやすさは捨てている**。
### スタック
| レイヤ | 採用 |
|---|---|
| Backend | Go + `chi` + `pgx`、単一バイナリ ~40MB、起動 ~100ms |
| DB | PostgreSQL |
| Frontend | Next.js + React + Tailwind + Framer Motion + `next-intl` |
| 認証 | Argon2id + JWT HS256 + HttpOnly Cookie (WebAuthn は将来用にスキーマのみ用意・未実装) |
| テスト | DB 統合テスト + E2E (主要パスのみ) |
| 観測 | クエリ統計 + プロファイラ + slow-query 追跡 + 自前アラート |
| ホスティング | セルフホスト + Cloudflare Zero Trust トンネル (ports 公開ゼロ) |
### 移行履歴 — 4 段、ほぼ全部 git 開始前
1. **Cloudflare Workers + D1** (試作 day 1) — D1 が必要な extension を持たず詰んだ
2. **Node 20 + Hono + better-sqlite3** (試作 day 2-3) — multi-writer に弱い
3. **Node 20 + Hono + Postgres 16** (2026-04-23) — git 開始日
4. **Go + chi + pgx** (2026-04-24) ← 現行。**前日からたった 1 日で書き換え + cut-over**、スループットとメモリが目に見えて改善
3 → 4 の移行は、Argon2id PHC 形式 + JWT HS256 で認証スキームを互換にしておき (新ランタイムが旧ハッシュも検証可能)、**ほぼ無停止で runtime を切り替えられた**。「runtime を 1 日で全書き換えする」のは AI 駆動ならではの動き。
### なぜ Go + chi + pgx か
- **静的型 + シンプルな構文** → AI が型で間違いを構造的に減らせる。Rust も候補だったがライフタイムとマクロが AI の生成ばらつきを増やす方向に効くので除外
- **chi は薄い** — middleware を積む思想で、generated code が独自 magic に依存しない
- **pgx は超薄い** — ORM は使わない。**hot path で SQL を制御したい**用途に直接マッチ
### なぜ ORM を使わないか
- **AI は ORM の DSL より素の SQL のほうが圧倒的に上手い**
- **クエリの計算量が透明** — `EXPLAIN ANALYZE` で見たコストとコードが 1:1
- **migration は冪等 SQL でやる** — `schema.sql` を起動時に流すだけ
仕事のプロダクトだったら ORM は入れる。**1 人で書いてレビュアーも自分なら、その肩代わりが要らない**。
## ロードマップ完走 — C → B → A → D
UI/UX フェーズが落ち着いたタイミングで仕込んでいた 4 軸を 2026-04-26 にまとめて完走させた。
- **A. 世界観**: 削除廃止 + 深海復活 + 経年表現
- **B. 性能**: 抽選アルゴリズム + count 集約
- **C. メタ**: `CLAUDE.md` 性能規約
- **D. 整合性**: hash chain + content_hash 漸進化
着手順は **C → B → A → D**。メタ規約 → 性能基盤 → 世界観の上物 → 整合性の中長期路線、という積み方。
### C. メタ — `CLAUDE.md` に性能規約を刻む
最初にやったのは規約整備。AI 駆動である以上、AI に渡る `CLAUDE.md` が **そのままコード品質の上限** になる。コードレビューで都度直すより、規約を直したほうが伝播が早い。
- 「やってはいけない」セクションに、**hot path での** `COUNT(*)` 多発 / N+1 / `ORDER BY RANDOM()` / unbounded SELECT を禁止 の 4 条を追加
- 新節 **「性能 posture (hot / warm / cold path)」** を作成。endpoint ごとに温度感を表で定義
- テスト規約に **query count assertion** を追加
### B. 性能 — 抽選アルゴリズム + count 集約
- pick 抽選: `ORDER BY RANDOM()` → rejection sampling アルゴリズムへ。母集団膨張に対して scale-invariant (~1ms 前後を維持)
- 多重 `COUNT(*)` を集計用シングルトン表 (トリガ更新) + 短期キャッシュで **O(1)** 化
- N+1 を `IN ($1, $2, ...)` に統合
### A. 世界観 — 削除廃止 + 深海復活 + 経年表現
- 物理削除のクリーンアップを廃止。古い瓶も別フェーズで残す
- pick 抽選で **drifting / deep の tier 分け**。「深い海から、古い瓶が偶然浮上した」体験
- 瓶の表示コンポーネントに経年表現 (海藻 / 貝殻 / 退色) を追加。古い瓶ほど装飾が増える variance を仕込んだ
- 「これは古い瓶」と明示せず、視覚と時刻表記でさりげなく古さを匂わす
世界観論: 「流した瓶との別れも完全な別れ」 (= 「拾った瓶との出会いも一度きり」と対称) が一期一会の閉じ方として美しい。
### D. 整合性 — hash chain + content_hash 漸進化
- 監査チェーンの hash chain は **retention 上限** があるため頭打ち、現状 OK
- メッセージの content hash 全件 verify は将来詰まる → cursor-based 漸進バックグラウンド + N% サンプリング四半期 cron に
- 監査チェーンの先端を外部に退避する既存路線は維持
## AI 駆動開発の盲点 — なぜ C を最初にやったのか
ここが今回一番書きたかったところ。
「無駄が漏れた構造」(`COUNT(*)` 多発 / N+1 / `ORDER BY RANDOM()`) は、AI が要件を素直に SQL に翻訳する癖から来る。「ランダムに 1 件」と頼めば `ORDER BY RANDOM()`、「件数を 6 つ表示」と頼めば `COUNT(*)` を 6 個並べる。AI は「読みやすい」「短い」「動く」を優先する傾向があるので、これは構造的な特性。
問題は、これが厄介な性質を持っていること:
- **バグじゃない** — 動くし、結果も正しい
- **レビューで止まらない** — 行数も読みやすさも問題なし
- **小規模時には実害がない** — 1000 行の `COUNT(*)` は 1ms で返る
- **性能テストが規約に無いと検出できない** — 単体テストはパスする
つまり「動く + 読める + 小規模で速い」の三拍子で **構造的に検出できない**。AI レビューに頼っても止まらない (AI 同士は同じ盲点を共有しているので、書き手 AI が「OK」とするコードを、レビュワー AI も「OK」と通してしまう)。
人間レビューでも、「動いて読めるコード」を性能観点で止めるのは判断コストが高い。「これ将来的に詰まりそうなんだよな…でも今は動くし…」で見送りがちで、私自身も初期はそうだった。
C の規約追加で、
1. **「やってはいけないリスト」** — AI 生成時の負の制約として効く
2. **「temperature 表」** — endpoint ごとの温度感を AI に伝える共通語彙
3. **query count assertion** — テストでの自動検出
の **3 段で結界化** した。AI 駆動を続ける以上、こういう「正しいが筋が悪い」構造を **規約側で止める仕組み** が必要だ、というのが今回の一番の学び。
:::callout{type="tip" title="AI 駆動開発で一番大事なこと"}
**AI に書かせる前提で `CLAUDE.md` を整備するのが、AI 駆動開発における最大の投資先**。コードレビューで都度直すより格段に効く。
:::
## ふりかえり
AI 駆動開発で 4 軸を 2026-04-26 当日にまとめて完走できたのは、各軸が **小さく独立** していて **規約 (C) で品質保証** されていたから。規模 L の A も、B で hot path が綺麗になっていたので追加変更が局所的に閉じた。
技術選定の話で書いた **「ORM を使わず素の pgx で SQL を直書きする」** 判断が、B 章の hot path 最適化を現実的にしたのも大きい。AI 駆動 + 性能要件 + 世界観の 3 つを同時に満たすには、**抽象を一段薄くする** (= ORM を抜く、framework を薄いものにする、middleware は自分で積む) のが結果的に効いた。これは **趣味だから抜けた** 抽象でもある。仕事のプロダクトだったら ORM は入れていた。
git 開始から 10 日で β 公開水準まで持っていけた事実が、AI 駆動 + 趣味プロジェクト + 規約整備の組み合わせの説得材料として一番強い。
ロードマップ完結 (2026-04-26)。次は phase が止まった頃にまた書く。
---
**β 公開中**: — 「誰かの海へ、手紙を」
---
*※本記事は2026年6月時点の情報をもとにしています。サービス・コマンド・仕様は予告なく変わることがあります。*