通知戦略 — Severity / Channel / Source 設計

このドキュメントが Parky における通知設計の SSoT (Single Source of Truth)。 個別 source の手順 (Sentry alert rule / Synthetic healthcheck / Incident response) は 別 doc に詳細を持つが、Severity 区分・Channel 振り分け・Format 標準・Anti-pattern は すべて本 doc に従う。新規 alert を追加するときも本 doc の 4 軸 (severity / channel / format / dedup) を必ず守ること。


1. 設計原則 — 1 行で

Severity 4 段 (P0/P1/P2/P3) を Discord 4 channel に 1 対 1 マッピング。各 source は severity に応じて自動振り分け。Stripe 流 SLA + Linear 流 silent-by-default + Cloudflare 流 native notification のハイブリッド。1 人運用 / pre-launch に最適化。


2. Severity Taxonomy

Severity 名称 判断基準 SLA Mention
P0 Critical 本番 user 影響 / データ損失 / セキュリティ侵害 / 手動復旧必須 15 分以内 @here 必須
P1 High 本番一部影響 or 業務支障、放置で P0 化、自動 retry でしのげる 4 時間以内 なし
P2 Info 確認必要だが緊急ではない、自動回復済 or 進捗通知 翌営業日 なし
P3 Digest 個別 alert は不要、定期サマリーで把握すれば十分 週次 review なし

判定フロー

  1. 本番 user に影響あるか? → Yes なら最低 P1、影響大 (全停止 / データ損失) なら P0
  2. 放置で P0 化するか? → Yes なら P1
  3. 個別に見る価値あるか? → Yes なら P2、No なら P3 (digest)

1 人運用での簡略化: P0 のみ通知音 ON / mention 有り。P1 はサイレント通知 (見たら対応)。 P2 / P3 は寝かせて朝チェック。これにより「夜中に起きる必要があるのは P0 のみ」が明確化する。


3. Discord Channel 設計

通知 channel は 2 軸構成 で設計する:

  • A. Operational alert (4 channel) — システム異常・運用イベント。Severity (P0/P1/P2/P3) と 1 対 1 マッピング。
  • B. Business workflow event (N channel, topic 別) — 業務フローのトリガー (新規 task / 申請 / 重要 user action 等)。severity ではなく topic で分類。

両者は 完全に分離 する。Business event を operational channel に混ぜると alert 疲れの典型 anti-pattern (Stripe / Linear で確立された原則)。

A. Operational alert channels (severity-based)

Severity と 1 対 1 マッピング。1 人運用なら source 別 (Sentry / GHA / CF) 分割よりも severity 別の方が認知負荷が低い (Linear / Vercel 同パターン)。

Channel Severity Mention 想定頻度 反応 SLA
#parky-alerts P0 @here 必須 月 0-3 件 15 分以内
#parky-ops P1 なし 週 5-20 件 4 時間以内
#parky-deploys P2 なし 日 2-10 件 翌営業日
#parky-insights P3 なし 週 1 件 + 月 1 件 週次 review

B. Business workflow event channels (topic-based)

Channel Topic Severity 相当 Mention 想定頻度
#parky-admin-tasks 管理者向け新規 task / 緊急 task P2 (info)、urgency=high で P1 相当 なし 日 1-10 件

将来追加候補 (launch 後):

Channel Topic
#parky-owner-applications 新規オーナー申請 / 書類提出
#parky-revenue 大口決済 / 売上速報
#parky-signups 新規ユーザー登録 (digest)
#parky-support サポート chat 着信

Business event channel の設計原則:

  1. 必ず severity を付与 (上表の "Severity 相当" 列) — 同じ format 標準を使い、視覚的に operational alert と一貫させる
  2. 1 topic = 1 channel (混ぜない) — 「タスク全部」じゃなく「admin タスク作成」「owner 申請」のように具体的に
  3. mention は基本 false — operational P0 だけが mention、business event は mute された情報源
  4. 新規 channel 追加時は本 doc の表に追記必須 — channel 数が増えすぎないようゲートする (5+ になったら統合検討)
  5. alert ではなく "event log" として扱う — 必ずしも対応必須ではなく、業務状況を見渡す目的

各 channel の用途まとめ

#parky-alerts (P0)

本番障害、データ損失、セキュリティ侵害、Critical CVE。15 分以内に確認 + Discord で「対応開始」リアクション or reply。

#parky-ops (P1)

業務に支障あるが緊急じゃない、修正計画立てる対象。営業時間内、4 時間以内に対応。

#parky-deploys (P2)

進捗確認、後追いで見ればよい情報。翌営業日に確認 OK、対応不要も多い。

#parky-insights (P3)

定期サマリー、傾向把握、business KPI。週次 review でまとめて見る。


4. Source × Channel × Action 完全表

新規 alert を追加するときは必ずこの表に行を足してから実装すること。各行が「① system / ② 頻度 / ③ check / ④ 条件 / ⑤ メッセージ / ⑥ channel / ⑦ action」の 7 軸を満たす。

P0 → #parky-alerts

① system ② 頻度 ③ check 対象 ④ 条件 ⑤ メッセージ内容 ⑦ アクション
Sentry (parky-api prod) 連続 (event drive) error イベント数 5xx が 5分窓で 50件超 (=10/min) [P0] parky-api 5xx burst (52/5min) + Sentry issue link + runbook 即 Sentry 開く → wrangler tail → Worker rollback 判断
Sentry (全 prod project) 1時間粒度 Error budget burn rate 14.4× (1h で 30日 budget の 2% 焼失) [P0] Error budget fast burn 14.4× + SLO link SLO doc → 障害源特定 → deploy freeze 検討
Synthetic healthcheck 5 分 cron api.parky.co.jp/healthz 連続 2 回 fail (5-10 分継続) [P0] prod healthz down + workflow run link + runbook wrangler tail prod → Hyperdrive/R2 切り分け → status page 更新
Cloudflare Notifications リアルタイム Workers script platform-side outage [P0] CF Workers outage detected + CF status link CF status page → ユーザー告知
Cloudflare Notifications リアルタイム WAF / DDoS 大規模攻撃検知 [P0] WAF blocking surge + analytics link WAF rule 確認 → IP rate limit 判断
Supabase Cron 1 分粒度 DB 接続 prod DB 接続喪失 (test query fail) [P0] Supabase prod DB unreachable + Supabase dashboard Supabase status → connection pool 確認
GitHub security alert リアルタイム secret scan secret leak detected (push に key 等) [P0] Secret leaked in commit <sha> + GitHub Security tab link 即 rotate → git history purge 判断

P1 → #parky-ops

① system ② 頻度 ③ check 対象 ④ 条件 ⑤ メッセージ内容 ⑦ アクション
Sentry 5 分粒度 new issue rate 新規 issue が 100/h 以上 [P1] New high-volume issue + Sentry link issue triage → fix sprint に追加
Sentry Performance 1 時間粒度 p95 latency 通常比 +50% [P1] p95 regression on /v1/... + Performance tab trace 確認 → 直近 deploy revert 判断
Synthetic healthcheck 5 分 cron dev-api.parky.co.jp/healthz 連続 2 回 fail [P1] dev healthz down + run link dev wrangler tail → 修正 push
GHA (deploy-*-prod) event drive workflow conclusion failure [P1] prod deploy failed: <workflow> + run link + last commit run log 確認 → re-run or fix → re-merge
GHA (E2E / lint / drift) event drive main branch 連続 fail 連続 3 回失敗 [P1] CI failing on main: <workflow> + run link 安定化 PR 作成、main の merge 凍結
DLQ monitor 5 分 cron Cloudflare Queue dead letter 蓄積 >10 件 [P1] DLQ accumulating: <queue> (<n> messages) + summary dead letter 内容確認 → re-enqueue or 修正
Cost monitor (週 1 cron) 週 1 月曜朝 各 service quota 80% 到達 (CF / Sentry / GH Actions / Supabase) [P1] <service> quota at 80% (X / Y) 使用パターン確認 → optimize or upgrade plan 判断
Cloudflare Notifications リアルタイム R2 / KV quota 80% 到達 [P1] R2 storage at 80% (X GB / Y GB) 古い object 削除 or plan upgrade
Dependabot event drive Critical CVE 新規 Critical CVE 発見 [P1] Critical CVE: <package> <version> + advisory link PR review → merge 判断
Supabase Cron 5 分 cron connection pool 使用率 >80% [P1] Supabase pool 85% (90/100) slow query 探索、pool size 拡張判断
Supabase Cron 1 時間 cron slow query p99 >1s [P1] Slow query spike: <query digest> EXPLAIN → index 追加

P2 → #parky-deploys

① system ② 頻度 ③ check 対象 ④ 条件 ⑤ メッセージ内容 ⑦ アクション
GHA (deploy-*-prod) event drive workflow conclusion success [P2] prod deploy success: <workflow> + commit / changelog link 任意で smoke test、通常は確認のみ
GHA (deploy-*-dev) event drive workflow conclusion success / failure [P2] dev deploy <result>: <workflow> + run link dev URL で動作確認
Sentry event drive new low-volume issue 新規 issue (<10/h) [P2] New issue: <title> + Sentry link 朝確認、優先度判定
Sentry event drive regression 解決済 issue が再発 [P2] Regression: <title> + last fix commit 該当 commit 調査
Migration apply event drive DB migration 適用 apply success [P2] Migration applied: <filename> (env: <env>) 適用ログ確認のみ
Workers Versioned Uploads (将来) gradual rollout step rollout 進捗 10% → 50% → 100% 遷移 [P2] Rollout progressed: 10%→50% (<version>) error rate 増加なければ続行
Dependabot event drive High / Medium CVE 新規 High/Medium CVE [P2] High CVE: <package> + advisory 翌週の dep update PR にまとめる
Cloudflare Notifications event drive Pages / Worker deploy fail platform-side fail [P2] CF Pages deploy failed: <project> + CF dashboard CF UI で deploy log 確認

Business events → topic-based channels

① system ② 頻度 ③ check 対象 ④ 条件 ⑤ メッセージ内容 ⑥ channel ⑦ アクション
BFF (bff/admin/tasks.ts) event drive admin_tasks INSERT is_new=true (xmax = 0 で判定) [P2] Admin task created: <task_kind> + ref_id / urgency / memo / due_at #parky-admin-tasks 管理者ポータルで該当タスク確認
BFF (owner inquiry submit) event drive 同上 (auto-task) 同上 [P2] Admin task created + applicant / lot / assets #parky-admin-tasks 書類確認 + approve/reject 判断
BFF future: owner application event drive owner_inquiries INSERT 新規申請 [P2] Owner application: <name> #parky-owner-applications (将来) LP 経由申請の review
BFF future: revenue event drive revenue_transactions INSERT 1件 ≥ 1万円 [P2] Big revenue: ¥X,XXX #parky-revenue (将来) 大口決済の確認
BFF future: signups 日次 cron app_users INSERT 過去 24h 集計 [P2] Daily signups: 12 #parky-signups (将来) 集計 trend 確認

P3 → #parky-insights

① system ② 頻度 ③ check 対象 ④ 条件 ⑤ メッセージ内容 ⑦ アクション
GHA cron (週 1 月曜朝) 週 1 (cron) Sentry top issues 過去 7 日 sample [P3] Weekly Sentry digest: top 10 / new N / resolved M + dashboard link 月曜 review で確認、優先度割当
GHA cron (週 1) 週 1 synthetic healthcheck history 過去 7 日 fail rate [P3] Weekly uptime: dev 99.7% / prod 100% trend 確認
GHA cron (週 1) 週 1 GH Actions usage 過去 7 日 minutes 消費 [P3] GH Actions: 412 min used (Free 2000 残) 圧縮検討タイミング
GHA cron (月 1, 1 日) 月 1 全 service cost 各 service 月額 [P3] Monthly cost: CF $0 / Supabase $0 / Sentry $0 / Mapbox $X コスト review
Dependabot 週 1 Low CVE + outdated 過去 7 日 まとめ [P3] Weekly deps: 3 low CVE / 12 outdated + PR list 週次でまとめて update PR
Supabase Cron 週 1 storage growth 過去 7 日 増分 [P3] DB storage: +120MB / week (total 480MB) scale plan 判断
Business KPI (launch 後) 週 1 DAU/MAU/signup/revenue 過去 7 日 集計 [P3] Weekly KPI: DAU 1,234 / signup +56 / 駐車場登録 +12 trend 確認

5. Alert Format 標準

必須 field (1 つでも欠けたら NG)

Field 内容
severity badge title 先頭に [P0]/[P1]/[P2]/[P3] + 絵文字 :rotating_light: [P0] / :warning: [P1] / :information_source: [P2] / :bar_chart: [P3]
service 影響を受けるシステム名 parky-api (prod) / parky-admin (dev)
symptom 1 行で症状を要約 5xx errors burst (52/min, threshold 10)
env dev / stg / prod の明示 env: prod
triggered_at UTC + JST 両方記載 2026-04-29 10:23 JST (01:23 UTC)
runbook 対応手順への直リンク [runbook: incident-response.md#sev1](...)
dashboard / log 該当する観測 dashboard URL [Sentry issue](https://...) / [Workflow run](https://github.com/.../runs/123)

任意 field

  • owner: 主担当 (1 人運用なら省略 or dev@parky.co.jp 固定)
  • related_alerts: 同 window で発火した別 alert ID (cascade 検知用)
  • auto_resolve: 自動解決された時刻 (transient flap 等)

Discord embed の実例 (P0)

{
  "content": "@here :rotating_light: **[P0] parky-api (prod) 5xx burst**",
  "embeds": [{
    "title": "Sentry alert: 5xx errors burst",
    "color": 14431557,
    "fields": [
      { "name": "Service",   "value": "parky-api (prod)", "inline": true },
      { "name": "Env",       "value": "prod",             "inline": true },
      { "name": "Symptom",   "value": "52 errors / 5min (threshold: 50)" },
      { "name": "Sentry",    "value": "[Issue PARKY-123](https://parky-72.sentry.io/issues/123)" },
      { "name": "Runbook",   "value": "[incident-response.md#sev1-checklist](https://github.com/...)" },
      { "name": "Triggered", "value": "2026-04-29 10:23 JST (01:23 UTC)", "inline": true }
    ],
    "footer": { "text": "Parky Sentry alert · rule R-01" },
    "timestamp": "2026-04-29T01:23:00Z"
  }]
}

Discord embed 色コード (severity 視覚化)

Severity Decimal Hex
P0 14431557 #DC2626 red
P1 15105570 #E67E22 orange
P2 3447003 #3498DB blue
P3 9807270 #95A5A6 gray

6. Dedup / Suppression ルール

ルール 適用条件 挙動
Frequency cap 同一 alert rule 5 分に最大 1 回 (Sentry の "At most once per X minutes" 機能で実装)
Flap retry healthcheck / synthetic monitor 連続 2 回 fail で初めて発火 (synthetic-healthcheck.yml 既存実装)
Auto-resolve transient な障害 (5 分以内に回復) 後続 message を thread reply で「自動回復」と通知、新規 alert は出さない
Maintenance window 計画 deploy / migration 中 事前に gh workflow run notify-suppress.yml --duration 30m で全通知 mute (Phase 3)
Cascade suppression 1 つの根本原因が複数 alert を発火 同 time window (5 分) で 5 件以上の alert は最初の 1 件のみ通知、残りは 5 alerts in window, see thread 形式に集約
Severity dedup 同 issue が P0 → 後で P1 にダウングレード thread reply で severity 変化を通知、新規 alert は出さない
Dev fail tolerance dev 環境の transient failure 連続 5 回 fail で初めて P1 に格上げ (dev は壊れて当たり前を許容)

夜中 mute は 1 人運用では不要: Stripe / GitHub は on-call rotation があるので "wake up only for P0" は意味あるが、Parky 1 人運用なら寝てる間の P0 も「起きてから」対応で OK。むしろ dedup を強くして「鳴ったら 100% 本物」状態を作る方が効果大。


7. Failure handling & resilience — Webhook 失敗時の振る舞い

設計判断: Discord 直 + retry + DLQ (P0 のみ email backup)

「より可用性の高い relay サービス (PagerDuty / Opsgenie / 自前 Worker) を経由する」案は delivery 目的だけなら採用しない。理由:

反対理由 詳細
Relay 自体が SPOF hop が増えると availability は乗算で減る (99.9% × 99.95% = 99.85%)
可視性が落ちる 失敗時「Discord/relay/Worker のどこ?」の切り分けに調査時間が増える
PagerDuty 等の本当の価値は配信ではない on-call rotation / escalation / dedup / runbook 機能。最終 hop は結局 Discord/Slack/Email/SMS で同じ
コスト過大 $9-19/user/mo を 1 人運用で払うなら Sentry Team plan upgrade の方が ROI 高い
複雑さ vs 利益 多 hop で staging テスト難、設定 drift 発生しやすい

採用するアーキテクチャは 3 層防御 + 多チャネル冗長化 (P0 のみ):

[Layer 1] Direct Discord webhook
    ↓ 失敗 (5xx / 429 / network error)
[Layer 2] Exponential backoff retry (3 attempts: 1s → 4s → 16s)
    ↓ 全失敗
[Layer 3] DLQ 永続化 (admin.notification_failures table)
    + P0 のみ email fallback (Resend, 別物理経路で送信)
    ↓ 後で
[Layer 4] 週次 cron が DLQ 集計 → #parky-insights に digest

故障モード別の挙動

故障モード Layer 1 Layer 2 (retry) Layer 3 (DLQ + email) 結果
Discord rate limit (429) 失敗 retry 後成功 触らず 数秒遅延だけ
Discord transient 5xx 失敗 retry 後成功 触らず 数秒遅延だけ
Discord 完全停止 (SLA 99.95% = 22min/月) 失敗 全 retry 失敗 DLQ 記録 + (P0 なら email 送信) DLQ で後で見える、P0 は email で届く
Webhook URL revoked 失敗 (404) retry しない (4xx 即 DLQ) DLQ 記録 + (P0 なら email) DLQ digest で気付く、P0 は email で届く
Worker → Discord network 障害 失敗 retry で大半復旧 全失敗時のみ DLQ ほぼ自動回復
Payload 不正 (4xx) 失敗 retry しない DLQ 記録 dev で発見、prod に出さない
Discord + Email 同時停止 失敗 全 retry 失敗 DLQ 記録のみ 確率限りなく 0、対策不要

Retry policy (詳細)

HTTP ステータス Retry? 理由
200 / 204 しない 成功
429 (rate limit) する Discord 30 msg/min/webhook 制限。指数 backoff で待つ
5xx する Discord 側の transient
408 / 499 (timeout) する network transient
4xx (それ以外) しない payload 不正 / URL 失効、retry しても同じ
network error (fetch reject) する TLS / DNS transient

Backoff: 1s → 4s → 16s (4× 倍増)。最大 3 回試行 = 21 秒以内に決着。

P0 backup email の設計

  • 対象: severity = P0 のみ (P1/P2/P3 は DLQ 記録のみで email しない、過剰通知防止)
  • provider: 既存 Resend (lib/transactional-email.ts)。物理経路が Discord と完全分離 (Resend 障害 ≠ Discord 障害)
  • 送信先: dev@parky.co.jp (固定、複数人運用時に env で多人数化)
  • Subject: [P0 BACKUP] <title> で先頭明示 (重複時の dedup 容易化)
  • Body: HTML + text 両対応、Discord embed と同じ field を平文化
  • 失敗時の挙動: email も失敗したら DLQ の fallback_email_sent=false のまま、digest で目立つ
  • 将来拡張: 別 provider (SES / SendGrid) を二段目 fallback として追加検討、launch 後の規模次第

DLQ schema (admin.notification_failures)

用途
id UUID PK
attempted_at TIMESTAMPTZ 最初の試行時刻
channel TEXT ALERTS / OPS / DEPLOYS / INSIGHTS / ADMIN_TASKS
severity TEXT P0 / P1 / P2 / P3
title TEXT alert title
summary TEXT 1 行要約
payload JSONB full Discord payload (replay できる shape)
error_message TEXT 最後のエラー文字列
http_status INT 最後の HTTP ステータス (network error は NULL)
retry_count INT 実施した retry 回数
status TEXT failed / replayed_success / manual_acknowledged
fallback_email_sent BOOLEAN P0 backup email を送ったか
source TEXT sentry / gha / admin-task / etc. (debugging 用)
created_at TIMESTAMPTZ 作成時刻

週次 DLQ digest cron

  • 配信先: #parky-insights (P3)
  • 頻度: 毎週月曜 09:00 UTC (JST 18:00) — HOURLY スロット同居
  • 内容: 過去 7 日 status='failed' の集計 (channel 別 / 件数 / top 3 エラーメッセージ)
  • 集計後: 該当行の status を manual_acknowledged に更新 (再 digest 防止)

8. アンチパターン

新規 alert / channel 設計時に以下を作らないこと:

  • 全部 1 channel に流す — P0 と info が同じ channel に並ぶと user は info の山から P0 を見つけられない、3 日で「もう見ない」状態に
  • @here を P1/P2 で使う — @here が無意味化、本当の P0 で誰も気付かない、P0 のみ mention を厳守
  • 同じ事象を複数 source から重複通知 — 例: 5xx burst で Sentry alert + healthcheck + GHA E2E fail が同時発火 → 3 通知、Cascade suppression 必須
  • Email + Discord 並行 — どちらか一本に絞る、Parky は Discord メイン、email は Sentry 個別 issue triage 用にだけ残す
  • Runbook link なし — 「何が起きたか」だけ書いて「どうすればいいか」が無いと寝起き / 移動中に対応できない、全 alert に runbook link 必須
  • 平文だけ (Discord embed 不使用) — 色 / icon / structured field がないと一瞥で severity 判別不可、必ず embed 形式
  • Quiet hours を 1 人運用で強制 — on-call rotation があるなら意味あるが、1 人運用では結局自分で見るので mute しても意味薄い、むしろ dedup を強化
  • Severity の判断を都度 — 各 alert で「これ P0?」を悩むのは時間の無駄、alert rule 作成時に severity を必ず固定、後で見直しは月次

9. テック企業ベンチマーク

会社 Severity 段階 Channel 戦略 Dedup 1 人運用への適用
Stripe SEV1/2/3 (15min/4h/24h SLA) severity 別 Slack channel + PagerDuty escalation Frequency cap + cascade detection そのまま 4 段に拡張可、PagerDuty は不要
GitHub SEV1-4 + Public service area × severity の matrix channels Datadog + custom dedup service area 分割は overkill、severity のみで十分
Linear P0/P1/P2/Info (silent-by-default) severity 別 Slack 1 channel each + opt-in subscription Linear notification engine Parky の理想形に最も近い
Vercel Critical / Warning / Info internal: severity 3 channels / external: status page Native dedup in Vercel platform 3 channel 構成で OK、status page は launch 後
Cloudflare Critical / Warning / Info / Healthy Notification destinations per severity (webhook / email / PagerDuty) Per-rule frequency setting built-in CF Notifications を活用
Plaid P0-P3 + Customer-facing customer-facing: status page / internal: 5 channels Datadog incident management customer-facing は status page を将来検討
Parky 採用 P0/P1/P2/P3 (Stripe 準拠) severity 別 4 Discord channels (Linear 同型) Frequency cap + flap retry + cascade group 1 人運用 / pre-launch 最適化

結論: Linear 流の severity-based 4 channel + Stripe 流の SLA + format 標準 + Cloudflare 流の native notification 活用 のハイブリッドを Parky で採用。


10. 実装ロードマップ

Phase 1 — 今週 (工数 2-3h)

  1. Discord channel 5 本作成: #parky-alerts / #parky-ops / #parky-deploys / #parky-insights / #parky-admin-tasks
  2. Webhook URL 5 本発行 → 1Password に保存
    • Vault: PJ|Parky
    • Item 名: Discord Webhook|#parky-alerts / #parky-ops / #parky-deploys / #parky-insights / #parky-admin-tasks
    • Field: url (secret)
  3. GH Secrets に登録: DISCORD_WEBHOOK_ALERTS / DISCORD_WEBHOOK_OPS / DISCORD_WEBHOOK_DEPLOYS / DISCORD_WEBHOOK_INSIGHTS / DISCORD_WEBHOOK_ADMIN_TASKS
    • 既存 DISCORD_HEALTHCHECK_WEBHOOK_URL は廃止 → DISCORD_WEBHOOK_OPS に統合
  4. Wrangler secrets に投入: DISCORD_WEBHOOK_ADMIN_TASKS を dev / prod に。api/src/env/bindings.ts に型宣言済み。
    cd parky/api
    wrangler secret put DISCORD_WEBHOOK_ADMIN_TASKS --env dev
    wrangler secret put DISCORD_WEBHOOK_ADMIN_TASKS --env prod
    
  5. Synthetic healthcheck workflow を severity-aware に改修: dev fail → OPS / prod fail → ALERTS
  6. Reusable workflow _notify-discord.yml 作成: severity / channel / message を input に取り、適切な webhook + format で送信
  7. 全 prod deploy workflow に if: failure() notify step 追加: _notify-discord.yml を使い OPS へ送信
  8. Admin task 通知の動作確認: 管理者ポータルから新規 task 作成 → #parky-admin-tasks に投稿されるか確認 (未投入なら warn log のみ)

Phase 2 — 1-2 週 (工数 4-6h)

  1. Sentry Discord native integration 設定: 2024+ で native 提供、12 alert rule 全てを severity に応じた channel に振り分け
  2. Cloudflare Notifications 設定: Workers outage / Pages deploy fail / R2 quota / WAF を該当 channel に webhook 配線
  3. DLQ monitor を OPS へ統合: DLQ_WEBHOOK_URLDISCORD_WEBHOOK_OPS に向け直し
  4. Cost / Quota 監視 cron 作成: 週 1 回 GH Actions で各 service API を叩いて集計、80% 超過で OPS
  5. Dependabot 通知整理: GitHub Settings → Notifications → Dependabot を email デフォルト → repo 内 weekly digest 化

Phase 3 — 1 ヶ月 (工数 6-8h)

  1. Supabase 健全性監視: pg_cron で pool / slow query / RLS violation 集計 → BFF endpoint → Discord webhook
  2. Weekly digest workflow: 月曜朝に Sentry + GHA + uptime + cost を集約 → INSIGHTS へ HTML サマリ
  3. Business KPI digest (launch 後): signup / DAU / 駐車場登録 etc. → INSIGHTS
  4. Maintenance window mute: scripts/notify/suppress.sh --duration 30m で全 webhook 一時無音化
  5. Status page (status.parky.co.jp): launch 後の customer-facing 透明性のため Better Uptime Public Status / Atlassian で構築

Phase 4 — 3 ヶ月 (工数 4h, 任意)

  1. Runbook automation: alert に Discord button (interactive component) 追加で "ack" / "runbook 開く" / "mute 30m" を 1 click 化
  2. Postmortem 自動雛形生成: P0 alert 解決後に GitHub Issue を自動生成、postmortem-template.md ベースで雛形プレフィル

11. コスト見積もり

項目 無料枠 Parky 想定使用量 追加コスト
Discord webhook 無制限 月 100-300 通知 $0
Sentry (Developer plan) 5K errors/mo + 10K performance pre-launch ~1K/mo / launch 後 5-30K/mo launch 後超過時 $26/mo (Team)
GH Actions (private repo) 2,000 min/mo healthcheck 1,440 min + notify 100 min + digest 50 min ≈ 1,600 min/mo Free 枠 80% (要圧縮)
Cloudflare Notifications Workers Free / R2 Free 枠内 monitor 数本 $0
Cloudflare Health Checks (本格化時) Pro plan 必要 1 monitor (api.parky.co.jp) $20/mo (Pro plan, 1 monitor 込)
Honeycomb (M-03 後) 20M events/mo (Free) pre-launch ~500K / launch 後 5-10M $0 (Free 内)
Supabase (現 Free) 500MB DB / 1GB bandwidth schema 投入のみ、データ少 launch 後 $25/mo (Pro plan + PITR)
Better Uptime / UptimeRobot (代替案) 10 monitors (Free) 2 monitor で十分 $0 (Free 枠内、Cloudflare Pro 不要)

段階別コスト

  • Phase 1-2 (現状): $0/mo (Discord + GH Actions + Sentry Dev + CF Notifications + Better Uptime Free)
  • launch 後 (~3 ヶ月): $25-50/mo (Supabase Pro + Sentry Team)
  • scale 後 (~6 ヶ月): $100-150/mo (CF Pro / Honeycomb Pro / 専用 monitor 等)

GH Actions 圧縮策: synthetic healthcheck cron を 5 分 → 10 分間隔に変更で月使用 720 → 360 min。Better Uptime Free (10 monitors / 3 分間隔) に丸ごと移行すれば GH Actions 0 min に。


12. シナリオ別の挙動例

シナリオ A: 平常時 (ローンチ前)

  • 月曜朝に #parky-insights で weekly digest 4-5 通
  • 日中に #parky-deploys で dev deploy 通知 5-10 通
  • #parky-ops #parky-alerts は基本無音

シナリオ B: dev healthcheck 1 回 fail

  • #parky-ops[P1] dev healthz down 1 通
  • 5 分後の次 cron で復活したら何も来ない (auto-resolve)

シナリオ C: prod に bad deploy

  • #parky-alerts[P0] prod healthz down (synthetic healthcheck)
  • #parky-alerts[P0] 5xx burst (Sentry)
  • → cascade suppression で 2 通目以降は thread reply に集約
  • #parky-ops[P1] prod deploy failed (post-deploy assert) (GHA)
  • 対応 → wrangler rollback → 5 分後 healthz 緑 → #parky-alerts thread に「auto-resolved」reply

シナリオ D: Critical CVE (例: lodash 脆弱性)

  • #parky-ops[P1] Critical CVE: lodash@4.17.x 1 通 + Dependabot PR link
  • 翌営業日に PR review → merge → #parky-deploys で deploy success 通知

13. 関連 doc

このドキュメントが SSoT。以下は本戦略に従って動く individual runbook:

監査根拠 (社内 work)

  • .work/parky/2026-04-29_001_parky_comprehensive_evaluation_v2.html — Operations 軸監査 (本戦略の動機)
  • .work/parky/2026-04-29_002_parky_notification_strategy.html — 本 doc の HTML 版 (visual reference)

変更履歴

  • 2026-04-29: 初版作成。既存 3 つの通知配線 (Sentry alert / DLQ / synthetic healthcheck) を整理し、Severity 4 段 + Discord 4 channel の framework を確立。
↗ Source markdown (notification-strategy.md)