# バッチ設計書 26-rebuild_models

## 概要

本ドキュメントは、MPTT構造を持つ全モデルのツリー構造を再構築するDjango管理コマンド「rebuild_models」の設計仕様を定義する。

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

このコマンドは、InvenTreeシステムで使用されているMPTT（Modified Preorder Tree Traversal）構造を持つモデルのツリーインデックスを再構築し、階層データの整合性を回復する。

**業務上の目的・背景**：InvenTreeでは、部品カテゴリ、在庫ロケーション、製造指示などの階層構造データをMPTTアルゴリズムで管理している。データインポートやデータベース操作後にMPTTインデックスが破損することがあり、その結果、階層表示の不整合やクエリエラーが発生する可能性がある。本コマンドは、全てのMPTTモデルのツリー構造を再計算し、データベースの整合性を回復する。

**バッチの実行タイミング**：手動実行（CLI）。データインポート後、データベース復元後、またはツリー構造の問題が検出された場合に実行される。

**主要な処理内容**：
1. メンテナンスモードを有効化
2. Part（部品）モデルのツリーを再構築
3. PartCategory（部品カテゴリ）モデルのツリーを再構築
4. StockItem（在庫品目）モデルのツリーを再構築
5. StockLocation（在庫ロケーション）モデルのツリーを再構築
6. Build（製造指示）モデルのツリーを再構築
7. メンテナンスモードを無効化

**前後の処理との関連**：データインポート後やデータベース復元後に実行することを推奨。他のユーザーアクセスを防ぐため、メンテナンスモード中に実行される。

**影響範囲**：Part、PartCategory、StockItem、StockLocation、Buildテーブルのlft, rght, tree_id, levelフィールドが更新される。

## バッチ種別

データメンテナンス / インデックス再構築 / CLIコマンド

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（手動） |
| 実行時刻 | メンテナンス時間帯 |
| 実行曜日 | 不定 |
| 実行日 | 不定 |
| トリガー | CLIコマンド: `python manage.py rebuild_models` |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| データベース接続 | InvenTreeデータベースに正常に接続できること |
| 排他的アクセス | 他のユーザーがデータを変更していないこと |

### 実行可否判定

特別な実行可否判定はないが、メンテナンスモードを自動的に有効化してユーザーアクセスを防止する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 本コマンドは入力パラメータを受け取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| part_part | DB | 部品テーブル |
| part_partcategory | DB | 部品カテゴリテーブル |
| stock_stockitem | DB | 在庫品目テーブル |
| stock_stocklocation | DB | 在庫ロケーションテーブル |
| build_build | DB | 製造指示テーブル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| part_part | DB | ツリー構造フィールドの更新 |
| part_partcategory | DB | ツリー構造フィールドの更新 |
| stock_stockitem | DB | ツリー構造フィールドの更新 |
| stock_stocklocation | DB | ツリー構造フィールドの更新 |
| build_build | DB | ツリー構造フィールドの更新 |
| ログ | Log | 再構築処理のログ |

### 出力ファイル仕様

本コマンドはファイル出力を行わない。

## 処理フロー

### 処理シーケンス

```
1. メンテナンスモードを有効化
   └─ with maintenance_mode_on():
2. Partモデルの再構築
   └─ logger.info('Rebuilding Part objects')
   └─ Part.objects.rebuild()
3. PartCategoryモデルの再構築
   └─ logger.info('Rebuilding PartCategory objects')
   └─ PartCategory.objects.rebuild()
4. StockItemモデルの再構築
   └─ logger.info('Rebuilding StockItem objects')
   └─ StockItem.objects.rebuild()
5. StockLocationモデルの再構築
   └─ logger.info('Rebuilding StockLocation objects')
   └─ StockLocation.objects.rebuild()
6. Buildモデルの再構築
   └─ logger.info('Rebuilding Build objects')
   └─ Build.objects.rebuild()
7. メンテナンスモードを無効化
   └─ set_maintenance_mode(False)
```

### フローチャート

```mermaid
flowchart TD
    A[コマンド開始] --> B[メンテナンスモード有効化]
    B --> C[Part再構築]
    C --> D{成功?}
    D -->|Yes| E[PartCategory再構築]
    D -->|No| E1[エラーログ出力]
    E1 --> E
    E --> F{成功?}
    F -->|Yes| G[StockItem再構築]
    F -->|No| F1[エラーログ出力]
    F1 --> G
    G --> H{成功?}
    H -->|Yes| I[StockLocation再構築]
    H -->|No| H1[エラーログ出力]
    H1 --> I
    I --> J{成功?}
    J -->|Yes| K[Build再構築]
    J -->|No| J1[エラーログ出力]
    J1 --> K
    K --> L{成功?}
    L -->|Yes| M[メンテナンスモード無効化]
    L -->|No| L1[エラーログ出力]
    L1 --> M
    M --> N[コマンド終了]
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Part再構築 | part_part | UPDATE | lft, rght, tree_id, levelの更新 |
| PartCategory再構築 | part_partcategory | UPDATE | lft, rght, tree_id, levelの更新 |
| StockItem再構築 | stock_stockitem | UPDATE | lft, rght, tree_id, levelの更新 |
| StockLocation再構築 | stock_stocklocation | UPDATE | lft, rght, tree_id, levelの更新 |
| Build再構築 | build_build | UPDATE | lft, rght, tree_id, levelの更新 |

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

#### MPTTモデル共通（各テーブル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | lft | 再計算された左値 | ツリートラバーサル用 |
| UPDATE | rght | 再計算された右値 | ツリートラバーサル用 |
| UPDATE | tree_id | 再計算されたツリーID | ルート識別用 |
| UPDATE | level | 再計算された深さ | 階層レベル |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Exception | モデルのrebuild()失敗 | エラーログ出力、次のモデルへ継続 |
| - | DatabaseError | データベース操作エラー | エラーログ出力、次のモデルへ継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（各モデルの再構築は1回のみ試行） |
| リトライ間隔 | なし |
| リトライ対象エラー | なし（エラー時は次のモデルへ継続） |

### 障害時対応

個別モデルの再構築に失敗しても、他のモデルの処理は継続される。失敗したモデルはエラーログに記録され、必要に応じて個別に対処する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 各モデルのrebuild()処理ごと |
| コミットタイミング | 各モデルの再構築完了後 |
| ロールバック条件 | 個別再構築処理でのエラー発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | モデルあたり数千〜数万レコード |
| 目標処理時間 | データ量依存（数分〜数十分） |
| メモリ使用量上限 | 大規模データセットでは注意が必要 |

## 排他制御

メンテナンスモードにより、処理中は他のユーザーからのアクセスをブロックする。これにより、再構築中のデータ不整合を防止する。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | 各モデル処理開始時 | "Rebuilding {Model} objects" |
| エラーログ | 再構築失敗時 | "Error rebuilding {Model} objects" |
| 終了ログ | 全処理完了時 | メンテナンスモード解除 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | データ量に依存 | システム管理者 |
| エラー発生 | 1件以上 | システム管理者 |

## 備考

- 本コマンドはDjango管理コマンド（BaseCommand）として実装されている
- 実行方法: `python manage.py rebuild_models`
- MPTTライブラリの `objects.rebuild()` メソッドを使用
- メンテナンスモードは `maintenance_mode` パッケージを使用
- 各モデルの処理は独立しており、1つの失敗が他に影響しない設計
- データインポート後やフィクスチャ読み込み後に実行することを推奨
- 大量データの場合は処理時間が長くなる可能性がある
- structlogを使用したログ出力
