# 機能設計書 66-リリースノート表示

## 概要

本ドキュメントは、InvenTreeモバイルアプリにおけるリリースノート表示機能の設計を記述するものである。アプリのリリースノートをMarkdown形式で表示する画面の仕様を定義する。

### 本機能の処理概要

本機能は、アプリのリリースノート（更新履歴）をMarkdown形式で表示する画面を提供する。リリースノートはアプリのアセットファイルとして同梱されており、flutter_markdownパッケージを使用してレンダリングされる。また、新バージョンへのアップデート時に自動的にリリースノート画面が表示される。

**業務上の目的・背景**：アプリの更新内容をユーザーに伝達することは、新機能の活用促進やバグ修正の周知において重要である。特に業務アプリでは、機能変更がワークフローに影響を与える可能性があるため、ユーザーが更新内容を把握できることが求められる。

**機能の利用シーン**：
- アプリをアップデートした直後に自動表示される
- アバウト画面からリリースノートを確認したい場合
- 特定のバージョンで追加・変更された機能を確認したい場合

**主要な処理内容**：
1. アセットファイル（assets/release_notes.md）からリリースノートを読み込み
2. Markdownウィジェットによるレンダリング
3. Markdown内のリンククリック時の外部ブラウザ起動
4. 新バージョン検出時の自動表示（main.dartで制御）

**関連システム・外部連携**：
- 外部ブラウザ：Markdown内のリンククリック時にurl_launcherで起動

**権限による制御**：本機能に特別な権限制御はなく、すべてのユーザーが利用可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | アバウト画面 | 遷移元画面 | リリースノートメニュー押下時に本画面へ遷移 |
| 18 | リリースノート画面 | 主画面 | アプリのリリースノートをMarkdown形式で表示 |

## 機能種別

情報表示 / 外部リンク起動

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| releaseNotes | String | Yes | リリースノートのMarkdownテキスト | 空文字列許容 |

### 入力データソース

- アセットファイル：`assets/release_notes.md`
- rootBundle.loadString()で読み込み

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| renderedMarkdown | Widget | Markdownウィジェットによるレンダリング結果 |

### 出力先

- 画面表示：Markdownウィジェット
- 外部ブラウザ：Markdown内リンククリック時

## 処理フロー

### 処理シーケンス

```
1. 画面表示（build）
   └─ Scaffoldウィジェット構築
      └─ AppBarにタイトル表示
      └─ bodyにMarkdownウィジェット配置
2. リンククリック
   └─ onTapLinkコールバック発火
   └─ openLink()で外部ブラウザ起動
```

### フローチャート

```mermaid
flowchart TD
    A[アバウト画面] --> B[リリースノートタップ]
    B --> C[release_notes.md読み込み]
    C --> D[ReleaseNotesWidget生成]
    D --> E[Markdownレンダリング]
    E --> F{リンククリック}
    F -->|Yes| G[外部ブラウザ起動]
    F -->|戻る| H[画面終了]
    G --> F
```

### 新バージョン検出時の自動表示フロー

```mermaid
flowchart TD
    A[アプリ起動] --> B[保存されたバージョン取得]
    B --> C{現在バージョンと比較}
    C -->|異なる| D[バージョン保存]
    D --> E[release_notes.md読み込み]
    E --> F[ReleaseNotesWidget表示]
    C -->|同じ| G[通常起動]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-66-01 | 自動表示 | 新バージョンへのアップデート時に自動的にリリースノートを表示 | バージョン変更検出時 |
| BR-66-02 | バージョン記録 | 表示後は現在のバージョンを保存し、次回起動時に自動表示しない | 自動表示後 |
| BR-66-03 | リンク起動 | Markdown内のリンクは外部ブラウザで開く | リンククリック時 |
| BR-66-04 | 選択不可 | Markdownテキストは選択不可（selectable: false） | 常時 |

### 計算ロジック

該当なし

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| バージョン読み込み | settings（sembast store） | SELECT | recentVersionキーで保存されたバージョンを取得 |
| バージョン保存 | settings（sembast store） | UPDATE | 現在のバージョンを保存 |

### テーブル別操作詳細

#### settings（sembast store）

| 操作 | 項目（キー） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | recentVersion | 最後に表示したバージョン | main.dartで使用 |
| UPDATE | recentVersion | 現在のアプリバージョン | main.dartで使用 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アセット読み込みエラー | release_notes.mdが存在しない場合 | 例外がスローされる（稀なケース） |
| - | URL起動エラー | 外部ブラウザ起動失敗 | 空文字列チェック後に起動、失敗時は無視 |

### リトライ仕様

リトライは実装されていない。

## トランザクション仕様

sembastデータベースの単一キー操作のため、明示的なトランザクション管理は不要。

## パフォーマンス要件

- アセット読み込み：100ms以内
- Markdownレンダリング：200ms以内
- 外部リンク起動：ブラウザ依存

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

- リリースノートはローカルアセットから読み込まれるため、改ざんリスクは低い
- 外部リンクはHTTPS経由のみ（リリースノート内のリンクは開発者が管理）

## 備考

- flutter_markdownパッケージを使用
- リリースノートはアプリビルド時に同梱される
- 新バージョン検出ロジックはmain.dartのrunInitTasks()で実装

---

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

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

### 推奨読解順序

#### Step 1: リリースノート画面を理解する

ReleaseNotesWidgetの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | release.dart | `lib/settings/release.dart` | ReleaseNotesWidgetクラス |

**読解のコツ**:
- **9-10行目**: StatelessWidgetとして定義、releaseNotesをコンストラクタで受け取る
- **12行目**: 受け取ったリリースノートを保持
- **15-32行目**: buildメソッドでMarkdownウィジェットを構築
- **21行目**: `selectable: false`でテキスト選択を無効化
- **22行目**: `data: releaseNotes`でMarkdownテキストを渡す
- **23-28行目**: `onTapLink`コールバックでリンククリック時に外部ブラウザを起動

#### Step 2: リリースノート呼び出し元を理解する

アバウト画面からの呼び出しを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | about.dart | `lib/settings/about.dart` | _releaseNotesメソッド |

**主要処理フロー**:
- **21-29行目**: `_releaseNotes`メソッド
- **23行目**: `rootBundle.loadString("assets/release_notes.md")`でアセット読み込み
- **25-28行目**: `Navigator.push`でReleaseNotesWidgetへ遷移

#### Step 3: 新バージョン検出時の自動表示を理解する

main.dartでの自動表示ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | main.dart | `lib/main.dart` | runInitTasksメソッド |

**主要処理フロー**:
- **121-145行目**: `runInitTasks`メソッド
- **127-129行目**: 保存されたバージョンを取得
- **131行目**: 現在のアプリバージョンを取得
- **133行目**: バージョン比較
- **135行目**: 新バージョンの場合、バージョンを保存
- **138行目**: リリースノートを読み込み
- **141-143行目**: ReleaseNotesWidgetを表示

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

```
[アバウト画面からの呼び出し]
InvenTreeAboutWidget
    │
    └─ _releaseNotes()
           │
           ├─ rootBundle.loadString("assets/release_notes.md")
           │
           └─ Navigator.push()
                  └─ ReleaseNotesWidget
                         └─ Markdown(data: releaseNotes)
                                └─ onTapLink: openLink()

[新バージョン検出時の自動表示]
InvenTreeAppState
    │
    └─ runInitTasks()
           │
           ├─ InvenTreeSettingsManager.getValue("recentVersion")
           ├─ PackageInfo.fromPlatform()
           │
           ├─ [バージョン比較]
           │      │
           │      └─ [異なる場合]
           │             ├─ InvenTreeSettingsManager.setValue("recentVersion")
           │             └─ rootBundle.loadString("assets/release_notes.md")
           │
           └─ OneContext().push()
                  └─ ReleaseNotesWidget
```

### データフロー図

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

assets/release_notes.md ─────▶┌─────────────────────┐
                              │ rootBundle.loadString│
                              └──────────┬──────────┘
                                         │
                                         ▼
                              ┌─────────────────────┐
                              │ ReleaseNotesWidget  │
                              │ - Markdown()        │──────▶ レンダリング済みテキスト
                              └──────────┬──────────┘
                                         │
                                         ▼
                              ┌─────────────────────┐
リンククリック ──────────────▶│ onTapLink()         │
                              │ - openLink()        │──────▶ 外部ブラウザ
                              └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| release.dart | `lib/settings/release.dart` | ソース | リリースノート表示画面・クレジット表示画面 |
| about.dart | `lib/settings/about.dart` | ソース | アバウト画面（呼び出し元） |
| main.dart | `lib/main.dart` | ソース | 新バージョン検出と自動表示ロジック |
| helpers.dart | `lib/helpers.dart` | ソース | openLink()ヘルパー関数 |
| l10.dart | `lib/l10.dart` | ソース | 多言語テキスト取得ヘルパー |
| app_colors.dart | `lib/app_colors.dart` | ソース | アプリ共通カラー定義 |
| release_notes.md | `assets/release_notes.md` | アセット | リリースノートMarkdownファイル |
