翻訳 プロセス

sequenceDiagram
  participant C as Client
  participant A as FastAPI /fields/translate
  participant DB as Postgres (portal_fields)
  participant T as I18nTranslator
  participant O as OpenAI API

  C->>A: POST /fields/translate (dry_run=true)
  A->>DB: SELECT 対象行 (ids/only_missing/limit 反映)
  DB-->>A: rows
  loop 各 row
    A->>T: fill_missing_recursively(value)
    alt *_i18n 辞書かつ target 未設定
      T->>O: 翻訳(ja_JP→en_US)
      O-->>T: translated_text
      T-->>A: after値 + changed=true
    else list/dict/その他
      T-->>A: 再帰結果 / 変更なし
    end
    alt dry_run=true
      A-->>C: preview_samples に {before/after} を積む(応答)
    else dry_run=false
      A->>DB: UPDATE portal_fields ... , updated_at=NOW()
      DB-->>A: OK
    end
  end
  A-->>C: {processed, updated, dry_run, preview_samples}
graph TD
  A["クライアント<br/>(Swagger / CLI)"] -->|POST /fields/translate| B["FastAPI ルータ"];
  B --> C["パラメータ検証 / 正規化"];
  C --> D["対象カラム列挙<br/>label_i18n / help_i18n / placeholder_i18n / unit_i18n / notes_i18n / selection_items / notes"];
  D --> E{"WHERE 条件組み立て"};
  E -->|ids あり| F["WHERE id IN (:ids)"];
  E -->|only_missing true| G["トップレベル i18n 欠落判定<br/>(col IS NULL OR NOT col ? :json_key)"];
  E -->|それ以外| H["フィルタなし"];
  F --> I["SELECT ... FROM portal_fields<br/>LIMIT :limit"];
  G --> I;
  H --> I;
  I --> J{"各行の処理"};
  J --> K["再帰走査 fill_missing_recursively(value)"];
  K --> L{"*_i18n 辞書か?"};
  L -->|Yes| M["未設定 target を補完<br/>(OpenAI 翻訳)"];
  L -->|No| N{"list / dict か?"};
  N -->|list| O["要素ごとに再帰"];
  N -->|dict| P["キーごとに再帰"];
  N -->|その他| Q["変更なし"];
  M --> R["diff 収集 (最大20件)"];
  O --> R;
  P --> R;
  Q --> S["変更フラグ off"];
  R --> T{"dry_run か?"};
  S --> T;
  T -->|true| U["preview_samples に積む<br/>(DB 更新なし)"];
  T -->|false| V["UPDATE をバッファへ"];
  V --> W{"to_update あり?"};
  W -->|Yes| X["TX で UPDATE + updated_at=NOW()"];
  W -->|No| Y["集計処理へ"];
  X --> Y;
  Y --> Z["JSON レスポンス (processed / updated / preview_samples)"];


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です