Add V116 migration (parent_uuid on entity_data) + sortable_handle on draggable_list#538
Merged
Conversation
Nullable self-referential UUID column with a b-tree index and no ON DELETE cascade. Lets each entity data row point at another row of the same entity as its parent — a built-in system field on every row, always present, optional to fill, never user-removable (it does not appear in entities.fields_definition). Same shape as V103 (catalogue's nested categories): the context layer owns parent/child cascade rules so the soft-delete machinery and the activity log stay in the loop. Same-entity enforcement (a parent must share entity_uuid) is also a context responsibility — the self-FK has no view of entity_uuid. Bumps @current_version 115 → 116 in postgres.ex and adds the LATEST-marked moduledoc entry. Originally authored as V115 against an older dev tip; renumbered after rebasing onto upstream's V115 (phoenix_kit_annotations).
Optional attr (default nil) that, when set to a CSS selector, emits data-sortable-handle on the container and skips the cursor-grab styling on the item wrapper. The SortableGrid hook reads the data attribute and feeds it to SortableJS's `handle` option, restricting drag initiation to elements matching the selector inside each item. Mirrors the convention <.table_default> already uses with :on_reorder → ".pk-drag-handle". Lets consumers render their own handle (e.g. a hover-revealed bars icon) instead of making the whole card grabbable. Backward-compatible: existing call sites without :sortable_handle keep the whole-item drag behavior.
ddon
pushed a commit
that referenced
this pull request
May 12, 2026
7 findings: 1 BUG-LOW (my carry-over from PR #536 — V114 down SQL suffix collision because UUIDv7's first 8 chars are timestamp not random), 5 IMPROVEMENT-LOW (V116 no-op conditional, prefix_str drift, self-loop CHECK, defensive table_exists, component test TODO widening), 1 IMPROVEMENT-LOW component (sortable_handle typo-safety). Strengths: mirrors V103 catalogue pattern, idempotent, no-cascade trade-off documented, sortable_handle is purely additive (JS already supported data-sortable-handle), PR description honest about pre- existing test failure. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ddon
pushed a commit
that referenced
this pull request
May 12, 2026
Code (PR #538 #1 — carry-over from PR #536 follow-up): - V114 down SQL: switch the collision-suffix source from `substring(uuid::text from 1 for 8)` (UUIDv7 timestamp prefix — same millisecond ⇒ identical prefix ⇒ duplicate suffixed keys when two+ rows collide on (provider, name)) to `substring(uuid::text from 25 for 8)` (the post-variant random tail, 32 bits of entropy ⇒ 1-in-4B collision probability per pair). Mirrored in `run_down!` in `v114_test.exs` since the test duplicates the SQL. - V114 moduledoc updated to spell out the suffix source and why the timestamp prefix was wrong. The fix is forward-compat: systems that already ran V114.down get the old (potentially-collided) keys; fresh installs and any future rollback get the corrected behavior. Docs (PR #538 #6): - AGENTS.md TODO entry for `<.draggable_list>` test coverage widened to call out the new `:sortable_handle` axis: three branches (`:draggable=false`, `:draggable=true + sortable_handle=nil`, `:draggable=true + sortable_handle=".pk-drag-handle"`). Plus a one-line `mix format` normalization in V116 (multi-line `execute(...)` collapsed to single line). mix precommit: compile → format → credo --strict (0 findings) → dialyzer (160 errors all skipped) clean. Deferred to maintainer: #2 / #3 / #5 (cosmetics on deployed migrations), #4 (DB-level self-loop CHECK — needs a V117), #7 (`sortable_handle` typo safety — design call on boolean shape vs JS warning). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ddon
pushed a commit
that referenced
this pull request
May 12, 2026
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ddon
pushed a commit
that referenced
this pull request
May 12, 2026
CHANGELOG: covers PRs #536 (Integrations V114 + IntegrationPicker + form fixes), #537 (V115 annotations + Etcher overlay + AnnotationComposer), #538 (V116 entity_data parent_uuid + sortable_handle), plus all post-merge review fixes folded into dev between merges. Organized Added / Changed / Fixed / i18n to match the 1.7.108 entry's style. AGENTS.md: the "entries written by the maintainer, not agents — flag the gap and stop" line was filling context with a false rule. Replaced with reality: agents draft the entry against the bumped @Version heading. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two independent additions on top of the post-V115 upstream:
V116 —
parent_uuidself-FK onphoenix_kit_entity_dataso eachentity-data row can point at another row of the same entity as its
parent. System field — always present, optional, never user-removable
(does not appear in
entities.fields_definition). Same shape as V103(catalogue's nested categories): nullable self-FK, no
ON DELETEcascade, b-tree index on
(parent_uuid). Same-entity scope + cycleprevention are context-layer responsibilities in
phoenix_kit_entities.sortable_handleattribute on<.draggable_list>so consumerscan render their own grab handle (e.g. a hover-revealed bars icon)
instead of making the whole card draggable. Optional, default
nil—backward-compatible with every existing call site. Mirrors the
:on_reorder→.pk-drag-handleconvention<.table_default>already ships.
Companion PR
BeamLabEU/phoenix_kit_entities— consumes V116 (parent_uuidschema +context layer) and the new
:sortable_handleattr (card-view DnD inWeb.Entities+Web.DataNavigator).Verification
mix compile— clean.mix test— 1230 / 1231 pass (one pre-existing failure inV114Test "N >= 3 collision: exactly one plain key, N-1 distinct suffixed keys"— unrelated to this PR; theV114.down/1collision-suffix logic ships a duplicate
integration:openrouter:work-<8-char>in the test fixture).
(
IF NOT EXISTSon both the column and the index).down/1drops the index then the column; comment marker rewritesto '115' on rollback.
Test plan
mix format --check-formattedmix credo --strict(no new findings)mix compile --warnings-as-errorsmix test(1230 of 1231; 1 pre-existing flake noted above)down/1smoke: marker rewrites to 115, column + index dropped