# 通知設計書 52-ダッシュボードリセット成功

## 概要

本ドキュメントは、レポートダッシュボードをデフォルト状態にリセットした際に表示される成功通知の設計書です。

### 本通知の処理概要

ダッシュボードのリセット操作が正常に完了した場合に、ユーザーに対して成功を通知し、元に戻す（Undo）オプションを提供します。

**業務上の目的・背景**：Actual Budget のダッシュボード機能では、ユーザーが自由にウィジェットを配置・カスタマイズできます。しかし、カスタマイズが複雑になりすぎた場合や、初期状態に戻したい場合に、ダッシュボードをデフォルト状態にリセットする機能が必要です。この通知は、リセット操作が成功したことをユーザーに伝え、誤操作の場合に備えてUndo機能を提供することで、ユーザー体験を向上させます。

**通知の送信タイミング**：ダッシュボードのメニューから「Reset to default」オプションを選択し、`dashboard-reset` API呼び出しが正常に完了した直後に通知が発行されます。

**通知の受信者**：ダッシュボードのリセット操作を実行した現在のユーザーが受信者となります。

**通知内容の概要**：リセット成功のメッセージと、Ctrl+Z（またはCmd+Z）でUndo可能であることを示すリンク付きメッセージが表示されます。

**期待されるアクション**：ユーザーはリセット結果を確認し、必要に応じてUndo操作（Ctrl+Zまたはメッセージ内のリンクをクリック）を実行することが期待されます。30秒のタイムアウト後、通知は自動的に消えます。

## 通知種別

アプリ内通知（トースト通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（即時） |
| 優先度 | 中 |
| リトライ | 無し |

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

現在アプリケーションを操作しているユーザーに対して表示されます。サーバーサイドでの送信先決定は行われず、クライアントサイドで直接通知が表示されます。

## 通知テンプレート

### アプリ内通知の場合

| 項目 | 内容 |
|-----|------|
| 通知タイプ | message |
| 通知ID | import |
| sticky | true |
| timeout | 30000ms（30秒） |

### 本文テンプレート

```
Dashboard has been successfully reset to default state. Don't like what you see? You can always press [ctrl+z](#undo) to undo.
```

**注意**: メッセージ内の `[ctrl+z](#undo)` はMarkdown形式のリンクで、クリックするとUndo操作が実行されます。

### 添付ファイル

該当なし

## テンプレート変数

該当なし（固定メッセージ）

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | ダッシュボードメニューの「Reset to default」選択 | `dashboard-reset` API呼び出しが正常完了 | onResetDashboard関数内で発行 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| API呼び出し失敗時 | リセットAPIがエラーを返した場合は通知しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Reset to defaultメニュー選択] --> B[isImportingをtrueに設定]
    B --> C[dashboard-reset API呼び出し]
    C --> D[isImportingをfalseに設定]
    D --> E[onDispatchSuccessNotification呼び出し]
    E --> F[addNotification発行]
    F --> G[成功通知表示]
    G --> H{ユーザーアクション}
    H -->|Undoクリック| I[closeNotifications + undo実行]
    H -->|30秒経過| J[自動クローズ]
    H -->|手動クローズ| K[通知を閉じる]
    I --> L[終了]
    J --> L
    K --> L
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| dashboard | 現在のウィジェット一覧取得 | リセット対象の特定 |

### テーブル別参照項目詳細

#### dashboard

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | ウィジェットID | dashboard_page_id = 対象ダッシュボードID AND tombstone = 0 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| dashboard | DELETE（論理） | 既存ウィジェットの削除（tombstone = 1） |
| dashboard | INSERT | デフォルトウィジェットの挿入 |

#### dashboardテーブル更新詳細

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| DELETE | tombstone | 1 | 既存の全ウィジェットを論理削除 |
| INSERT | id, type, x, y, width, height, meta, dashboard_page_id | DEFAULT_DASHBOARD_STATE の値 | デフォルト状態のウィジェットを挿入 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| データベースエラー | DB操作失敗 | 処理を中断（成功通知は発行されない） |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（ユーザー操作に応じて即時表示）

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

- ダッシュボードリセットは undoable 操作として実装されており、誤操作からの復旧が可能
- リセット操作は現在のユーザーのダッシュボードにのみ影響
- batchMessagesによりトランザクション管理が行われる

## 備考

- 通知ID「import」は、ダッシュボードのインポート操作と共有されており、Ctrl+Zのホットキーで閉じられる
- sticky: true と timeout: 30000 の組み合わせにより、30秒後に自動消去される
- messageActions.undo により、メッセージ内のリンククリックでUndo操作が可能

---

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

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

### 推奨読解順序

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

まず、デフォルトダッシュボードの状態とウィジェット構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dashboard.ts | `packages/loot-core/src/shared/dashboard.ts` | DEFAULT_DASHBOARD_STATE（3-260行目）でデフォルトウィジェット構成を確認 |
| 1-2 | dashboard.ts | `packages/loot-core/src/types/models/dashboard.ts` | Widget型（118行目）とNewWidget型（119行目）の定義 |

**読解のコツ**: デフォルトダッシュボードは4行構成（サマリーカード、純資産/キャッシュフロー、支出カード、カレンダー/マークダウン）であることを理解する。

#### Step 2: エントリーポイントを理解する

処理の起点となるダッシュボード画面コンポーネントを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Overview.tsx | `packages/desktop-client/src/components/reports/Overview.tsx` | ダッシュボード画面のメインコンポーネント |

**主要処理フロー**:
1. **182行目**: useUndo フックでundo関数を取得
2. **184-202行目**: onDispatchSucessNotification 関数で成功通知を構築
3. **204-214行目**: onResetDashboard 関数でリセット処理と通知発行
4. **600-601行目**: メニューの「reset」オプション選択時に onResetDashboard を呼び出し

#### Step 3: サーバーサイド処理を理解する

ダッシュボードリセットのAPIハンドラーを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | app.ts | `packages/loot-core/src/server/dashboard/app.ts` | resetDashboard関数（167-185行目） |

**主要処理フロー**:
- **167-185行目**: batchMessages内で既存ウィジェット削除とデフォルトウィジェット挿入を実行
- **371行目**: undoableラッパーによりUndo対応

#### Step 4: 通知システムを理解する

通知の追加・表示メカニズムを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | notificationsSlice.ts | `packages/desktop-client/src/notifications/notificationsSlice.ts` | addNotificationリデューサー（58-68行目） |

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

```
Overview.tsx (ダッシュボード画面)
    │
    ├─ onResetDashboard (204行目)
    │      ├─ setIsImporting(true)
    │      ├─ send('dashboard-reset', dashboard.id) (206行目)
    │      │      └─ dashboard/app.ts: resetDashboard (167行目)
    │      │             ├─ db.selectWithSchema (169行目)
    │      │             ├─ db.delete_ (177行目) - 既存ウィジェット削除
    │      │             └─ db.insertWithSchema (180行目) - デフォルト挿入
    │      ├─ setIsImporting(false)
    │      └─ onDispatchSucessNotification (209行目)
    │             └─ dispatch(addNotification(...)) (185行目)
    │
    └─ useUndo (182行目)
           └─ undo関数 - messageActions.undoで利用
```

### データフロー図

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

メニュー選択 ───▶ dashboard-reset API ───▶ DB更新
    │                                          │
    │                                          ▼
    │                               DEFAULT_DASHBOARD_STATE
    │                                          │
    └───────────────────────────────────────────┘
                        │
                        ▼
              onDispatchSucessNotification
                        │
                        ▼
               [成功通知表示 + Undoリンク]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Overview.tsx | `packages/desktop-client/src/components/reports/Overview.tsx` | ソース | ダッシュボード画面コンポーネント |
| app.ts | `packages/loot-core/src/server/dashboard/app.ts` | ソース | ダッシュボードAPIハンドラー |
| dashboard.ts | `packages/loot-core/src/shared/dashboard.ts` | ソース | デフォルトダッシュボード定義 |
| notificationsSlice.ts | `packages/desktop-client/src/notifications/notificationsSlice.ts` | ソース | 通知状態管理スライス |
| useUndo.ts | `packages/desktop-client/src/hooks/useUndo.ts` | ソース | Undoフック |
| dashboard.ts | `packages/loot-core/src/types/models/dashboard.ts` | 型定義 | ウィジェット型定義 |
