# 機能設計書 31-プラグインミックスイン

## 概要

本ドキュメントは、InvenTreeシステムにおけるプラグインミックスイン機能の設計を定義する。プラグインミックスインは、プラグインに対して特定の拡張機能を追加するための仕組みを提供する。

### 本機能の処理概要

プラグインミックスイン機能は、InvenTreeのコア機能を拡張するためのプラグインアーキテクチャにおいて、各種機能拡張ポイントを提供する。これにより、サードパーティ開発者や内部開発者が、既存のシステム機能を拡張・カスタマイズすることが可能となる。

**業務上の目的・背景**：企業ごとに異なるビジネス要件に対応するため、InvenTreeのコア機能を変更することなく、プラグインを通じて機能を拡張する必要がある。バーコード処理、UI拡張、イベント処理、バリデーションなど、様々な拡張ポイントを提供することで、柔軟なカスタマイズを実現する。

**機能の利用シーン**：
- サプライヤー固有のバーコードフォーマットに対応する場合
- 在庫移動やオーダー作成時にカスタムバリデーションを追加する場合
- 外部システムとのイベント連携を実装する場合
- カスタムレポートやラベル印刷機能を追加する場合
- 独自のUI要素をシステムに追加する場合

**主要な処理内容**：
1. プラグイン基底クラス（InvenTreePlugin）によるプラグインライフサイクル管理
2. ミックスインレジストリによる拡張機能の登録・管理
3. 各種ミックスインクラスによる機能拡張ポイントの提供
4. プラグイン設定のサポート（グローバル設定・ユーザー設定）
5. イベント駆動型の処理連携

**関連システム・外部連携**：
- プラグインレジストリ（plugin.registry）による動的プラグイン管理
- Djangoの信号（signals）システムによるイベント通知
- 外部API呼び出し機能（APICallMixin）

**権限による制御**：プラグインの有効化・無効化、設定変更にはスタッフ権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 34 | 管理センター画面 | 主画面 | プラグイン管理パネルでの設定 |

## 機能種別

フレームワーク機能 / 拡張ポイント提供

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SETTINGS | dict | No | プラグイングローバル設定の定義 | 辞書形式 |
| USER_SETTINGS | dict | No | プラグインユーザー設定の定義 | 辞書形式 |
| NAME | str | Yes | プラグイン名称 | 空文字不可 |
| SLUG | str | No | プラグイン識別子（自動生成可） | 英数字とハイフン |
| VERSION | str | No | プラグインバージョン | セマンティックバージョニング推奨 |

### 入力データソース

- プラグインクラス定義（Pythonコード）
- プラグイン設定ファイル
- データベース（PluginConfig, PluginSetting）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| plugin_name | str | プラグイン名 |
| plugin_slug | str | プラグイン識別子 |
| is_active | bool | プラグイン有効状態 |
| registered_mixins | dict | 登録されたミックスイン情報 |

### 出力先

- プラグインレジストリ（メモリ内）
- データベース（plugin_pluginconfig）
- 管理画面への表示

## 処理フロー

### 処理シーケンス

```
1. プラグインクラスのロード
   └─ InvenTreePlugin.__init__の呼び出し
2. ミックスインの登録
   └─ add_mixin()によるミックスイン追加
3. プラグイン設定の読み込み
   └─ PluginConfigからの設定取得
4. ミックスインの有効化
   └─ _activate_mixin()の呼び出し
5. 機能拡張ポイントの提供
   └─ 各ミックスインメソッドの公開
```

### フローチャート

```mermaid
flowchart TD
    A[プラグインロード開始] --> B[InvenTreePlugin初期化]
    B --> C[ミックスイン登録]
    C --> D{ミックスイン有効?}
    D -->|Yes| E[ミックスイン設定読込]
    D -->|No| F[スキップ]
    E --> G[機能拡張ポイント有効化]
    F --> G
    G --> H[プラグイン利用可能]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-01 | ミックスイン一意性 | 同一プラグイン内で同じミックスインタイプは1回のみ登録可能 | ミックスイン登録時 |
| BR-31-02 | 必須プラグイン | is_mandatoryがtrueのプラグインは常にアクティブ | プラグイン状態確認時 |
| BR-31-03 | バージョン互換性 | MIN_VERSION/MAX_VERSIONによる互換性チェック | プラグインロード時 |

### 計算ロジック

バージョン互換性チェック:
```python
min_v <= current_version <= max_v
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| プラグイン設定取得 | plugin_pluginconfig | SELECT | プラグイン設定の読み込み |
| 設定値取得 | plugin_pluginsetting | SELECT | プラグイン設定値の取得 |
| 設定値更新 | plugin_pluginsetting | INSERT/UPDATE | プラグイン設定値の保存 |
| ユーザー設定取得 | plugin_pluginusersetting | SELECT | ユーザー別プラグイン設定 |

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

#### plugin_pluginconfig

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | key | プラグインスラッグで検索 | プラグイン識別 |
| SELECT | active | プラグイン有効状態 | true/false |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| INVE-E11 | PluginError | @mark_finalメソッドのオーバーライド試行 | オーバーライド禁止メソッドを変更しない |
| PLUGIN_LOAD_ERROR | ImportError | プラグインモジュールのインポート失敗 | プラグインコードの修正 |

### リトライ仕様

プラグインロードエラーの場合、該当プラグインをスキップして他のプラグインのロードを継続する。

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

プラグイン設定の更新は個別のトランザクションで処理される。複数設定の一括更新機能は提供されない。

## パフォーマンス要件

- プラグインロード：システム起動時に全プラグインをロード（起動時間に影響）
- 設定キャッシュ：プラグイン設定はメモリキャッシュされる
- ミックスインチェック：O(1)の時間複雑度でミックスイン有無を判定

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

- プラグインコードはサーバー上で実行されるため、信頼できるソースからのみインストール
- @mark_finalデコレータによるコアメソッドの保護
- プラグイン設定へのアクセスはスタッフ権限が必要

## 備考

利用可能なミックスイン一覧：
- ActionMixin: カスタムアクション実行
- BarcodeMixin: バーコードスキャン・生成
- EventMixin: イベント処理
- SettingsMixin: プラグイン設定
- ValidationMixin: データバリデーション
- NavigationMixin: ナビゲーション拡張
- ReportMixin: レポート生成
- LabelPrintingMixin: ラベル印刷
- ScheduleMixin: スケジュールタスク
- UserInterfaceMixin: UI拡張

---

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

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

### 推奨読解順序

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

プラグインミックスインの基本構造を理解するため、まず列挙型とミックスイン定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | plugin.py | `src/backend/InvenTree/plugin/plugin.py` | PluginMixinEnum（55-83行目）で利用可能なミックスインタイプを確認 |
| 1-2 | __init__.py | `src/backend/InvenTree/plugin/mixins/__init__.py` | エクスポートされる全ミックスインクラスの一覧 |

**読解のコツ**: PluginMixinEnumはStringEnumを継承しており、各ミックスインタイプは文字列値として定義されている。

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

プラグインの基底クラスと初期化処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | plugin.py | `src/backend/InvenTree/plugin/plugin.py` | InvenTreePluginクラス（295-629行目）の初期化処理 |

**主要処理フロー**:
1. **312-320行目**: __init__でベースミックスインを登録
2. **322-341行目**: __init_subclass__で@mark_finalメソッドのオーバーライドを防止
3. **202-208行目**: mixin()メソッドでミックスイン登録状態を確認

#### Step 3: ミックスイン基盤を理解する

ミックスインの登録・管理機構を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | plugin.py | `src/backend/InvenTree/plugin/plugin.py` | MixinBaseクラス（190-274行目） |

**主要処理フロー**:
- **193-200行目**: __init__で_mixinregと_mixinsを初期化
- **230-235行目**: add_mixin()でミックスインを登録
- **209-227行目**: mixin_enabled()でミックスインの有効状態を確認

#### Step 4: 各種ミックスインの実装を理解する

代表的なミックスインの実装パターンを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mixins.py (barcode) | `src/backend/InvenTree/plugin/base/barcodes/mixins.py` | BarcodeMixin（22-81行目）の基本構造 |
| 4-2 | mixins.py (event) | `src/backend/InvenTree/plugin/base/event/mixins.py` | EventMixin（7-38行目）のイベント処理 |
| 4-3 | SettingsMixin.py | `src/backend/InvenTree/plugin/base/integration/SettingsMixin.py` | 設定管理（27-206行目） |
| 4-4 | ValidationMixin.py | `src/backend/InvenTree/plugin/base/integration/ValidationMixin.py` | バリデーション拡張（14-247行目） |

**主要処理フロー**:
- 各ミックスインは__init__でself.add_mixin()を呼び出してミックスインを登録
- MixinMetaクラスでミックスイン名を定義
- プロパティとメソッドで拡張機能を提供

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

```
InvenTreePlugin
    │
    ├─ MixinBase
    │      ├─ add_mixin()
    │      ├─ mixin()
    │      └─ mixin_enabled()
    │
    ├─ MetaBase
    │      ├─ plugin_name()
    │      ├─ plugin_slug()
    │      └─ plugin_config()
    │
    └─ VersionMixin
           └─ check_version()

各ミックスイン (例: BarcodeMixin)
    │
    ├─ __init__() → add_mixin()
    │
    └─ 拡張メソッド
           ├─ scan()
           └─ generate()
```

### データフロー図

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

プラグインクラス ───▶ InvenTreePlugin.__init__() ───▶ ミックスイン登録
        │
        ▼
PluginConfig(DB) ───▶ plugin_config() ───▶ 設定情報
        │
        ▼
拡張呼び出し ───▶ mixin_enabled() → メソッド実行 ───▶ 拡張機能結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| plugin.py | `src/backend/InvenTree/plugin/plugin.py` | ソース | プラグイン基底クラス定義 |
| __init__.py | `src/backend/InvenTree/plugin/mixins/__init__.py` | ソース | ミックスインエクスポート |
| models.py | `src/backend/InvenTree/plugin/models.py` | ソース | プラグイン設定モデル |
| registry.py | `src/backend/InvenTree/plugin/registry.py` | ソース | プラグインレジストリ管理 |
| mixins.py | `src/backend/InvenTree/plugin/base/barcodes/mixins.py` | ソース | バーコードミックスイン |
| mixins.py | `src/backend/InvenTree/plugin/base/event/mixins.py` | ソース | イベントミックスイン |
| SettingsMixin.py | `src/backend/InvenTree/plugin/base/integration/SettingsMixin.py` | ソース | 設定ミックスイン |
| ValidationMixin.py | `src/backend/InvenTree/plugin/base/integration/ValidationMixin.py` | ソース | バリデーションミックスイン |
| api.py | `src/backend/InvenTree/plugin/api.py` | ソース | プラグインAPI |
| serializers.py | `src/backend/InvenTree/plugin/serializers.py` | ソース | プラグインシリアライザ |
