MishkaCmsBuilder.Plugins.ReleaseDraftHistory (Mishka CMS Builder v0.0.1-alpha.2)

Copy Markdown View Source

Detaches a deleted draft's editing history from it, so the rows survive and join the live record's own timeline.

One plugin per destroy action of the three draft resources, each on the announcement MishkaCmsCore.Runtime.Resources.Notifiers.PluginHook fires after the destroy commits: cms_core:page_draft:after_destroy and cms_core:page_draft:after_master_destroy, and the same two for layout_draft and error_page_draft. A master's delete runs the master_destroy twin, which fires its own event, so both are listened on.

Why this is not a foreign key

It was one. MishkaCmsBuilder.HistoryEvent.draft_id was a belongs_to to MishkaCmsCore.Runtime.PageDraft with on_delete: :nilify, which did exactly this job — for pages. But source_type names all four editable kinds and three of them keep their drafts in tables of their own, so a change made on a layout's or an error page's draft violated that one key and the row was refused: the History sheet was simply empty for those two sections.

A single key cannot name three tables, so the column became a plain id and the nilify moved to the draft resources' own destroy — the same level the constraint was at, rather than any one caller. That matters because a draft is deleted from several places: the picker's Delete goes through the resource's own destroy, publishing spends the draft through MishkaCmsCore.Runtime.Authoring.Drafts.discard/3, and the twenty-draft sweep prunes through prune/3. Only the resource sees all of them, and its announcements are how the editor hears of each without the drafts naming the editor.

Best effort, deliberately

The release runs after the delete has committed and never undoes it: a draft the author asked to delete must go even if its history could not be released. A row left pointing at a draft that no longer exists is invisible rather than wrong — no read names a dead branch — so a failure is logged and the record is handed back as it came. It is never raised: a plugin that raises is skipped by the event, and the reason would be lost.

Summary

Functions

Turns the module into the plugin on event, releasing the history of the draft it announces.

Sets draft_id to nil on every history row recorded on draft_id, as actor. Always :ok; a failure is logged.

Functions

__using__(opts)

(macro)

Turns the module into the plugin on event, releasing the history of the draft it announces.

use MishkaCmsBuilder.Plugins.ReleaseDraftHistory,
  event: PluginHook.event_name(MishkaCmsCore.Runtime.PageDraft, :destroy)

release(draft_id, actor)

@spec release(String.t(), map() | nil) :: :ok

Sets draft_id to nil on every history row recorded on draft_id, as actor. Always :ok; a failure is logged.