PhoenixKitManufacturing.Web.MachineTypeTemplateLive (PhoenixKitManufacturing v0.3.2)

Copy Markdown View Source

Hidden-route mini-editor for a single machine_type entity's field_template — the list of dynamic metadata fields rendered on the machine form for machines linked to that type (see Machines.merged_field_template/1).

Why this exists

machine_type CRUD moved to the generic phoenix_kit_entities admin UI as part of the entities migration (dev_docs/ENTITIES_MIGRATION_SPEC.md), but that generic form only renders fields_definition-declared fields — field_template is deliberately not declared there (declaring it would expose a raw, unvalidated JSON-array editor with none of this module's row-level validation). It also isn't stored in data at all: the generic form's Multilang.put_language_data/3 fully replaces the primary-language data block with only its declared fields on every save, which would silently drop an undeclared key living there. So field_template lives in metadata["field_template"] instead (see EntitiesRegistry's "Record shape" moduledoc section), a column the generic entities form never touches — and this small standalone LiveView is the only way to edit it.

Route

manufacturing/machine-types/:uuid/template, visible: false in PhoenixKitManufacturing.admin_tabs/0 — never appears in the sidebar. :uuid is the machine_type entity-data record's own uuid. Reachable from a pencil icon next to each type badge on Web.MachineFormLive's General tab, or by direct URL (Paths.machine_type_template/1).

Row shape & validation

Reuses the row shape and per-row validation rules of the pre-migration machine_type_form_live.ex (removed in E12): each row is a string-keyed map with key (~r/^[a-z0-9_]+$/, must be unique within the template), label, type (text/number/date/boolean/select), an optional unit, an optional required flag, and — mandatory and non-empty only when type == "select" — an options list. Unlike the removed schema's version, validation here is plain Elixir (validate_rows/1), not an Ecto changeset — field_template is a nested array inside EntityData's freeform metadata map, not a field of its own to cast/3.

@field_template_rows is a plain assign, not changeset-bound: every row input uses a raw name="field_template[IDX][key]" (not @form[:atom]), refreshed from submitted params on every phx-change="validate", same convention MachineFormLive uses for its dynamic metadata inputs.

Persistence

Saves via EntityData.update/3 with only metadata: in the attrs — Map.putted onto the record's existing metadata (not replaced) so legacy_uuid (and any other key living there) survives untouched. Reads are a plain EntityData.get/2 (not through EntitiesRegistry — this page edits a single record it already knows the uuid of, so the ETS cache buys nothing); EntityData.update/3 broadcasts its own PhoenixKitEntities.Events message, so EntitiesRegistry picks up the change on its own.

persist/2 re-reads the record via EntityData.get/1 immediately before merging, rather than reusing socket.assigns.entity_data (the mount-time snapshot) — the session can sit open on this page for a while, and another process (e.g. the trash flow writing trashed_from_status, see phoenix_kit_entities) may have written a different metadata key in the meantime. Merging onto a fresh read avoids clobbering that concurrent write with the stale snapshot's copy of the same key.

Summary

Functions

on_mount(atom, params, session, socket)