💻 システム開発

2026-05-01_D1移行完了

最終更新 2026年05月04日 / 31_システム開発部/SCALE_CRM/2026-05-01_D1移行完了.md

SCALE CRM 最高品質化 D1移行完了レポート

2026-05-01 GW中の大改修。Supabase停止からD1完全移行・無料運用継続・production-grade達成。


30秒で全体像

観点 一言
核心 SCALE CRM を Supabase 廃→ D1 移行+ドメイン恒久化+Runbook整備
コスト 完全無料(Cloudflare D1 + Pages + Functions)
所要時間 約4時間
影響 パートナー/PMの全業務、5/7 GW明け本格運用

なぜ移行したか

きっかけ

  • Supabase プロジェクト pelhuxlntrtejgwhcvzoDNS解決不能(NXDOMAIN)
  • = データ層が事実上死んでいた状態
  • ユーザーは気づかず使えてた → try{}catch(e){} で localStorage フォールバック動作中だった
  • 多ユーザー同期 / バックアップ / 監査ログ全部死んでた

判断

  • Supabase Free は1週間放置で自動停止(GW中に停止確実)
  • Supabase Pro $25/mo 有料は「無料縛り」に反する
  • Cloudflare D1 が最適解(自動停止なし・5GB free・SCALE Base と同じスタック)

構成変更

Before(2026-04 まで)

[Browser] ─ HTTPS ─ [Cloudflare Pages: scale-hp/base/]
                            │
                    [Supabase: pelhuxl... → DNS死亡]
                    ↓ try-catch
                    [localStorage のみ]
項目
URL https://crm.scale-group.co.jp/base/
Project scale-hp(コーポレートHPと共有)
DB Supabase(停止)
同期 Realtime WebSocket(動作せず)

After(2026-05-01〜)

[Browser] ─ HTTPS ─ [Cloudflare Pages: scale-lead]
                            ├ functions/api/* (Pages Functions)
                            ↓
                    [Cloudflare D1: scale-lead-prod]
                            ├ app_data
                            ├ snapshots (100世代)
                            ├ error_log
                            ├ audit_log
                            └ health_check
項目
URL https://crm.scale-group.co.jp/(ルート、SSL pending中)
Project scale-lead(独立プロジェクト)
DB Cloudflare D1 scale-lead-prod (id 30c62b40-8953-42e3-8fc8-3f3e47e58db1)
同期 30秒ポーリング + BroadcastChannel(同タブ即時)
復元 D1 Time-Travel 24h + snapshots 100世代
監視 window.onerror → D1 error_log 自動収集

実装内容

1. Cloudflare D1 セットアップ

  • scale-lead-prod データベース新規作成(APAC region)
  • 5テーブル schema.sql で作成
  • wrangler.toml に binding DB 設定

2. Pages Functions API(functions/api/

エンドポイント 用途
GET /api/data 全件取得(prefix=でフィルタ可)
GET /api/data/<key> 単一取得
PUT /api/data/<key> upsert + audit_log
DELETE /api/data/<key> 削除 + audit_log
GET /api/changes?since= 差分取得(polling)
POST /api/snapshot 手動スナップショット
GET /api/snapshot?id= 特定スナップショット取得(復元用)
GET /api/health UptimeRobot用ヘルスチェック
POST /api/error クライアントエラー収集

3. core.js D1 移行

互換性維持のため関数名 _initSupabase / _syncToSupabase は保持、内部実装をD1に置換。

// 旧: _sb.from('app_data').upsert(...)
// 新: fetch('/api/data/<key>', {method:'PUT', body: ...})

追加機能:
- _d1Delete(k) — D1削除ヘルパー
- _startD1Polling() — 30秒間隔で /api/changes を呼び他ユーザー更新を取得
- _reportClientError()window.error / unhandledrejection を D1 へ送信
- _migrateToSupabase() — localStorage → D1 一括マイグレーション(実体はD1向け、名前は互換維持)

4. ドメイン移管(Cloudflare API)

# scale-hp から削除
DELETE /accounts/<acct>/pages/projects/scale-hp/domains/crm.scale-group.co.jp

# scale-lead に追加
POST /accounts/<acct>/pages/projects/scale-lead/domains
  body: {"name":"crm.scale-group.co.jp"}

→ 旧URL crm.scale-group.co.jp/base/*_redirects/:splat に301。既存ブックマーク互換。

5. deploy.sh 大幅強化

# 自動でやること:
# - 必須ファイル存在チェック(13ファイル)
# - JS構文チェック(6ファイル node --check)
# - 必須関数grep(60+関数)
# - tar.gz pre-deploy バックアップ
# - wrangler pages deploy
# - 本番URL HTTP 200 確認
# - D1 API ヘルスチェック
# - tar.gz post-deploy バックアップ

障害耐性

レイヤー 対策
単一ブラウザ依存 解消。D1 がサーバ側永続層
多ユーザー同期 30秒ポーリング(/api/changes
多デバイス 解消。同じ URL から同 D1 を見る
データ消失 snapshots 100世代 + D1 Time-Travel 24時間 + 既存 localStorage キャッシュ
障害早期発見 window.onerror → D1 error_log + UptimeRobot 設定(要依頼)
退化防止 deploy.sh 60+関数grep + tar.gz自動

関連ノート


残タスク

区分 タスク 担当
待ち SSL active 待ち(crm.scale-group.co.jp) Cloudflare自動
大串 R2 有効化(1クリック / Cloudflareダッシュボード) 大串
大串 UptimeRobot 登録(無料・10分) 大串
大串 多ユーザー同期テスト(細川と別端末から) 大串・細川
Claude R2 Cron バックアップ Worker(R2有効化後) Claude
Claude SCALE CRM → SCALE CRM リネーム(次セッション) Claude

経緯

時刻 内容
12:00 キックオフMTG改修5項目(テキスト削除/UI色/スクロール飛び/日付/タスク詳細)
12:14 AI共創3項目改修(思考中UI/スクロール/セッション保持)
12:30 scale-hp と scale-lead の混同に気付く(配置マップが誤り)
12:45 hp/base/ への二重編集に気付く(誤情報削除)
13:00 Supabase NXDOMAIN 判明 → 全面再設計の必要性
13:30 D1 + Pages Functions プラン提示 → 大串承認
14:00 D1 作成 / スキーマ / API実装 / core.js移行 / ドメイン移管完了
14:30 Runbook + deploy.sh + 配置マップ + メモリ更新完了

更新履歴

日付 内容
2026-05-01 初版(D1移行完了レポート)