PhoenixKitOG.Assignments (PhoenixKitOG v0.4.0)

Copy Markdown View Source

Context for binding templates to scopes inside a consumer module's hierarchy.

Hierarchy resolution

A consumer module's refine_og/4 walks an ordered list of {scope_type, scope_uuid} tuples (most specific first) — the first scope with an assignment wins.

Assignments.resolve_template("publishing", [
  {"post", post_uuid},
  {"group", group_uuid},
  {"default", nil}
])

Returns {:ok, template} or :none.

Summary

Functions

%{template_uuid => assignment count} for the templates that have any.

Creates the assignment for a scope, slot mapping included, as one write and one activity row. A scope that already has an assignment is an {:error, changeset} (the unique indexes), never a silent overwrite — set/5 is the upsert.

Deletes every assignment bound to a template and returns the rows it actually removed (DELETE … RETURNING). A row that was moved to another template, or removed, by a concurrent transaction is not in the result.

Returns nil when no assignment has that uuid.

All assignments owned by module_key, preloaded with their template for display in the assignments admin UI.

The assignments bound to one template, any consumer module.

Walks the hierarchy, returns the first template that wins.

Same walk as resolve_template/2 but also returns the winning assignment's slot_mapping so callers can substitute template slots in one pass.

Upserts an assignment. Pass scope_uuid: nil for the module-wide default tier.

Changes the template and slot mapping of THIS assignment row — its scope is not an input, so an edit can never land on another scope's row. One write, one activity row.

Updates just the slot_mapping on an existing assignment. The wiring UI writes here every time a slot dropdown changes.

Functions

clear(module_key, scope_type, scope_uuid, opts \\ [])

@spec clear(String.t(), String.t(), binary() | nil, keyword()) ::
  {:ok, PhoenixKitOG.Schemas.Assignment.t()} | {:error, :not_found}

count_by_template()

@spec count_by_template() :: %{required(binary()) => pos_integer()}

%{template_uuid => assignment count} for the templates that have any.

create(module_key, scope_type, scope_uuid, template_uuid, slot_mapping, opts \\ [])

@spec create(String.t(), String.t(), binary() | nil, binary(), map(), keyword()) ::
  {:ok, PhoenixKitOG.Schemas.Assignment.t()} | {:error, Ecto.Changeset.t()}

Creates the assignment for a scope, slot mapping included, as one write and one activity row. A scope that already has an assignment is an {:error, changeset} (the unique indexes), never a silent overwrite — set/5 is the upsert.

delete_for_template(template_uuid)

@spec delete_for_template(binary()) :: [PhoenixKitOG.Schemas.Assignment.t()]

Deletes every assignment bound to a template and returns the rows it actually removed (DELETE … RETURNING). A row that was moved to another template, or removed, by a concurrent transaction is not in the result.

get(module_key, scope_type, scope_uuid)

@spec get(String.t(), String.t(), binary() | nil) ::
  PhoenixKitOG.Schemas.Assignment.t() | nil

get_by_uuid(uuid)

@spec get_by_uuid(binary()) :: PhoenixKitOG.Schemas.Assignment.t() | nil

Returns nil when no assignment has that uuid.

list_for_module(module_key)

@spec list_for_module(String.t()) :: [PhoenixKitOG.Schemas.Assignment.t()]

All assignments owned by module_key, preloaded with their template for display in the assignments admin UI.

list_for_template(template_uuid)

@spec list_for_template(binary()) :: [PhoenixKitOG.Schemas.Assignment.t()]

The assignments bound to one template, any consumer module.

resolve_template(module_key, hierarchy)

@spec resolve_template(String.t(), [{String.t(), binary() | nil}]) ::
  {:ok, PhoenixKitOG.Schemas.Template.t()} | :none

Walks the hierarchy, returns the first template that wins.

Skips tuples whose scope_uuid is nil for any scope other than "default" — those represent "no id resolvable" (e.g. a post without a group) and should pass through to the next tier.

resolve_template_with_mapping(module_key, hierarchy)

@spec resolve_template_with_mapping(String.t(), [{String.t(), binary() | nil}]) ::
  {:ok, PhoenixKitOG.Schemas.Template.t(), map()} | :none

Same walk as resolve_template/2 but also returns the winning assignment's slot_mapping so callers can substitute template slots in one pass.

set(module_key, scope_type, scope_uuid, template_uuid, opts \\ [])

@spec set(String.t(), String.t(), binary() | nil, binary(), keyword()) ::
  {:ok, PhoenixKitOG.Schemas.Assignment.t()} | {:error, Ecto.Changeset.t()}

Upserts an assignment. Pass scope_uuid: nil for the module-wide default tier.

update(assignment, template_uuid, slot_mapping, opts \\ [])

Changes the template and slot mapping of THIS assignment row — its scope is not an input, so an edit can never land on another scope's row. One write, one activity row.

update_slot_mapping(assignment, mapping, opts \\ [])

@spec update_slot_mapping(PhoenixKitOG.Schemas.Assignment.t(), map(), keyword()) ::
  {:ok, PhoenixKitOG.Schemas.Assignment.t()} | {:error, Ecto.Changeset.t()}

Updates just the slot_mapping on an existing assignment. The wiring UI writes here every time a slot dropdown changes.