# バッチ設計書 16-ffcrm:update_data:fix_countries

## 概要

本ドキュメントは、Fat Free CRMにおける国コード修正バッチ（ffcrm:update_data:fix_countries）の設計仕様を定義する。

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

このバッチは、住所データに含まれる国コードを誤ったマッピングからISO 3166-1標準に準拠した正しいコードに変換する処理を行う。一度限りの実行を想定したデータ移行バッチである。

**業務上の目的・背景**：Fat Free CRMの初期実装において、国コードのマッピングに誤りがあった。例えば、オーストラリア（Australia）が「AU」ではなく「AS」（アメリカ領サモアの正式コード）にマッピングされていた。この問題により、住所データの国コードが国際標準と異なる状態となっていた。本バッチを実行することで、既存の住所データを正しいISO 3166-1コードに変換し、データの整合性を回復する。外部システムとの連携や、正確な地域レポート生成のためにこの修正は重要である。

**バッチの実行タイミング**：システムアップグレード時に一度のみ実行。再実行は禁止されており、Setting.have_run_country_migrationフラグで制御される。

**主要な処理内容**：
1. 実行済みフラグの確認
2. 変換テーブル（旧コード→新コード）に基づく住所データの検索
3. 該当する住所レコードの国コードを更新
4. 実行済みフラグを設定

**前後の処理との関連**：本バッチは独立して実行されるが、関連するマイグレーションが警告メッセージを表示する場合がある。実行後は二度と実行すべきではない。

**影響範囲**：addressesテーブルのcountryカラムが更新される。約100カ国分の変換が定義されている。

## バッチ種別

データ更新 / データ移行（一回限り）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 一度のみ |
| 実行時刻 | 任意 |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| データベース接続 | アプリケーションデータベースに接続可能であること |
| addressesテーブル存在 | マイグレーション済みでaddressesテーブルが存在すること |
| 未実行状態 | Setting.have_run_country_migration が true でないこと |

### 実行可否判定

Setting.have_run_country_migration が true の場合、警告メッセージを表示して処理を中断する。これにより、誤って複数回実行されることを防止する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| N/A | - | - | - | パラメータなし |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| addresses | DB | 変換対象の住所データ |
| settings | DB | 実行済みフラグの確認 |
| 変換テーブル（コード内定義） | Array | 約100件の国コード変換ルール |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| addresses | DB | 国コードを更新 |
| settings | DB | have_run_country_migration = true |

### 出力ファイル仕様

ファイル出力なし。

## 処理フロー

### 処理シーケンス

```
1. Rails環境ロード
   └─ :environment タスクを依存関係として実行
2. 実行済みチェック
   └─ Setting.have_run_country_migration を確認
   └─ true の場合は警告を表示して終了
3. 変換対象の住所収集
   └─ 変換テーブルの各エントリをループ
   └─ 国名または旧コードに一致する住所を検索
   └─ 新コードを設定してメモリに保持
4. トランザクション開始
   └─ Address.transaction ブロック開始
5. 住所データ更新
   └─ 収集した住所を save! で保存
6. フラグ設定
   └─ Setting.have_run_country_migration = true
7. コミット/ロールバック
   └─ 成功時はコミット、失敗時はロールバック
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[Rails環境ロード]
    B --> C{have_run_country_migration?}
    C -->|true| D[警告メッセージ表示]
    D --> E[処理終了]
    C -->|false| F[変換対象住所の収集]
    F --> G[トランザクション開始]
    G --> H[住所データ更新]
    H --> I{更新成功?}
    I -->|成功| J[フラグ設定]
    J --> K[コミット]
    K --> L[バッチ終了]
    I -->|失敗| M[エラー出力]
    M --> N[ロールバック]
    N --> E
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 住所検索 | addresses | SELECT | 変換対象の住所を検索 |
| 住所更新 | addresses | UPDATE | countryカラムを更新 |
| フラグ確認 | settings | SELECT | 実行済みフラグ確認 |
| フラグ設定 | settings | INSERT/UPDATE | 実行済みフラグ設定 |

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

#### addresses

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | country | WHERE country = '旧コード' OR country = '国名' | Arel queryで検索 |
| UPDATE | country | 新しいISO 3166-1コード | save!で保存 |

**主要な変換例：**
- Australia: AS → AU
- Austria: AU → AT
- Germany: GM → DE
- Japan: JA → JP
- United Kingdom: UK → GB
- United States: USA → US

#### settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT/UPDATE | have_run_country_migration | true | 実行済みフラグ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ActiveRecord::RecordInvalid | バリデーションエラー | 住所データ更新失敗 | データを確認し修正 |
| ActiveRecord::StatementInvalid | DBエラー | データベース接続不可 | DB接続を確認 |
| Exception（全般） | 例外 | 予期しないエラー | ロールバックして調査 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. エラーメッセージを確認
2. トランザクションは自動ロールバック
3. Setting.have_run_country_migration は更新されない
4. 問題解決後に再実行可能

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 全住所更新 + フラグ設定 |
| コミットタイミング | 全処理完了時 |
| ロールバック条件 | Exception発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 住所データ量に依存（通常数百〜数千件） |
| 目標処理時間 | 数秒〜数分 |
| メモリ使用量上限 | 変換対象住所を全てメモリに保持 |

## 排他制御

本バッチ実行中のアプリケーションアクセスに注意。住所データが一時的に不整合になる可能性がある。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 警告ログ | 再実行時 | 詳細な警告メッセージ（英文） |
| エラーログ | 例外発生時 | 例外メッセージ |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| N/A | N/A | N/A |

## 備考

- **重要**：本バッチは一度しか実行してはならない
- 複数回実行すると、正しく変換されたデータが誤って別のコードに変換される
  - 例：AU（オーストラリア）→ AT（オーストリア）
- 再実行が必要な場合は、Setting.have_run_country_migration = false をコンソールで設定（非推奨）
- 変換テーブルには約100件の国コードマッピングが定義されている
- 一部の国コード（例：Aland Islands）は競合のため変換対象から除外されている
