Skip to content

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_vectorsembedding 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-appvectorize-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/cloudflareD1RestClient を追加)。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 を採用。