# 通知設計書 50-neverShowAgain

## 概要

本ドキュメントは、VS Codeの通知システムにおける「今後表示しない」（neverShowAgain）機能の設計仕様を定義します。この機能は通知に対するユーザー設定を永続化し、同じ通知が繰り返し表示されることを防ぎます。

### 本通知の処理概要

特定の通知に対して「今後表示しない」オプションを提供し、ユーザーの選択をストレージに永続化する機能です。これにより、同じ通知が再度表示されることを防ぎます。

**業務上の目的・背景**：VS Codeは様々な情報・警告・推奨を通知として表示しますが、一度確認した通知が繰り返し表示されるとユーザー体験を損なうことがあります。「今後表示しない」機能により、ユーザーは自分にとって不要な通知を永続的に非表示にでき、より効率的な作業環境を構築できます。

**通知の送信タイミング**：neverShowAgainオプションが設定された通知が表示される際に、自動的に「Don't Show Again」アクションが追加されます。

**通知の受信者**：通知を受け取るすべてのユーザーが対象です。

**通知内容の概要**：元の通知メッセージに加えて、「Don't Show Again」ボタンが表示されます。

**期待されるアクション**：ユーザーは通知を確認し、今後同様の通知を表示したくない場合は「Don't Show Again」を選択します。

## 通知種別

アプリ内通知への機能追加（すべての通知レベルに適用可能）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 元の通知に依存 |
| リトライ | 無 |

### 送信先決定ロジック

neverShowAgainオプションが設定された通知を受け取るユーザーに対して、自動的に「Don't Show Again」アクションが追加されます。

## 通知テンプレート

### INeverShowAgainOptions

| プロパティ | 型 | 説明 |
|-----------|------|------|
| id | string | 通知を識別するためのユニークID |
| isSecondary | boolean (optional) | trueの場合、セカンダリアクションとして表示 |
| scope | NeverShowAgainScope (optional) | 設定の適用範囲 |

### NeverShowAgainScope

| 値 | 説明 |
|-----|------|
| WORKSPACE | 現在のワークスペースのみで非表示 |
| PROFILE | 同一プロファイルの全ワークスペースで非表示 |
| APPLICATION | 全プロファイル、全ワークスペースで非表示（デフォルト） |

### アクションボタン

| ボタン | 説明 | 位置 |
|-------|------|------|
| Don't Show Again | 今後この通知を表示しない | isSecondary: falseの場合はプライマリ、trueの場合はセカンダリ |

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| id | 通知識別子 | INeverShowAgainOptions.id | Yes |
| isSecondary | セカンダリ表示フラグ | INeverShowAgainOptions.isSecondary | No |
| scope | 適用スコープ | INeverShowAgainOptions.scope | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 通知表示 | notify/prompt | neverShowAgainオプションが設定されている | 「Don't Show Again」アクションを追加 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| すでに「Don't Show Again」選択済み | ストレージにIDが記録されている場合、元の通知自体が表示されない |

## 処理フロー

### 表示判定フロー

```mermaid
flowchart TD
    A[通知表示要求] --> B{neverShowAgainオプション存在?}
    B -->|No| C[通常の通知表示]
    B -->|Yes| D[ストレージ確認]
    D --> E{ID記録済み?}
    E -->|Yes| F[通知を抑止]
    E -->|No| G[Don't Show Againアクション追加]
    G --> H[通知表示]
    C --> I[終了]
    F --> I
    H --> J{ユーザー選択}
    J -->|Don't Show Again| K[ストレージに記録]
    J -->|その他| I
    K --> I
```

## データベース参照・更新仕様

### 参照テーブル一覧

| ストレージキー | 用途 | 備考 |
|--------------|------|------|
| notifications.doNotDisturbMode | 通知のDo Not Disturbモード | Applicationスコープ |
| notification.neverShowAgain.{id} | 個別通知の非表示設定 | スコープはNeverShowAgainScopeによる |

### 更新テーブル一覧

| ストレージキー | 操作 | 概要 |
|--------------|------|------|
| notification.neverShowAgain.{id} | SET | 「Don't Show Again」選択時にtrueを設定 |

### ストレージスコープの対応

| NeverShowAgainScope | StorageScope | StorageTarget |
|--------------------|--------------|---------------|
| WORKSPACE | WORKSPACE | MACHINE |
| PROFILE | PROFILE | USER |
| APPLICATION | APPLICATION | USER |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ストレージ書き込み失敗 | ストレージサービスエラー | エラーログ出力、通知表示は継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

## セキュリティ考慮事項

- ストレージに保存されるのは通知IDのみであり、通知内容は保存されない
- 通知IDは拡張機能から提供される可能性があるため、サニタイズが必要な場合がある

## 備考

- localize関数でローカライズされたテキスト：'neverShowAgain', "Don't Show Again"
- 多くの組み込み機能と拡張機能がこの機能を利用している
- Git拡張機能の「Git not found」通知など、ユーザーが明示的に設定を変更するまで非表示にできる通知に使用される

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

通知システムのインターフェースとneverShowAgainオプションを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | notification.ts | `src/vs/platform/notification/common/notification.ts` | INeverShowAgainOptions, NeverShowAgainScope |
| 1-2 | notification.ts | `src/vs/platform/notification/common/notification.ts` | INotificationProperties |

**読解のコツ**: NeverShowAgainScopeの3つの値（WORKSPACE, PROFILE, APPLICATION）がストレージのスコープに対応します。

#### Step 2: 通知の表示処理を理解する

通知モデルでのneverShowAgain処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | notifications.ts | `src/vs/workbench/common/notifications.ts` | NotificationViewItem, INotificationViewItem |
| 2-2 | notificationService.ts | `src/vs/workbench/services/notification/common/notificationService.ts` | NotificationService実装 |

**主要処理フロー**:
1. 通知が作成される際にneverShowAgainオプションを確認
2. ストレージから過去の選択を確認
3. 未選択の場合、「Don't Show Again」アクションを追加
4. 選択済みの場合、通知を抑止

#### Step 3: ストレージの使用を理解する

ストレージサービスとの連携を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | storage.ts | `src/vs/platform/storage/common/storage.ts` | IStorageService, StorageScope, StorageTarget |

### プログラム呼び出し階層図

```
notificationService.notify/prompt
    │
    └─ NotificationModel.addNotification
           │
           ├─ checkNeverShowAgain (ストレージ確認)
           │      └─ storageService.get
           │
           ├─ [if not set]
           │      └─ addNeverShowAgainAction
           │             └─ Action: "Don't Show Again"
           │
           └─ [if set]
                  └─ 通知を抑止
```

### データフロー図

```
[入力]               [処理]                    [出力]

通知要求         ───▶ neverShowAgainチェック  ───▶ 表示/抑止判定
(with options)         │                            │
                       ▼                            ▼
               ストレージ参照              ───▶ 過去の選択確認
                       │
                       ▼
               [if not set]              ───▶ アクション追加
                       │
                       ▼
               [on click]                ───▶ ストレージ更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| notification.ts | `src/vs/platform/notification/common/notification.ts` | ソース | 通知インターフェース定義 |
| notifications.ts | `src/vs/workbench/common/notifications.ts` | ソース | 通知モデル |
| notificationService.ts | `src/vs/workbench/services/notification/common/notificationService.ts` | ソース | 通知サービス実装 |
| notificationsCenter.ts | `src/vs/workbench/browser/parts/notifications/notificationsCenter.ts` | ソース | 通知センターUI |
| notificationsToasts.ts | `src/vs/workbench/browser/parts/notifications/notificationsToasts.ts` | ソース | 通知トーストUI |
| storage.ts | `src/vs/platform/storage/common/storage.ts` | ソース | ストレージサービス |

### 使用例

```typescript
// 通知にneverShowAgainオプションを追加する例
notificationService.prompt(
    Severity.Info,
    'This is a notification message',
    [/* choices */],
    {
        neverShowAgain: {
            id: 'myExtension.myNotification',
            scope: NeverShowAgainScope.APPLICATION,
            isSecondary: false
        }
    }
);
```

```typescript
// Git拡張機能での使用例 (extensions/git/src/main.ts)
const neverShowAgain = l10n.t('Don\'t Show Again');
const choice = await window.showWarningMessage(
    l10n.t('Git not found. Install it or configure it using the "git.path" setting.'),
    download,
    neverShowAgain
);
if (choice === neverShowAgain) {
    await config.update('ignoreMissingGitWarning', true, true);
}
```
