# 通知設計書 34-アプリ更新準備完了

## 概要

本ドキュメントは、Actual Budget アプリケーションにおける「アプリ更新準備完了」通知の設計仕様を記述する。この通知は、新しいバージョンのアプリがダウンロード完了し、適用可能な状態になったことをユーザーに知らせるものである。

### 本通知の処理概要

**業務上の目的・背景**：アプリケーションの更新がバックグラウンドでダウンロード完了した際に、ユーザーに更新の適用を促す。これにより、ユーザーは最新の機能やセキュリティ修正を即座に利用できるようになる。更新の適用はユーザーの明示的なアクションを必要とし、作業中のデータを失うことなく適切なタイミングで更新できる。

**通知の送信タイミング**：Electron版アプリでバックグラウンド更新がダウンロード完了し、適用準備ができた時点で表示される。`global.Actual.waitForUpdateReadyForDownload()` が resolve した際にトリガーされる。

**通知の受信者**：Electron版アプリを使用しているユーザー。ブラウザ版では表示されない。

**通知内容の概要**：新しいバージョンが利用可能で、リロードすることで更新が適用されることを示すメッセージと「Update now」ボタンが表示される。この通知は sticky として設定され、ユーザーが明示的にアクションを取るまで表示され続ける。

**期待されるアクション**：ユーザーは作業を保存した上で「Update now」ボタンを押し、アプリを更新・リロードする。

## 通知種別

アプリ内通知（トースト通知 - メッセージタイプ）

## 送信仕様

### 基本情報

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

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

- Electron版アプリのみで表示
- `global.Actual.isUpdateReadyForDownload()` または `global.Actual.waitForUpdateReadyForDownload()` が true/resolve の場合に表示

## 通知テンプレート

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

| 項目 | 内容 |
|-----|------|
| 通知タイプ | `message` |
| 通知ID | `update-reload-notification` |
| 表示位置 | 画面右下（固定位置） |
| sticky | `true`（自動消去されない） |

### 本文テンプレート

```
Title: A new version of Actual is available!
Message: Click the button below to reload and apply the update.
[Update now ボタン]
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | 通知タイプ | 固定値 `message` | Yes |
| id | 通知ID | 固定値 `update-reload-notification` | Yes |
| title | 通知タイトル | 固定値（i18n対応） | Yes |
| message | 通知メッセージ | 固定値（i18n対応） | Yes |
| sticky | 自動消去無効フラグ | 固定値 `true` | Yes |
| button.title | ボタンラベル | 固定値 `Update now` | Yes |
| button.action | ボタンアクション | `global.Actual.applyAppUpdate()` | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| バックグラウンド処理 | 更新ダウンロード完了 | Electron版で更新準備完了 | FinancesApp.tsx で検知 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ブラウザ版 | Electron API が利用できない場合は表示しない |
| 同一IDの通知が既に表示中 | 重複防止 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[アプリ起動] --> B[FinancesApp マウント]
    B --> C[waitForUpdateReadyForDownload 呼び出し]
    C --> D{更新準備完了?}
    D -->|Yes (resolve)| E[addNotification dispatch]
    D -->|待機中| D
    E --> F[Redux store に追加]
    F --> G[Notifications コンポーネントで表示]
    G --> H[ユーザーがボタン押下]
    H --> I[applyAppUpdate 実行]
    I --> J[アプリ再起動/リロード]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| - | - | 通知表示自体ではDB参照なし |

### ボタンアクション実行時の更新

「Update now」ボタン押下時は `global.Actual.applyAppUpdate()` が実行され、以下の処理が行われる：
- Electronアプリの再起動
- ダウンロード済みの更新の適用

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 更新適用失敗 | ファイルシステムエラー等 | Electronのエラーハンドリングに委ねる |
| Promise reject | 更新確認エラー | エラーログ出力、通知は表示されない |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（同一ID重複防止あり） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（更新準備完了時に即時表示）

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

- 更新の配信元は Actual Budget の公式リリースチャンネルのみ
- Electron の自動更新機能（electron-updater）を使用
- コード署名による更新パッケージの検証

## 備考

- この通知は Electron 版専用であり、ブラウザ版では表示されない
- sticky 通知のため、ユーザーが明示的にアクションを取るまで表示され続ける
- 更新適用後はアプリが自動的に再起動される
- No.35「新バージョン利用可能」とは異なり、こちらはダウンロード完了後の即時更新を促す

---

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

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

### 推奨読解順序

#### Step 1: Electron API を理解する

更新関連の Electron API の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | global.d.ts または preload | Electron preload スクリプト | `global.Actual` オブジェクトの型定義 |

**読解のコツ**: `global.Actual.waitForUpdateReadyForDownload()` と `global.Actual.applyAppUpdate()` がどのように定義されているかを確認する。

#### Step 2: 通知発行処理を理解する

更新準備完了時の通知発行処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FinancesApp.tsx | `packages/desktop-client/src/components/FinancesApp.tsx` | init 関数内の更新通知処理（105-136行目） |

**主要処理フロー**:
1. **105行目**: `useEffectEvent` で init 関数を定義
2. **112行目**: `global.Actual.waitForUpdateReadyForDownload()` を await
3. **113-132行目**: `addNotification` で通知を追加
4. **126-128行目**: `applyAppUpdate()` を呼び出すボタンアクションを設定

#### Step 3: アプリ起動時の更新チェックを理解する

アプリ起動時の更新チェックと適用処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | App.tsx | `packages/desktop-client/src/components/App.tsx` | maybeUpdate 関数（65-75行目） |

**主要処理フロー**:
- **66行目**: `global.Actual.isUpdateReadyForDownload()` で即座にチェック
- **67-72行目**: 更新準備完了の場合、loadingText を表示して適用

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

```
App.tsx (起動時)
    │
    ├─ maybeUpdate()
    │      │
    │      └─ isUpdateReadyForDownload()
    │             │
    │             └─ (true) → applyAppUpdate() → アプリ再起動
    │
FinancesApp.tsx (マウント後)
    │
    ├─ init() (useEffectEvent)
    │      │
    │      └─ waitForUpdateReadyForDownload()
    │             │
    │             └─ (resolve) → addNotification()
    │                    │
    │                    └─ Redux store 更新
    │                           │
    │                           └─ Notifications.tsx 表示
    │
Notifications.tsx
    │
    └─ ButtonWithLoading ('Update now')
           │
           └─ onClick: applyAppUpdate()
                  │
                  └─ アプリ再起動
```

### データフロー図

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

Electron 更新ダウンロード ────▶ waitForUpdateReadyForDownload() ──▶ Promise resolve
                                       │
                                       └─▶ addNotification dispatch
                                              │
                                              └─▶ Redux store
                                                     │
                                                     └─▶ 通知表示

'Update now' ボタン押下 ─────▶ applyAppUpdate() ──────────────▶ アプリ再起動
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| FinancesApp.tsx | `packages/desktop-client/src/components/FinancesApp.tsx` | ソース | 更新準備完了通知の発行 |
| App.tsx | `packages/desktop-client/src/components/App.tsx` | ソース | 起動時の更新チェック |
| notificationsSlice.ts | `packages/desktop-client/src/notifications/notificationsSlice.ts` | ソース | 通知の Redux slice 定義 |
| Notifications.tsx | `packages/desktop-client/src/components/Notifications.tsx` | ソース | 通知表示コンポーネント |
| preload.ts | `packages/desktop-electron/preload.ts` | ソース | Electron preload スクリプト |
