# バッチ設計書 24-cleanup_import_sessions

## 概要

本ドキュメントは、5日以上経過した古いデータインポートセッションを削除するバッチ処理「cleanup_import_sessions」の設計仕様を定義する。

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

このバッチは、InvenTreeシステムにおけるデータインポート機能で作成されたセッションデータを定期的にクリーンアップし、不要なデータの蓄積を防ぐことでシステムのパフォーマンスとストレージ効率を維持する。

**業務上の目的・背景**：データインポート機能を使用すると、インポートセッションの情報（アップロードファイル、マッピング設定、インポート結果等）がデータベースに保存される。これらのセッションデータは一時的なものであり、長期間保持する必要はない。本バッチは、古くなったセッションデータを自動削除することで、データベースの肥大化を防ぎ、システムの安定運用を支援する。

**バッチの実行タイミング**：日次でスケジュール実行されるが、実際の削除処理は5日に1回のみ実行される（holdoff機構による制御）。

**主要な処理内容**：
1. check_daily_holdoffにより5日間の実行間隔を確認
2. 5日以上経過したDataImportSessionレコードを検索
3. 該当するセッションを削除
4. 成功時にrecord_task_successで完了を記録

**前後の処理との関連**：本バッチは独立して動作し、他のバッチとの直接的な依存関係はない。

**影響範囲**：importer_dataimportsessionテーブルの削除操作、関連するアップロードファイルの削除に影響する。

## バッチ種別

データクレンジング / データ削除

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 日次（実際の処理は5日に1回） |
| 実行時刻 | Django-Qスケジューラの設定に依存 |
| 実行曜日 | 毎日 |
| 実行日 | 毎日（ただし処理は5日間隔） |
| トリガー | Django-Q ScheduledTask.DAILY |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| データベース接続 | InvenTreeデータベースに正常に接続できること |
| Django-Qワーカー稼働 | バックグラウンドワーカーが稼働していること |

### 実行可否判定

- `check_daily_holdoff('cleanup_import_sessions', 5)` により、前回成功から5日経過しているかを確認
- 5日未満の場合は処理をスキップしてreturn

## 入力仕様

### 入力パラメータ

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

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| importer_dataimportsession | DB | データインポートセッションテーブル |
| common_inventreesetting | DB | タスク実行履歴（_cleanup_import_sessions_SUCCESS等） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| importer_dataimportsession | DB | 古いセッションの削除 |
| common_inventreesetting | DB | タスク成功日時の記録 |
| ログ | Log | 削除件数等の処理結果ログ |

### 出力ファイル仕様

本バッチはファイル出力を行わない（ただし、削除対象セッションに関連するアップロードファイルは削除される）。

## 処理フロー

### 処理シーケンス

```
1. クリーンアップ対象日数の定義
   └─ CLEANUP_DAYS = 5
2. 実行間隔の確認
   └─ check_daily_holdoff('cleanup_import_sessions', CLEANUP_DAYS)
3. 5日以内に実行済みの場合は終了
   └─ return
4. ログ出力：クリーンアップ開始
   └─ logger.info('Cleaning old data import sessions')
5. 削除対象日付の計算
   └─ before = current_date() - timedelta(days=CLEANUP_DAYS)
6. 古いセッションの検索
   └─ DataImportSession.objects.filter(timestamp__lte=before)
7. 該当セッションの削除
   └─ sessions.delete()
8. 削除件数をログ出力
   └─ logger.info('Deleting %s old data import sessions', sessions.count())
9. タスク成功を記録
   └─ record_task_success('cleanup_import_sessions')
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{check_daily_holdoff}
    B -->|5日未満| C[バッチ終了]
    B -->|5日以上経過| D[削除対象日付を計算]
    D --> E[古いセッションを検索]
    E --> F{該当セッションあり?}
    F -->|なし| G[タスク成功を記録]
    F -->|あり| H[セッションを削除]
    H --> I[削除件数をログ出力]
    I --> G
    G --> C
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 実行履歴確認 | common_inventreesetting | SELECT | 前回成功日時の取得 |
| 古いセッション検索 | importer_dataimportsession | SELECT | timestamp <= 5日前のレコード |
| セッション削除 | importer_dataimportsession | DELETE | 該当セッションの削除 |
| 成功記録 | common_inventreesetting | INSERT/UPDATE | タスク成功日時の記録 |

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

#### importer_dataimportsession

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | timestamp | <= current_date() - 5日 | 5日以上経過したセッション |
| DELETE | - | 上記条件に該当するレコード | カスケード削除される関連データあり |

#### common_inventreesetting

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | key | = '_cleanup_import_sessions_SUCCESS' | 前回成功日時 |
| SELECT | key | = '_cleanup_import_sessions_ATTEMPT' | 前回試行日時 |
| UPDATE | value | 現在日時のISO形式 | 成功時に更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | DatabaseError | データベース接続エラー | Django-Qがリトライを実行 |
| - | IntegrityError | 参照整合性エラー | ログ出力、処理中断 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Django-Qのデフォルト設定に依存 |
| リトライ間隔 | Django-Qのデフォルト設定に依存 |
| リトライ対象エラー | 一時的なデータベースエラー |

### 障害時対応

バッチ失敗時はrecord_task_successが呼ばれないため、次回実行時に再度クリーンアップが試行される。手動でのリカバリは不要。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 削除処理全体 |
| コミットタイミング | 全削除完了後 |
| ロールバック条件 | 削除処理中のエラー発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数件〜数百件/実行 |
| 目標処理時間 | 数分以内 |
| メモリ使用量上限 | 通常のDjangoプロセス制限内 |

## 排他制御

同時実行の制御はDjango-Qのスケジューラに委ねられている。check_daily_holdoffにより、12時間以内の重複実行は防止される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | クリーンアップ開始時 | "Cleaning old data import sessions" |
| 進捗ログ | 削除実行時 | "Deleting {件数} old data import sessions" |
| 終了ログ | バッチ終了時 | Django-Qによる自動ログ |
| エラーログ | エラー発生時 | エラー詳細、スタックトレース |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | Django-Qのタイムアウト設定 | システム管理者 |
| エラー件数 | Django-Q Failure テーブル | システム管理者 |

## 備考

- 本バッチは `@InvenTree.tasks.scheduled_task(InvenTree.tasks.ScheduledTask.DAILY)` デコレータにより日次実行される
- `check_daily_holdoff` と `record_task_success` を使用した5日間隔の実行制御を実装
- CLEANUP_DAYSは5日間で固定値として定義されている
- 削除対象の判定には `InvenTree.helpers.current_date()` を使用し、タイムゾーン対応がされている
- DataImportSessionの削除により、関連するアップロードファイルもDjangoのシグナルで削除される可能性がある
