›
byrcsc/laravel-checklist · 1.x
Templates group immutable versions so active checklists keep the structure they started with.
Checklist wording changes over time, but work already in progress must not. The template carries the shared name. Each version holds the wording and rules as they stood when you published it, and a checklist points at one published version rather than at whichever version is newest.
Template holds the stable name for a family of versions. Sections, items,
rules, and pass thresholds belong to TemplateVersion, not to Template.
$template = $version->template;
$template->currentVersion(); // highest published version
$template->draftVersion(); // highest draft, when one exists
$template->versions(); // HasMany relationRenaming a template changes its shared name. It does not rewrite frozen item labels inside earlier versions.
A draft accepts ordinary Eloquent writes. Publishing validates the complete
tree and changes its status to published.
After publication, model events reject updates and deletes on the version, its sections, its items, and its rules. Creating a new structural row under a published version is rejected as well.
$published->update(['pass_threshold' => 90]); // throws
$published->items()->firstOrFail()->delete(); // throwsThe guard applies to model-instance writes. Eloquent mass query updates do not run model events, so this bypasses the guard:
// Do not use this against published structure.
Item::query()->whereKey($item->id)->update(['label' => 'Changed']);Route structural writes through model instances or an authoring service that enforces draft status.
$draft = $published->newDraft();
$draft->items()
->where('label', 'Tires are roadworthy')
->firstOrFail()
->update(['label' => 'Tires and wheels are roadworthy']);
$next = $draft->publish();newDraft() deep-copies sections, items, rules, configuration, ordering, and
the pass threshold. It assigns the next available version number and leaves
the source unchanged.
Each copied item gets a new database row but retains its lineage_ulid. Reports
use lineage to follow one question across versions after wording changes or
section moves.
Validation catches malformed structures created through an admin interface, not only mistakes made through the fluent builder. It rejects section cycles, foreign parents, items in sections from another version, excessive depth, unknown item types, invalid item configuration, duplicate rule keys, missing rule targets, unsupported operators, self-targeting rules, and visibility cycles.
Publication is transactional. A failed first build leaves no template or partial structure behind. A failed later publication leaves the draft in draft status.
A template with a published version cannot be deleted. A published version cannot be deleted either, because existing checklists may point at it.
A draft-only template can be deleted. Deleting a draft section removes its items and nested sections while leaving sibling sections intact.