Generic Oban worker that translates one resource's fields into a single target language, shared by every consumer module.
Resolves a PhoenixKit.Modules.AI.Translatable adapter from the
job's resource_type (registered via ai_translatables/0 and
discovered through PhoenixKit.ModuleRegistry), then runs:
adapter.fetch/2 → adapter.source_fields/2 →
Translation.translate_fields/6 → adapter.put_translation/4broadcasting {:ai_translation, event, payload} at each lifecycle step
(see PhoenixKit.Modules.AI.Translations) and writing one
ai.translation_added activity entry on success.
Job args
%{
"resource_type" => "catalogue_item",
"resource_uuid" => uuid,
"endpoint_uuid" => uuid,
"prompt_uuid" => uuid,
"source_lang" => "en",
"target_lang" => "es",
"actor_uuid" => uuid_or_nil
}De-duplication
De-dup is app-level in PhoenixKit.Modules.AI.Translations.enqueue/1
(one in-flight job per (resource_type, resource_uuid, target_lang)), NOT
Oban's built-in unique:. Oban's uniqueness query references the
:suspended job state, which is absent from the oban_job_state enum on
hosts that upgraded the Oban lib ahead of its migration — there the
query raises 22P02 and kills every enqueue. The app guard queries only
the four always-present states (available/scheduled/executing/
retryable) and fails open. Same trade-off as the catalogue PDF worker.