Updates

更新

MAD TOMMY WITH…

オリジナルキャラクターと刺繍アイテムを組み合わせて注文できるオンラインストア。

公式ページ

購入不能時の診断と匿名エラー通知を追加

· feature

購入不能時の診断と匿名エラー通知を追加

何を変えたか

購入に必要なFirestore設定が不正な場合、ユーザーには内部事情を含まない一時停止メッセージを表示し、開発者コンソールには不正フィールドと修正先を記録するようにした。あわせて、設定・カタログ読込、注文作成、決済セッション作成、配送先保存、問い合わせ、レビューなどの操作でシステムエラーが起きた際、既存のDiscord Webhookへ匿名の固定メタデータだけを通知するCloud Functionを追加した。

なぜ変えたか

設定ドキュメントに新しい必須項目が不足したことで購入不能になった際、従来の画面は「配送設定が完了していない」と原因を狭く誤認させる表示だった。また、ユーザー操作で発生したエラーを運用者が能動的に把握する経路が不足していた。

ユーザーにとって何が良くなったか

内部設定の詳細や誤った原因説明を見せず、再試行可能な一般メッセージで案内できる。問い合わせ送信失敗時は入力内容を保持するため、再入力の負担も減る。運用者は通知とコンソール情報から問題箇所を早く特定できる。

技術的な内容

  • Firestoreの生設定をCloud Functions側と同等の条件で診断し、フィールドパス単位の問題一覧を返す。
  • ブラウザから送れる通知データを、操作種別・エラーコード・固定画面パス・ビルドIDの列挙型に限定する。
  • Cloud Functionでも入力を再検証し、任意フィールドは破棄する。
  • Discord payloadにはユーザーID、氏名、メール、住所、注文ID、入力値、例外メッセージ、スタックトレースを含めない。
  • 操作・コード・画面パスからSHA-256キーを作り、Firestore transactionで同一エラーを10分間重複通知しない。
  • 通知自体の失敗は元のユーザー操作へ伝播させない。
ユーザー操作
  -> 固定エラー分類
  -> Callable Functionで再検証
  -> Firestoreで10分重複抑制
  -> 既存Discord Webhookへ匿名通知

Before / After

Before

  • 購入不能の理由を配送設定に限定して表示していた。
  • 設定不正の具体的なフィールドをログから特定しづらかった。
  • クライアント操作エラーの通知経路がなかった。

After

  • ユーザー表示と運用者向け診断を分離した。
  • 管理画面の修正場所と不正フィールドをコンソールで特定できる。
  • 個人情報を含まない固定メタデータだけを通知できる。

判断したこと・トレードオフ

  • 例外メッセージは診断に便利だが個人情報や内部情報を含み得るため、Webhookへ送らず固定コードへ変換した。
  • 入力ミス、在庫切れ、ユーザーキャンセルなど通常の業務結果は通知対象外とし、対応可能なシステム・権限・設定エラーだけを対象にした。
  • 現状クライアントでFirebase App Checkを初期化していないため、今回のCallable Functionだけ強制すると正規ユーザーの通知も失敗する。固定allowlistと重複抑制を先に採用し、App Check導入は別課題とした。

ハマったこと・学んだこと

  • 表示用の設定正規化が既定値を補完していても、注文作成側が生データを厳格検証すると両者の判定がずれる。設定スキーマ追加時は、保存処理・生データ診断・サーバー検証・既存データ移行を一体で扱う必要がある。
  • 通知APIへ例外オブジェクトを渡す設計は、意図せず個人情報を送る危険がある。クライアントとサーバーの両方で固定スキーマへ絞る方が安全だった。
  • 重複抑制キーを有限な列挙値だけから作れば、保存ドキュメント数も上限が決まり、任意文字列による無制限増加を避けられる。