インシデント対応 Runbook

SSoT 参照: 通知ルーティング (severity / channel / mention / format) は notification-strategy.md で定義。 on-call 体制 (誰が・どの device で・何分以内に・何をする) は oncall.md で定義。 本 runbook は P0/P1 発火時の手順 (トリアージ + 初動 + エスカレーション) のみ扱う。

Severity 区分は notification-strategy.md と一致させること:

  • SEV1 ≡ P0 (Critical, 15分以内対応, #p0-alerts + @here)
  • SEV2 ≡ P1 (High, 4時間以内対応, #p1-ops)
  • SEV3 ≡ P2 (Info, 翌営業日, #p2-deploys)

Parky の本番/開発環境で障害が発生した際のトリアージ・初動手順。

トリアージ

  1. 影響範囲の特定
    • 対象: parky.co.jp / api.parky.co.jp / admin.parky.co.jp / owner.parky.co.jp / dev-* のどこか
    • 症状: 完全停止 / 部分機能不全 / レスポンス遅延 / エラー率上昇
    • 開始時刻(JST)を記録
  2. Severity 判定
    • SEV1: 本番完全停止、決済系エラー、データ破損の可能性
    • SEV2: 本番の一部機能停止、一部ユーザー影響
    • SEV3: dev 環境障害、監視アラートのみ
  3. SEV1/2 は即エスカレーション(Discord #p1-ops / #p0-alerts / 担当者 DM)。Parky では Slack は使用しない (Discord one-stop)。

Triage 判定フロー

flowchart TD
  A[アラート受信 / 異常検知] --> B{本番 user に影響あるか?}
  B -- No --> C{dev / 監視のみ?}
  B -- Yes --> D{影響大
全停止 / データ損失 / セキュリティ} C -- Yes --> SEV3[SEV3 / P2
#p2-deploys
翌営業日対応] C -- No --> SEV2P[再評価] D -- Yes --> SEV1[SEV1 / P0
#p0-alerts + @here
15 分以内 ack] D -- No --> SEV2[SEV2 / P1
#p1-ops
4 時間以内対応] SEV1 --> R1[wrangler tail / Sentry 確認
+ rollback 判断] SEV2 --> R2[修正計画立案
営業時間内] SEV3 --> R3[朝の triage で確認] R1 --> POST[復旧後 postmortem 必須] R2 --> POST

初動コマンド集

Cloudflare Workers ログ(BFF api/、4 worker split 後)

split 後 (2026-04-30 ~) は worker ごとに --config を指定。対象 worker を絞ってからの方が log 量が現実的。

cd parky/api

# 対象 worker / env を選択
npx wrangler tail --config wrangler.public.toml   --env prod   # mobile API
npx wrangler tail --config wrangler.admin.toml    --env prod   # admin portal
npx wrangler tail --config wrangler.marketing.toml --env prod  # marketing portal
npx wrangler tail --config wrangler.store-sync.toml --env prod # store-sync cron

deploy 直後の incident なら wrangler deployments list --config <toml> --env <env> で 直前の version ID を控え、必要なら npx wrangler rollback --config <toml> --env <env> で 即時切り戻し。緊急 incident 中の rollback は rollback-runbook.html + scripts/deploy/rollback.sh 経由が推奨 (Discord 通知 + canary 中断まで自動)。

GitHub Actions 状態

gh run list --limit 10
gh run view <run-id> --log-failed

Supabase DB 接続確認

OP_SERVICE_ACCOUNT_TOKEN=$(cat ~/.op/sa_token.txt) op run -- \
  psql "$SUPABASE_DB_URL" -c "select 1"

Cloudflare Pages デプロイ状態

通知が届かなかった疑いがあるとき (DLQ 確認)

「Discord に alert が来てない」「Sentry alert ルールが発火したが気付かなかった」等の場合、admin.notification_failures を確認する (notification-strategy.md §7 Layer 3 永続化先)。

-- 直近 24h で配信失敗した通知 (channel / severity / error message)
SELECT attempted_at, channel, severity, title, http_status, retry_count, error_message
  FROM admin.notification_failures
 WHERE attempted_at >= NOW() - INTERVAL '24 hours'
 ORDER BY attempted_at DESC
 LIMIT 50;

-- P0 で email backup が送られたか確認 (Discord 落ちで email に流れたケース)
SELECT attempted_at, title, fallback_email_sent, error_message
  FROM admin.notification_failures
 WHERE severity = 'P0' AND status = 'failed'
 ORDER BY attempted_at DESC;

-- Discord 自体の障害を疑うとき: HTTP status の集計
SELECT http_status, COUNT(*) AS n
  FROM admin.notification_failures
 WHERE attempted_at >= NOW() - INTERVAL '1 hour'
 GROUP BY http_status
 ORDER BY n DESC;

DLQ には full Discord payload が JSONB で残っているので、必要なら手動 replay も可能 (curl で webhook URL に payload を再 POST)。週次自動 digest は月曜 18:00 JST に #p3-insights に投稿される。

エスカレーションパス

詳細は oncall.md §5 (1 人運用フェーズのフロー / Primary 不在パターン / Phase 3 rotation)。簡略版:

  1. 一次対応者(気付いた担当) → 状況を #p1-ops (P1) または #p0-alerts (P0) に投下、:eyes: reaction で ack
  2. SEV1/2 (P0/P1) は incident 開始時刻 (JST) を #p0-alerts に thread で書く (postmortem の timeline 起点)
  3. ユーザー影響が継続 → status page 告知 (Phase 2 で構築予定)、または LP / X で暫定告知

対応後

  • 事後: docs/ops/postmortems/YYYY-MM-DD-<title>.md を作成 (テンプレート: postmortem-template.md)
  • 再発防止: AI (action item) を SMART 形式で起こし、Owner / 期限 / 検証方法を明記
  • migration / runbook / 監視を更新

TODO:

  • ポストモーテムテンプレート整備 — postmortem-template.md
  • オンコールローテーション明文化 — oncall.md (1 人運用フェーズの SLA / iPhone push 二重化 / Phase 3 で rotation 開始)
  • PagerDuty / Opsgenie 連携検討 — MAU 1 万到達後に再評価 (oncall.md §8 Phase 2)

関連 docs

↗ Source markdown (incident-response.md)