# 通知設計書 20-ソースファイル不在通知

## 概要

本ドキュメントは、StaxRipアプリケーションにおける「ソースファイル不在通知（Source file not found!）」の設計仕様を記述する。

### 本通知の処理概要

この通知は、ジョブ処理を開始する際にソースビデオファイルが存在しない場合に、ユーザーにエラー情報を表示する機能を提供する。

**業務上の目的・背景**：StaxRipでエンコードジョブを処理する際、ソースビデオファイル（入力ファイル）が必要である。プロジェクトファイルは存在してもソースファイルが見つからない場合（削除された、移動された、外部ドライブが接続されていないなど）、エンコード処理を開始することは不可能であり、ユーザーにエラーを通知してジョブをスキップする必要がある。

**通知の送信タイミング**：GlobalClass.ProcessJobメソッドにおいて、以下の2つのケースで発生する：
1. バッチモードの場合：p.SourceFilesのいずれかが存在しない場合（行493-494）
2. 通常モードの場合：p.SourceFileが存在しない場合（行503-504）

**通知の受信者**：StaxRipアプリケーションを操作している現在のユーザー（エンドユーザー）。g.RunTask()を通じてUIスレッドでモーダルダイアログとして表示される。

**通知内容の概要**：エラーメッセージとして「Source file not found!」というタイトルと、「{ファイルパス} could not be found and got skipped!」という詳細メッセージが表示される。

**期待されるアクション**：ユーザーはエラーメッセージを確認し、以下のような対処を行うことが期待される。(1) ソースファイルの場所を確認する、(2) 外部ドライブを接続する、(3) ファイルが削除されていないか確認する、(4) プロジェクトを再作成する。

## 通知種別

アプリ内通知（モーダルダイアログ）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（UIスレッドで実行） |
| 優先度 | 高（エラー通知） |
| リトライ | 無 |

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

現在StaxRipアプリケーションを操作しているユーザーに対して、モーダルダイアログとして直接表示される。バックグラウンドスレッドからはg.RunTask()を通じてUIスレッドで表示される。

## 通知テンプレート

### ダイアログ通知の場合

| 項目 | 内容 |
|-----|------|
| タイトル | Source file not found! |
| アイコン | Error |
| ボタン | OK |

### 本文テンプレート

バッチモードの場合：
```
{MissingFiles}
could not be found and got skipped!
```

通常モードの場合：
```
'{SourceFile}'
could not be found and got skipped!
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| MissingFiles | 見つからないファイルのリスト（改行区切り） | missingFiles.Join(BR) | バッチモード時 |
| SourceFile | ソースファイルのパス | p.SourceFile | 通常モード時 |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| バッチ処理 | ジョブ処理開始（バッチモード） | missingFiles.Count > 0 | いずれかのソースファイルが不在 |
| バッチ処理 | ジョブ処理開始（通常モード） | Not File.Exists(p.SourceFile) | ソースファイルが不在 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 全ソースファイルが存在 | すべてのソースファイルが存在する場合は通知しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[GlobalClass.ProcessJob - ソースファイルチェック部分] --> B{p.BatchMode?}
    B -->|Yes| C[missingFiles = p.SourceFiles.Where#40;Not FileExists#41;]
    B -->|No| D{File.Exists#40;p.SourceFile#41;?}
    C --> E{missingFiles.Count > 0?}
    E -->|Yes| F[g.RunTask#40;MsgError - バッチモード用#41;]
    E -->|No| G[ジョブ処理継続]
    D -->|No| H[g.RunTask#40;MsgError - 通常モード用#41;]
    D -->|Yes| G
    F --> I[Exit Sub]
    H --> I
```

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

### 参照テーブル一覧

データベースは使用しない。

### 更新テーブル一覧

データベースは使用しない。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ソースファイル不在（バッチ） | いずれかのソースファイルが存在しない | MsgError表示、ジョブをスキップ |
| ソースファイル不在（通常） | ソースファイルが存在しない | MsgError表示、ジョブをスキップ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし、ジョブをスキップ） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（ジョブ処理に応じて随時表示）

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

- ファイルパスがメッセージに含まれるため、ディレクトリ構造が露出する

## 備考

- GlobalClass使用時に発生する
- g.RunTask()を使用してUIスレッドでダイアログを表示する
- Exit Subによりジョブ処理は即座に中断され、次のジョブに移行する
- バッチモードでは複数のソースファイルをチェックし、見つからないファイルをすべてリストアップする
- プロジェクト不在通知（No.19）の後に実行される（プロジェクトファイルは存在するがソースファイルが不在のケース）

---

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

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

### 推奨読解順序

#### Step 1: ProcessJobメソッドのソースファイルチェック部分を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GlobalClass.vb | `Source/General/GlobalClass.vb` | ProcessJobメソッド（行490-507付近） |

**主要処理フロー**:
1. **行490**: If p.BatchMode Then
2. **行491**: missingFiles = p.SourceFiles.Where(Function(srcFile) Not srcFile.FileExists)
3. **行493**: If missingFiles.Count > 0 Then
4. **行494**: **通知発生箇所1（バッチモード）** - g.RunTask(Sub() MsgError("Source file not found!", ...))
5. **行495**: Exit Sub
6. **行502**: Else
7. **行503**: If Not File.Exists(p.SourceFile) Then
8. **行504**: **通知発生箇所2（通常モード）** - g.RunTask(Sub() MsgError("Source file not found!", ...))
9. **行505**: Exit Sub

#### Step 2: バッチモードとの違いを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | GlobalClass.vb | `Source/General/GlobalClass.vb` | p.BatchModeの分岐とp.SourceFiles/p.SourceFileの違い |

**読解のコツ**: バッチモードでは複数のソースファイルを処理するため、p.SourceFiles（リスト）を使用し、通常モードではp.SourceFile（単一ファイル）を使用することを理解する。

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

```
[ジョブキュー処理]
    │
    └─ GlobalClass.ProcessJob(jobPath)
           │
           ├─ [プロジェクトファイル存在チェック] → OK
           │
           └─ [ソースファイル存在チェック]
                  │
                  ├─ [p.BatchMode = True]
                  │      │
                  │      └─ missingFiles = p.SourceFiles.Where(Not FileExists)
                  │             │
                  │             ├─ [missingFiles.Count = 0] → ジョブ処理継続
                  │             │
                  │             └─ [missingFiles.Count > 0]
                  │                    │
                  │                    └─ g.RunTask(Sub()
                  │                                    MsgError("Source file not found!",
                  │                                             missingFiles.Join(BR) + "could not be found...")
                  │                                End Sub)
                  │                    │
                  │                    └─ Exit Sub
                  │
                  └─ [p.BatchMode = False]
                         │
                         ├─ [File.Exists(p.SourceFile)] → ジョブ処理継続
                         │
                         └─ [Not File.Exists(p.SourceFile)]
                                │
                                └─ g.RunTask(Sub()
                                                MsgError("Source file not found!",
                                                         "'" + p.SourceFile + "' could not be found...")
                                            End Sub)
                                │
                                └─ Exit Sub
```

### データフロー図

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

p.BatchMode ─────────────▶ 分岐判定
        │
        ├─ [True]
        │      │
        │      ▼
        │   p.SourceFiles ──▶ Where(Not FileExists) ──▶ missingFiles
        │                           │
        │                           ├─ [Count = 0] ──▶ 処理継続
        │                           │
        │                           └─ [Count > 0]
        │                                  │
        │                                  ▼
        │                              MsgError表示
        │                              (missingFiles.Join(BR))
        │
        └─ [False]
               │
               ▼
           p.SourceFile ──────▶ File.Exists()
                                    │
                                    ├─ [True] ──▶ 処理継続
                                    │
                                    └─ [False]
                                           │
                                           ▼
                                       MsgError表示
                                       (p.SourceFile)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| GlobalClass.vb | `Source/General/GlobalClass.vb` | ソース | グローバルクラス（行494, 504が通知発生箇所） |
| Project.vb | `Source/General/Project.vb` | ソース | プロジェクト設定（SourceFile, SourceFiles, BatchMode） |
| Msg.vb | `Source/UI/Msg.vb` | ソース | MsgError関数の定義 |
