コンテンツにスキップ

2026-03 Storefront メンテナンスモードの Cloudflare KV 正本化

位置づけ

Storefront のメンテナンス状態を Vendure の稼働可否から切り離し、障害時でも Storefront 側を即時に遮断・復旧できるようにするための補足仕様。

通常運用では Vendure Dashboard から手動切替と毎日の予約時間を設定し、Vendure 障害時のみ Cloudflare を直接操作する。

適用範囲

  • Storefront のメンテナンス判定
  • maintenance_bypass による回避導線
  • Vendure Dashboard / Admin GraphQL によるメンテナンス切替と毎日の予約時間設定
  • Cloudflare KV namespace と Worker binding
  • maintenance 用 Cloudflare credential の Secrets Manager 配置

合意事項

  1. 正本
  2. Storefront のメンテナンス設定の正本は Cloudflare KV とする。
  3. Vendure DB には複製しない。
  4. KV のキーは単一キー storefront:maintenance とする。

  5. KV データ構造

  6. KV 値は JSON とし、以下の 3 項目を必須とする。
    • enabled: boolean — 手動メンテナンスの ON/OFF。false でも scheduleWindows の時間窓内では予約メンテナンスとして有効になる。
    • bypassToken: string
    • updatedAt: string
  7. 以下の項目は省略可能(optional)とする。

    • displayTitle: string — Storefront のメンテナンス画面に表示する見出し。 省略時は Storefront / Vendure の既定文言を使う。
    • displayDescription: string — Storefront のメンテナンス画面に表示する rich text HTML 本文。 省略時は Storefront / Vendure の既定本文を使う。定期メンテナンスの開始・終了予定、 復旧案内、問い合わせ先は Vendure Dashboard からこの本文へ明記する。
    • scheduleWindows: MaintenanceScheduleWindow[] — 定時メンテナンス時間窓(Asia/Tokyo)。 省略した場合は手動 enabled のみを参照する。
    {
      "startHour": 0,
      "startMinute": 0,
      "endHour": 4,
      "endMinute": 0
    }
    

    各フィールドは startHour/endHour が 0-23、startMinute/endMinute が 0-59。 値は UTC や操作者のローカル timezone ではなく、常に JST(Asia/Tokyo)の時刻として扱う。 Storefront runtime は Intl.DateTimeFormattimeZone: "Asia/Tokyo" で現在時刻を JST の分単位へ変換してから判定する。 start === end は空窓として無視し、start > end は日跨ぎ窓として扱う(例: 23:00-01:00)。 判定は [start, end) の半開区間。malformed なフィールドを持つ窓は個別に無視し、他の窓の評価に影響しない。

  8. 責務分担

  9. Storefront は Cloudflare KV のみを参照してメンテナンス判定を行う。
  10. Vite SPA 配信では Worker entrypoint が navigation 配信前に KV を判定し、 メンテナンス中の通常ページを /maintenance へ redirect する。
  11. Storefront 側の KV payload 解釈と毎日予約時間の判定は apps/storefront/src/lib/maintenance-state.ts を正本とし、Worker entrypoint や legacy server guard はこの共通関数を呼び出す。
  12. Vendure は Cloudflare KV を操作する制御面とし、通常運用では Vendure Dashboard の専用画面または Admin GraphQL を利用する。
  13. Vendure Dashboard 上では enabled を「手動メンテナンス」として表示する。 適用状態は手動ONと予約時間中を合成して表示し、手動OFFでも予約時間が設定されていれば 指定時間に Storefront がメンテナンスページへ切り替わることを明示する。
  14. Vendure は 切替制御面であり、メンテナンス画面の見出し・rich text 本文も KV payload の一部として管理する。Storefront はその文言を表示するだけで、 予約時間から終了予定文言を推定しない。
  15. Vendure の maintenanceSettings / updateMaintenanceSettings / rotateMaintenanceBypassToken 契約は維持する。
  16. 通常運用の予約時間設定は Vendure Dashboard のメンテナンスモード画面を正とし、 Cloudflare KV の直接編集は Vendure 障害時の復旧手段とする。

  17. JST 判定の回帰テストは Storefront 側に置く。主な対象は apps/storefront/src/lib/maintenance-state.test.tsapps/storefront/src/lib/server-maintenance-guard.test.tsapps/storefront/src/worker-entry.test.ts。 Vendure 制御面の保存・保持・入力値検証は packages/plugins/src/system-integration/maintenance-mode/maintenance-mode.service.test.ts で確認する。

  18. 判定順

  19. Storefront の判定順は以下とする。

    1. STOREFRONT_MAINTENANCE_MODE / VITE_PUBLIC_STOREFRONT_MAINTENANCE_MODE
    2. Cloudflare KV
    3. 通常動作
  20. 回避導線

  21. maintenance_bypass クエリと maintenance_bypass cookie による回避導線は維持する。
  22. 回避トークンの正本も Cloudflare KV に置く。

  23. Secret 配置

  24. CLOUDFLARE_MAINTENANCE_KV_NAMESPACE_ID / CLOUDFLARE_ACCOUNT_ID / CLOUDFLARE_API_TOKENb2b-ecommerce/{env}/shared を正本とする。
  25. Storefront deploy (*_storefront + shared) と Vendure 制御面 (*_vendure + shared) は、同じ shared secret から解決する。
  26. 同一値を service secret 側へ重複配置しない。

  27. namespace / deploy 前提

  28. 環境ごとに Cloudflare KV namespace を分離する。
  29. namespace 名は ec-storefront-config 系を正とし、maintenance 専用名には戻さない。
  30. ec project 全体で共有する設定が必要になった場合のみ、別途共有 namespace を設ける。
  31. Storefront の Cloudflare deploy では MAINTENANCE_KV binding を必須とし、target 環境の CLOUDFLARE_MAINTENANCE_KV_NAMESPACE_ID から割り当てる。
  32. apps/storefront/wrangler.tomlMAINTENANCE_KV placeholder は、production では top-level table 群の前、staging / preview / mock では各 [env.<target>] の前に置き、生成される binding が正しい TOML scope に入るようにする。
  33. Storefront deploy は binding 注入後に Worker version を upload し、versions viewMAINTENANCE_KV binding を検証してから deploy / promote する
  34. 手動の version promote でも、MAINTENANCE_KV binding を持たない version は deploy しない。

  35. 障害時運用

  36. Vendure 停止時は Cloudflare Dashboard / API / CLI から Cloudflare KV を直接更新してよい。
  37. このため、Cloudflare 側にメンテナンス用 namespace と最小権限 API トークンを用意する。

  38. 障害時の失敗モード

  39. Cloudflare KV 読み取り失敗時、Storefront は fail-open とする。
  40. 理由は、Cloudflare KV 一時障害により Storefront 全体を誤停止させないため。
  41. 失敗時は Sentry とログへ記録する。

非対象

  • Vendure Dashboard 上で Storefront と同等のメンテナンス表示を出すこと
  • Vendure DB へのメンテナンス状態の複製
  • ec project 全体の共通設定を、この namespace へ混載すること

受け入れ観点

  1. Storefront は Cloudflare KV の値だけでメンテナンス表示を開始・解除できること。
  2. 通常運用では Vendure Dashboard または Admin GraphQL からメンテナンス状態と bypass token を更新できること。
  3. Vendure 停止時でも Cloudflare Dashboard / API / CLI で同じ状態を直接更新できること。
  4. CLOUDFLARE_MAINTENANCE_KV_NAMESPACE_ID / CLOUDFLARE_ACCOUNT_ID / CLOUDFLARE_API_TOKENb2b-ecommerce/{env}/shared を正本として管理されること。
  5. Cloudflare KV 読み取り失敗時に Storefront が fail-open で継続し、失敗が Sentry / ログで観測できること。

影響範囲

  • DB migration は不要。
  • Storefront の公開 URL 構造は変更しない。
  • Vendure Dashboard のメンテナンスモード導線は維持する。