# バッチ設計書 14-app_update

## 概要

本ドキュメントは、Shopwareプラットフォームにおけるアプリ更新バッチの設計仕様を定義します。インストール済みのアプリケーション（サードパーティ拡張機能）の更新を確認し、利用可能な更新があれば自動的に適用します。

### 本バッチの処理概要

**業務上の目的・背景**：Shopwareのアプリシステムでは、ストアやサードパーティから提供されるアプリケーションをインストールして機能を拡張できます。これらのアプリはセキュリティ修正、バグ修正、新機能追加などの更新が頻繁にリリースされます。手動での更新確認は運用負荷が高く、更新の見落としによりセキュリティリスクが発生する可能性があります。本バッチは定期的に更新を確認し、自動適用することでシステムを最新の状態に保ちます。

**バッチの実行タイミング**：日次（86400秒間隔）でスケジュール実行されます。ただし、`shopware.deployment.runtime_extension_management`パラメータがtrueに設定されている場合のみ実行されます。

**主要な処理内容**：
1. shouldRunメソッドでruntime_extension_management設定を確認
2. CLIコンテキストを作成
3. AbstractAppUpdaterサービスのupdateAppsメソッドを呼び出し
4. 更新可能なアプリを検出し、順次更新を適用

**前後の処理との関連**：前提として、アプリがインストールされており、アプリストアまたは外部ソースから更新情報が取得可能である必要があります。app_deleteタスクは削除されたアプリのカスケード削除を処理する関連タスクです。

**影響範囲**：アプリの更新により、関連するデータベーススキーマ、設定、権限、フロントエンド表示などが変更される可能性があります。更新は各アプリのライフサイクル（アップグレードスクリプト等）に従って実行されます。

## バッチ種別

データ連携 / システム更新

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 日次 |
| 実行時刻 | スケジュールタスクランナーに依存 |
| 実行曜日 | 毎日 |
| 実行日 | - |
| トリガー | cron（スケジュールタスク） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| shopware.deployment.runtime_extension_management | trueに設定されている必要あり |
| アプリストア接続 | 更新情報取得のためのネットワーク接続が必要 |

### 実行可否判定

`shouldRun()`メソッドで`shopware.deployment.runtime_extension_management`パラメータを確認し、falseの場合はタスク自体が実行されません。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 入力パラメータは不要 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| app | DB | インストール済みアプリ情報 |
| アプリストアAPI | HTTP | 更新可能バージョン情報 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| app | DB | 更新されたアプリ情報 |
| app関連テーブル | DB | アプリの設定、権限等の更新 |

### 出力ファイル仕様

ファイル出力はありません（アプリのアセットファイル更新を除く）。

## 処理フロー

### 処理シーケンス

```
1. 実行条件チェック
   └─ shouldRun()でruntime_extension_management確認
2. コンテキスト作成
   └─ Context::createCLIContext()でCLIコンテキスト生成
3. アプリ更新実行
   └─ AbstractAppUpdater::updateApps()を呼び出し
4. 更新処理
   └─ 各アプリの更新を順次適用
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{runtime_extension_management?}
    B -->|false| Z[スキップ終了]
    B -->|true| C[CLIコンテキスト作成]
    C --> D[AppUpdater.updateApps呼び出し]
    D --> E[更新可能アプリ検出]
    E --> F{更新あり?}
    F -->|なし| G[バッチ終了]
    F -->|あり| H[アプリ更新適用]
    H --> I{次のアプリ?}
    I -->|あり| H
    I -->|なし| G
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| アプリ情報取得 | app | SELECT | インストール済みアプリの取得 |
| アプリ更新 | app | UPDATE | バージョン情報等の更新 |
| 権限更新 | acl_role | INSERT/UPDATE/DELETE | アプリ権限の更新 |
| 設定更新 | system_config | INSERT/UPDATE | アプリ設定の更新 |

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

#### app

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, version等 | 全インストール済みアプリ | 更新対象の特定 |
| UPDATE | version, updated_at等 | 更新適用後の新バージョン | ライフサイクル経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ネットワークエラー | 接続エラー | アプリストアAPI接続失敗 | ネットワーク確認、再試行 |
| 更新失敗 | アプリエラー | アプリ更新スクリプト失敗 | ログ確認、手動対応 |
| 権限不足 | 設定エラー | 必要な権限がない | 管理者権限で実行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 失敗時再スケジュール有効 |
| リトライ間隔 | 次回スケジュール実行時 |
| リトライ対象エラー | 全般的なエラー |

### 障害時対応

1. エラーログを確認し原因を特定
2. ネットワーク接続を確認（アプリストアへのアクセス）
3. 手動でアプリ更新を実行（管理画面または`bin/console`）
4. 問題のあるアプリを一時的に無効化

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | アプリ単位 |
| コミットタイミング | 各アプリ更新完了時 |
| ロールバック条件 | アプリ更新失敗時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | インストール済みアプリ数（通常10〜50件程度） |
| 目標処理時間 | アプリ数とネットワーク速度に依存（数分〜数十分） |
| メモリ使用量上限 | 通常のPHP制限に準拠 |

## 排他制御

アプリ更新中は同一アプリの重複更新を防止するため、アプリライフサイクル層で排他制御が行われます。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | タスク開始時 | タスク開始通知 |
| 進捗ログ | アプリ更新時 | 更新対象アプリ名、バージョン |
| 終了ログ | タスク終了時 | 処理完了通知、更新件数 |
| エラーログ | エラー発生時 | エラー詳細、スタックトレース |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | 1800秒 | システム管理者 |
| エラー件数 | 1件以上 | システム管理者 |

## 備考

- runtime_extension_management設定がfalseの場合、本タスクは実行されません
- アプリ更新は各アプリのライフサイクル（install, update, activate等）に従って処理されます
- 更新中はアプリの機能が一時的に利用できなくなる場合があります
- 本番環境では更新前にバックアップを取得することを推奨します
- AbstractAppUpdaterにより実際の更新ロジックが抽象化されており、異なる更新元（ストア、ローカル等）に対応可能です
