Skip to content

通知設定カスタマイズ

概要

ユーザーが通知の受信方法を柔軟にカスタマイズできる設定機能を定義する。 チャネル別ON/OFF、通知頻度(即時/ダイジェスト)、Quiet Hours(通知抑制時間帯)を提供し、通知疲れを防止する。


1. 通知設定データモデル

user_notification_settings テーブル

user_notification_settings
├── id: UUID (PK)
├── user_id: FK → users (UNIQUE)
├── global_enabled: boolean (default true)
├── quiet_hours_enabled: boolean (default false)
├── quiet_hours_start: time (default '22:00')
├── quiet_hours_end: time (default '08:00')
├── timezone: varchar (default 'Asia/Tokyo')
├── digest_enabled: boolean (default false)
├── digest_schedule: enum (DAILY_MORNING, DAILY_EVENING, WEEKLY) (default DAILY_MORNING)
├── digest_time: time (default '09:00')
├── created_at: timestamp
└── updated_at: timestamp

user_notification_channel_settings テーブル

user_notification_channel_settings
├── id: UUID (PK)
├── user_id: FK → users
├── channel: enum (SLACK, DISCORD, EMAIL, IN_APP)
├── enabled: boolean (default true)
├── created_at: timestamp
└── updated_at: timestamp
UNIQUE(user_id, channel)

user_notification_trigger_settings テーブル

user_notification_trigger_settings
├── id: UUID (PK)
├── user_id: FK → users
├── trigger_type: enum (全トリガー種別)
├── channel: enum (SLACK, DISCORD, EMAIL, IN_APP)
├── enabled: boolean (default: マトリクスのデフォルト値)
├── frequency: enum (INSTANT, DIGEST, OFF) (default INSTANT)
├── created_at: timestamp
└── updated_at: timestamp
UNIQUE(user_id, trigger_type, channel)

2. 設定画面UI仕様

2.1 グローバル設定

┌─────────────────────────────────────────────────┐
│ 通知設定                                         │
├─────────────────────────────────────────────────┤
│                                                   │
│ ■ 全体設定                                        │
│                                                   │
│   通知を受け取る           [====ON====]            │
│                                                   │
│   タイムゾーン             [Asia/Tokyo     ▼]      │
│                                                   │
│ ■ Quiet Hours(通知抑制時間)                      │
│                                                   │
│   Quiet Hoursを有効にする  [====ON====]            │
│   開始時刻                 [22:00]                 │
│   終了時刻                 [08:00]                 │
│   ※ Critical通知はQuiet Hours中も配信されます      │
│                                                   │
│ ■ ダイジェスト配信                                 │
│                                                   │
│   ダイジェストを有効にする [===OFF====]             │
│   配信スケジュール         [毎朝 9:00      ▼]      │
│                                                   │
└─────────────────────────────────────────────────┘

2.2 チャネル別設定

┌─────────────────────────────────────────────────┐
│ チャネル別受信設定                                 │
├─────────────────────────────────────────────────┤
│                                                   │
│   チャネル        ステータス    アクション          │
│   ─────────────────────────────────────────       │
│   Slack           接続済み     [====ON====]        │
│   Discord         接続済み     [====ON====]        │
│   メール          verified     [====ON====]        │
│   プラットフォーム 常時有効     [====ON====]        │
│                                                   │
│   ※ Slack/Discordの連携は「アカウント連携」        │
│     ページから設定してください                      │
│                                                   │
└─────────────────────────────────────────────────┘

2.3 トリガー別詳細設定

┌──────────────────────────────────────────────────────────────┐
│ 通知タイプ別設定                                              │
├──────────────────────────────────────────────────────────────┤
│                                                                │
│ ▼ Issue ライフサイクル                                         │
│                                                                │
│   通知タイプ           Slack  Discord  メール  PF内   頻度     │
│   ─────────────────────────────────────────────────────       │
│   新規Issue公開         ―      [✓]     [✓]    [✓]   即時 ▼   │
│   Issue着手            [✓]     ―      [ ]    [✓]   即時 ▼   │
│   MR提出              [✓]     ―      [ ]    [✓]   即時 ▼   │
│   レビューFB            ―      [✓]     [✓]    [✓]   即時 ▼   │
│   承認・報酬確定       [✓]     [✓]     [✓]    [✓]   即時 ▼   │
│   期限アラート(24h前)  [✓]     [✓]     [✓]    [✓]   即時 ▼   │
│   予算超過アラート     [✓]     ―      [✓]    [✓]   即時 ▼   │
│   レビュー滞留(3日)   [✓]     ―      [✓]    [✓]   即時 ▼   │
│                                                                │
│ ▼ 補助通知                                                     │
│                                                                │
│   コメント追加         [ ]     [ ]     [ ]    [✓]   DG  ▼   │
│   Issue取り下げ         ―      [✓]     [✓]    [✓]   即時 ▼   │
│   報酬支払完了          ―      [✓]     [✓]    [✓]   即時 ▼   │
│   新規プロジェクト      ―      [✓]     [ ]    [✓]   DG  ▼   │
│                                                                │
│   [✓] = 有効  [ ] = 無効  ― = 変更不可(対象外)                │
│   頻度: 即時 = リアルタイム / DG = ダイジェスト                 │
│                                                                │
│           [ デフォルトに戻す ]  [ 保存する ]                    │
│                                                                │
└──────────────────────────────────────────────────────────────┘

3. 設定API

エンドポイント

MethodPath説明
GET/api/v1/users/me/notification-settings現在の通知設定取得
PUT/api/v1/users/me/notification-settingsグローバル設定更新
GET/api/v1/users/me/notification-settings/channelsチャネル別設定取得
PUT/api/v1/users/me/notification-settings/channels/{channel}チャネル別設定更新
GET/api/v1/users/me/notification-settings/triggersトリガー別設定取得
PUT/api/v1/users/me/notification-settings/triggersトリガー別設定一括更新
POST/api/v1/users/me/notification-settings/resetデフォルトにリセット

リクエスト/レスポンス例

GET /api/v1/users/me/notification-settings

json
{
  "global_enabled": true,
  "quiet_hours": {
    "enabled": true,
    "start": "22:00",
    "end": "08:00"
  },
  "timezone": "Asia/Tokyo",
  "digest": {
    "enabled": false,
    "schedule": "DAILY_MORNING",
    "time": "09:00"
  },
  "channels": {
    "SLACK": { "enabled": true, "connected": true },
    "DISCORD": { "enabled": true, "connected": true },
    "EMAIL": { "enabled": true, "verified": true },
    "IN_APP": { "enabled": true }
  },
  "triggers": [
    {
      "trigger_type": "ISSUE_PUBLISHED",
      "settings": {
        "SLACK": { "enabled": false, "frequency": "INSTANT", "editable": false },
        "DISCORD": { "enabled": true, "frequency": "INSTANT", "editable": true },
        "EMAIL": { "enabled": true, "frequency": "DIGEST", "editable": true },
        "IN_APP": { "enabled": true, "frequency": "INSTANT", "editable": false }
      }
    }
  ]
}

PUT /api/v1/users/me/notification-settings/triggers

json
{
  "triggers": [
    {
      "trigger_type": "ISSUE_PUBLISHED",
      "channel": "EMAIL",
      "enabled": false,
      "frequency": "OFF"
    },
    {
      "trigger_type": "COMMENT_ADDED",
      "channel": "DISCORD",
      "enabled": true,
      "frequency": "DIGEST"
    }
  ]
}

4. 通知配信ロジック

配信判定フロー

[通知イベント発生]


[対象ユーザー特定] ← マトリクスのロール定義


[グローバル設定チェック]
    │ global_enabled = false → 配信しない

[チャネル別設定チェック]
    │ channel.enabled = false → そのチャネルをスキップ

[トリガー別設定チェック]
    │ trigger.enabled = false → そのチャネルをスキップ
    │ trigger.frequency = DIGEST → ダイジェストキューに追加
    │ trigger.frequency = INSTANT → 即時配信

[Quiet Hoursチェック]
    │ Quiet Hours内 AND 優先度 ≠ CRITICAL → ダイジェストキューに追加
    │ Quiet Hours外 OR 優先度 = CRITICAL → 即時配信

[配信実行]

優先度によるオーバーライド

一部の通知は、ユーザー設定に関係なく配信を強制する。

優先度オーバーライドルール
CRITICALQuiet Hours を無視して即時配信。チャネルOFF設定は尊重する。
HIGHQuiet Hours 中はダイジェストに回す。ユーザー設定を尊重。
MEDIUM全てのユーザー設定を尊重。
LOW全てのユーザー設定を尊重。デフォルトでダイジェスト。

5. ダイジェスト配信

ダイジェスト集約ルール

設定配信タイミング集約期間
DAILY_MORNING毎朝 (設定時刻)前日の設定時刻〜当日の設定時刻
DAILY_EVENING毎夕 (設定時刻)当日朝〜当日の設定時刻
WEEKLY毎週月曜 (設定時刻)前週月曜〜当週月曜

ダイジェストメッセージ形式

メール:

件名: [Issue Outsource] 通知ダイジェスト - 2026/03/28

━━━━━━━━━━━━━━━━━━━━━━━
📋 新規Issue (3件)
━━━━━━━━━━━━━━━━━━━━━━━
• #142 React コンポーネントリファクタリング - ¥15,000 (期限: 4/5)
• #143 API エラーハンドリング改善 - ¥8,000 (期限: 4/3)
• #144 テストカバレッジ向上 - ¥12,000 (期限: 4/7)

━━━━━━━━━━━━━━━━━━━━━━━
💬 コメント (5件)
━━━━━━━━━━━━━━━━━━━━━━━
• #140 に田中さんからコメント: "LGTMです!細かい..."
• #141 に佐藤さんからコメント: "修正方針について..."
  ...他3件

━━━━━━━━━━━━━━━━━━━━━━━
詳細はプラットフォームでご確認ください:
https://outsource.example.com/notifications

Slack/Discord: 同様の構造をBlock Kit / Embedで表現する(1メッセージにまとめる)。


6. アカウント連携

Slack連携

  1. プラットフォーム設定画面で「Slackと連携」ボタンをクリック
  2. Slack OAuth認可フローを実行
  3. ユーザーのSlack IDを user_external_accounts テーブルに保存
  4. 以降、Slack通知はそのユーザーへのDM or チャネルメンションで配信

Discord連携

  1. プラットフォーム設定画面で「Discordと連携」ボタンをクリック
  2. Discord OAuth2認可フローを実行
  3. ユーザーのDiscord IDを user_external_accounts テーブルに保存
  4. 以降、Discord通知はサーバー内でのメンション or DMで配信

user_external_accounts テーブル

user_external_accounts
├── id: UUID (PK)
├── user_id: FK → users
├── provider: enum (SLACK, DISCORD, GITLAB)
├── external_id: varchar (Slack/Discord ユーザーID)
├── external_username: varchar
├── access_token: varchar (encrypted)
├── refresh_token: varchar (encrypted, nullable)
├── token_expires_at: timestamp (nullable)
├── connected_at: timestamp
├── created_at: timestamp
└── updated_at: timestamp
UNIQUE(user_id, provider)

7. 管理者設定

システム全体の通知設定

管理者は以下をシステムレベルで制御できる。

設定項目説明デフォルト
通知送信の有効/無効システム全体の通知を一時停止有効
デフォルトチャネル設定新規ユーザーの初期チャネル設定マトリクスに準拠
ダイジェスト配信可否ダイジェスト機能の有効/無効有効
Quiet Hours 強制設定全ユーザーに適用するQuiet Hours無効
最大リトライ回数配信失敗時の最大リトライ3回
リトライ間隔リトライ間のバックオフ設定5分, 10分, 30分

通知テンプレート管理

管理者はプラットフォーム管理画面から通知テンプレートを編集可能。

  • テンプレートはYAML形式で管理
  • プレースホルダー変数一覧をUIで確認可能
  • プレビュー機能で送信前に表示を確認
  • バージョン管理(テンプレート変更履歴を保持)

8. 通知ログ・監査

notification_logs テーブル

notification_logs
├── id: UUID (PK)
├── notification_id: FK → notifications
├── channel: enum
├── status: enum (PENDING, SENT, DELIVERED, FAILED, BOUNCED)
├── error_message: text (nullable)
├── retry_count: int
├── external_message_id: varchar (Slack ts / Discord message_id)
├── sent_at: timestamp
├── delivered_at: timestamp (nullable)
├── created_at: timestamp
└── updated_at: timestamp

管理ダッシュボード指標

指標説明
配信成功率チャネル別の配信成功率
平均配信遅延トリガー発生〜配信完了の平均時間
ダイジェスト利用率ダイジェスト設定を有効にしているユーザーの割合
チャネル別利用率各チャネルの有効化率
エラー発生率配信失敗率とエラー種別内訳
Quiet Hours 利用率Quiet Hoursを設定しているユーザーの割合