ADR 0004: Turso→D1 (ベクトルは Vectorize) / S3→R2 / Upstash→KV・D1
一部変更 (2026-06)
Turso→D1(ベクトルは Vectorize)・S3→R2 の決定は有効。ユーザーメモリの格納先のみ ADR 0008 で D1 から KV に変更した(Upstash 系は KV へ全面移行)。また単一 Worker 化(ADR 0006)によりコンテナ向け REST クライアント(D1RestClient 等)は不要になった。
Context
tied-bot のストレージは Cloudflare 外のサービスに分散している。
- Turso (libsql):
reactions(監査)とmessages_vectors(embedding BLOB+vector_distance_cosで意味検索)。 - AWS S3: parquet 分析(
tied-bot-data)、Slack ファイル(tied-bot-files)、master-data JSON。 - Upstash Redis: イベント重複排除 / 分散ロック、およびユーザーメモリ(10 種・TTL・重要度スコア)。
Cloudflare ファーストパーティで完結させるため、対応する Cloudflare プリミティブへ移行する。ただし D1 は素の SQLite でベクトル拡張がない点が制約になる。
Decision
- Turso → D1:
reactionsは D1 に移行。D1 / Drizzle を本リポジトリに初導入し、db/にスキーマとマイグレーション(drizzle-kit生成、wrangler d1 migrations apply適用)を置く。 - ベクトルのみ Vectorize:
messages_vectorsは D1 でベクトル検索不可のため Cloudflare Vectorize に載せ替え、メタデータは D1 または KV に保持(noisy-crow-appのvectorize-emoji-store.tsを手本)。埋め込みは AI Gateway 経由(ADR 0002)。 - S3 → R2:
tied-ai-data/tied-ai-filesバケットに移行。キー構成(slack-events/.../slack-files/.../slack-data/...)は踏襲。 - Upstash → KV / D1: 重複排除・ロックは KV(TTL 付き)、メモリシステムは D1(型・TTL・集計が必要なため)。
- アクセス経路: bot コンテナからはバインド不可のため REST クライアント(KV REST は既存、D1 REST は
packages/cloudflareにD1RestClientを追加)。Consumer / 管理画面(Worker)は バインディング直結。
Consequences
- 良い点: ストレージが Cloudflare 内で完結し、認証・課金・運用が一元化。Worker からはバインディングで低レイテンシアクセス。
noisy-crow-appの Vectorize/R2/KV パターンを再利用。 - 悪い点 / 注意:
- D1/Drizzle が新規プリミティブ。マイグレーション運用と CI への組み込みが必要。
- Vectorize 切り替えで
vector_distance_cosとコサイン類似スコアの閾値再チューニングが要る。 - parquet を書く Consumer は Workers での
parquets動作が不確実 → Bun コンテナ案を既定(移行計画 §2-3)。 - 既存データの移行(Turso/S3 → D1/Vectorize/R2)には別途バックフィルスクリプトが必要。
- フォローアップ: D1 データベース・Vectorize インデックス・R2 バケット・KV namespace の作成と ID 払い出し。Drizzle スキーマ確定。
Alternatives
messages_vectorsも D1 に載せる: ベクトル類似検索ができず意味検索機能が失われる。却下。- Turso をそのまま利用継続: Cloudflare 外依存が残り「Cloudflare で完結」方針に反する。却下。
- メモリを KV に格納: 型付き集計・TTL 別管理・管理画面からの検索がしづらい。D1 を採用。