PhoenixKitPublishing.AITranslatable (PhoenixKitPublishing v0.1.14)

Copy Markdown View Source

PhoenixKit.Modules.AI.Translatable adapter for publishing posts — the per-module hook into core's generic AI-translation pipeline (PhoenixKit.Modules.AI.{Translations,TranslateWorker}).

Replaces the bespoke Workers.TranslatePostWorker, which translated every language sequentially in a single Oban job. Translations.enqueue_all_missing/2 dispatches one job per target language, so they run in parallel (bounded by the Oban queue) — wall-clock drops from the sum of all languages to ~the slowest single one.

Resource identity

resource_type is "publishing_post"; resource_uuid is the post's uuid (core validates it as a real UUID). Translations target the post's active version — the version the editor normally works on.

Fields

source_fields/2 returns %{"title", "content"} read in the source language. put_translation/4 creates the target-language content row (via add_language_to_post when absent) and writes the translated title/content, generating the per-language url_slug locally from the translated title via SlugHelpers.slugify/1. That honors the configured slug style and avoids trusting an AI-returned slug (which a reasoning model can mangle).

Concurrency

Each target language is a distinct phoenix_kit_publishing_contents row (unique on version_uuid + language), so concurrent per-language jobs never touch the same row — no merge/lock dance is needed (unlike JSONB-on-one-row consumers).

Events

pubsub_topics/1 returns the post's translations topic, so core's {:ai_translation, …} lifecycle events reach the editor LiveView (already subscribed to that topic). Per-language content creation also emits publishing's own :translation_created via add_language_to_post.

Summary

Functions

The resource_type string this adapter serves.

Types

t()

@type t() :: %PhoenixKitPublishing.AITranslatable{
  group_slug: String.t(),
  post_slug: String.t() | nil,
  post_uuid: String.t(),
  version: pos_integer() | nil
}

Functions

resource_type()

@spec resource_type() :: String.t()

The resource_type string this adapter serves.