# バッチ設計書 24-translation:extract

## 概要

本ドキュメントは、Symfonyフレームワークの`translation:extract`コンソールコマンドのバッチ設計書である。このコマンドは、テンプレートやPHPコードから翻訳キーを抽出し、翻訳ファイルに追加する機能を提供する。

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

`translation:extract`コマンドは、Symfonyアプリケーションのテンプレートおよびソースコードを解析して翻訳メッセージキーを抽出し、既存の翻訳ファイルとマージして未翻訳キーを特定・出力する多機能な翻訳管理ユーティリティである。

**業務上の目的・背景**：多言語対応のWebアプリケーション開発において、テンプレートやコードに散在する翻訳キーを手動で管理することは非効率であり、翻訳漏れの原因となる。本コマンドは、コードから自動的に翻訳キーを抽出し、翻訳ファイルに追加することで、翻訳作業の効率化と翻訳漏れの防止を実現する。新しい翻訳キーの検出、不要な翻訳キーのクリーンアップ、翻訳ファイルの自動更新を一括して行える。

**バッチの実行タイミング**：開発中の翻訳キー追加時、リリース前の翻訳漏れチェック時、翻訳ファイルの一括更新時に手動で実行される。

**主要な処理内容**：
1. 翻訳パスとコードパスを特定する（デフォルトパスまたはバンドル指定）
2. テンプレートからExtractorInterfaceで翻訳キーを抽出する
3. 既存の翻訳ファイルをTranslationReaderInterfaceで読み込む
4. MergeOperationまたはTargetOperationでカタログを処理する
5. `--dump-messages`指定時は抽出結果をコンソールに表示する
6. `--force`指定時は翻訳ファイルに書き込む
7. ソート、ドメインフィルタ、ツリー形式出力などのオプションに対応する

**前後の処理との関連**：`debug:translation`（No.20）が翻訳メッセージの状態を表示するのに対し、本コマンドは翻訳ファイルの更新を行う。`translation:push`（No.43）や`translation:pull`（No.44）と併用して翻訳ワークフローを構成する。

**影響範囲**：`--force`オプション使用時は翻訳ファイル（XLF, YAML等）を直接更新する。`--dump-messages`のみの場合は読み取り専用。

## バッチ種別

データ抽出・更新 / 翻訳管理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動（開発者による任意実行） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| TranslationWriterInterfaceが利用可能 | 翻訳ファイルの書き込み機能が登録されていること |
| TranslationReaderInterfaceが利用可能 | 翻訳ファイルの読み込み機能が登録されていること |
| ExtractorInterfaceが利用可能 | テンプレートからの翻訳キー抽出機能が登録されていること |
| --forceまたは--dump-messagesが指定 | いずれかが必須 |

### 実行可否判定

`--force`と`--dump-messages`のいずれも指定されていない場合はエラーとなる（終了コード1）。指定されたフォーマットがサポートされていない場合もエラーとなる。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| locale | string | Yes | なし | 対象ロケール |
| bundle | string | No | null | バンドル名またはディレクトリパス |
| --prefix | string | No | __ | 新規翻訳キーに付与するプレフィックス |
| --no-fill | bool | No | false | 翻訳値を空のままにする |
| --format | string | No | xlf12 | 出力フォーマット（xlf12, xlf20, その他Writerサポート形式） |
| --dump-messages | bool | No | false | メッセージをコンソールに表示 |
| --force | bool | No | false | 翻訳ファイルに書き込む |
| --clean | bool | No | false | 見つからなかったメッセージを削除 |
| --domain | string | No | null | 特定ドメインのみを抽出 |
| --sort | string | No | null | アルファベット順ソート（asc/desc） |
| --as-tree | int | No | null | ツリー形式での出力（インラインYAMLに切り替えるレベル） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| テンプレートファイル | Twig/PHP等 | 翻訳キー抽出元のテンプレート |
| 翻訳ファイル | XLF/YAML/PHP等 | 既存の翻訳定義ファイル |
| ソースコード | PHP | 翻訳キー抽出元のソースコード |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 翻訳ファイル | XLF/YAML等 | --force使用時に更新される翻訳ファイル |
| コンソール（stdout） | テキスト | --dump-messages使用時の抽出結果 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 翻訳ドメイン.ロケール.フォーマット拡張子 |
| 出力先 | 翻訳パスディレクトリ |
| 文字コード | UTF-8 |
| フォーマット | XLF 1.2/2.0, YAML等（--formatオプションで指定） |

## 処理フロー

### 処理シーケンス

```
1. 入力バリデーション
   └─ --forceまたは--dump-messagesの指定確認
   └─ フォーマットの妥当性検証
2. パス決定
   └─ バンドル指定時: バンドルの翻訳パス・コードパスを設定
   └─ 未指定時: デフォルトの翻訳パス・コードパスを使用
3. テンプレート解析・キー抽出
   └─ ExtractorInterfaceで翻訳キーを抽出しMessageCatalogueに格納
4. 既存翻訳ファイル読み込み
   └─ TranslationReaderInterfaceで現在の翻訳カタログを読み込み
5. ドメインフィルタリング
   └─ --domain指定時は対象ドメインのみに絞り込み
6. カタログ処理
   └─ --clean: TargetOperation（不要キー削除）
   └─ デフォルト: MergeOperation（新規キー追加）
7. Intlドメイン移行
   └─ 新規メッセージをIntlドメインに移動可能な場合は移動
8. メッセージ表示（--dump-messages時）
   └─ ドメイン別に新規・既存・不要キーを色分けして表示
9. ファイル書き込み（--force時）
   └─ ソート適用後、TranslationWriterInterfaceで翻訳ファイルに書き込み
10. 完了メッセージ出力
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{--forceまたは--dump-messages?}
    B -->|No| C[エラー: オプション未指定]
    B -->|Yes| D[フォーマット検証]
    D --> E{フォーマット有効?}
    E -->|No| F[エラー: 不正フォーマット]
    E -->|Yes| G[パス決定]
    G --> H[テンプレート解析・キー抽出]
    H --> I[既存翻訳ファイル読み込み]
    I --> J{--domain指定?}
    J -->|Yes| K[ドメインフィルタリング]
    J -->|No| L{--clean指定?}
    K --> L
    L -->|Yes| M[TargetOperation]
    L -->|No| N[MergeOperation]
    M --> O[Intlドメイン移行]
    N --> O
    O --> P{--dump-messages?}
    P -->|Yes| Q[メッセージ表示]
    P -->|No| R{--force?}
    Q --> R
    R -->|Yes| S[翻訳ファイル書き込み]
    R -->|No| T[完了メッセージ]
    S --> T
    T --> U[バッチ終了]
    C --> U
    F --> U
```

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

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

データベース操作なし。本コマンドはファイルシステム上の翻訳ファイルのみを操作する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | オプション未指定 | --forceと--dump-messagesのいずれも未指定 | いずれかのオプションを指定 |
| 1 | 不正フォーマット | サポートされていないフォーマットを指定 | サポートフォーマット（xlf12, xlf20等）を指定 |
| 1 | 不正ソート順 | asc/desc以外のソート順を指定 | asc または desc を指定 |
| InvalidArgumentException | バンドル未発見 | 指定されたバンドル名が存在しない | 正しいバンドル名を指定 |

### リトライ仕様

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

### 障害時対応

翻訳ファイルの書き込み失敗時は、ファイルシステムの権限とディスク容量を確認する。翻訳ファイルのバックアップを取得してから再実行することが推奨される。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 全体一括 |
| コミットタイミング | 全ドメインの処理完了後に一括書き込み |
| ロールバック条件 | ファイルシステムレベルでのロールバック機能はなし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | テンプレート数・翻訳キー数に依存（数百〜数千キー） |
| 目標処理時間 | 数秒〜数十秒 |
| メモリ使用量上限 | 標準的なCLIメモリ制限内 |

## 排他制御

翻訳ファイルへの同時書き込みは推奨されない。`--force`オプション使用時は排他的に実行すること。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | 対象ロケール、対象バンドル/ディレクトリ |
| 進捗ログ | テンプレート解析時 | "Parsing templates..." |
| 進捗ログ | 翻訳ファイル読み込み時 | "Loading translation files..." |
| 進捗ログ | ファイル書き込み時 | "Writing files..." |
| 結果ログ | ドメイン別 | ドメイン名、メッセージ数、新規/既存/不要キーリスト |
| 終了ログ | バッチ終了時 | 抽出件数と更新結果 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 該当なし | 該当なし | 該当なし |

開発時ユーティリティのため、監視・アラートは不要。

## 備考

- XLIFFフォーマットは`xlf12`（XLIFF 1.2）と`xlf20`（XLIFF 2.0）の2バージョンをサポート
- `--no-fill`オプションを使用すると、翻訳値を空のままにして翻訳キーのみを抽出する（`--prefix`は無効化される）
- `--clean`オプション使用時はTargetOperationが適用され、コード中に見つからなかった翻訳キーが削除される
- `--as-tree`オプションはYAML形式でのみ有効で、翻訳キーをツリー構造で出力する
- 重複する翻訳パスは自動的にフィルタリングされる
- メッセージのIntlドメイン（`+intl-icu`サフィックス付き）への自動移行機能を持つ
