PhoenixKitPublishing.AITranslatable (PhoenixKitPublishing v0.1.15)

Copy Markdown View Source

PhoenixKitAI.Translatable adapter for publishing posts — the per-module hook into PhoenixKitAI's generic AI-translation pipeline (PhoenixKitAI.{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 (PhoenixKitAI 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 — lowercase to match the {{title}}/{{content}} placeholders in the publishing translation prompt, the same convention as the catalogue and projects adapters (PhoenixKitAI's variable substitution is case-sensitive). 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 PhoenixKitAI'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.