Skip to content

Revert: a change set that restores the previous version of every item #2510

Closed

Description

@pournasserian

Part of #2418 (F-CHG). Fifth slice: one revert action (CHG-06, D22). Reverting a published change set opens a new change set whose operations put every item of the original back at the version it had before. Once that set is approved and published, the live content reads exactly as before the original, and the original moves to reverted in the same unit of work. It builds on atomic publish (#2478).

Scope

  • Core (FluentCMS.Core.ChangeSets): ChangeOperation.Inverse() returns the operation that undoes one. A create becomes a delete based on the created version, an update becomes an update from its proposed version back to its base version, and a delete becomes a create that proposes the deleted version. An update back to an earlier version exists only as an inverse; ChangeOperation.Create still requires a later version.
  • Core: ChangeSet.Revert(rationale, initiator) on a published set opens a new set that holds the inverse of every operation in the original's order and names the original in RevertsChangeSetId. A revert names the set it undoes instead of citing sources, and needs a rationale like any set. A set that is not published fails with transition_not_allowed. Operations cannot be added to a revert set (revert_set_fixed), so publishing it restores exactly what the original changed.
  • IChangeSetDirectory.RevertAsync(changeSetId, rationale) stores the revert set with its operations and their change_set.opened and change_set.operation_added events, and returns it. Before the unit of work it refuses an unknown set (change_set_not_found), a set that is not published, and a set with an item that moved on since it was published (base_version_stale, as its publish would). An agent cannot revert, as Refuse agents' review moves and enforce change set caps #2503 decided for the move to reverted (MCP-06).
  • Publish: publishing a revert set also moves the original from published to reverted, over the revision it read, and appends change_set.reverted after change_set.published, all in the same unit of work. If the original is no longer published, the publish fails and writes nothing. TransitionAsync to reverted fails with transition_not_allowed: a set is reverted only by publishing its revert.
  • Infrastructure: ChangeSets.RevertsChangeSetId, nullable and indexed, with a foreign key to the reverted set. Migrations for SQLite and PostgreSQL.

Out of scope

Acceptance

  • Reverting a published set that creates one content type, updates a second and deletes a third opens a set that names the original. In the original's order, it holds a delete of the created version, an update from the proposed version back to the base version, and a create of the deleted version. Each operation's event names the row of the version it is based on, and the set's diff shows each item going back.
  • Once the revert set is approved and published, each content type's published version is where it was before the original. The original is reverted, and the events are one per item, then change_set.published for the revert and change_set.reverted for the original.
  • Reverting the revert publishes the original's versions again and moves the revert to reverted.
  • An unknown set, a set that is not published, a set with an item that moved on, a blank rationale and an agent are refused, and none of them writes a set or a change set event. Adding an operation to a revert set is refused. TransitionAsync to reverted is refused.
  • Of two reverts of one set, only the first to publish goes through. The second fails and writes nothing, and the original is reverted once.
  • A failure injected at any audit append while a revert publishes leaves the items, the revert and the original as they were.
  • All of the above passes on SQLite and PostgreSQL, the new migration's Down works, and ProjectReferenceRulesTests pass with no new package.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:featureNew capabilityv2FluentCMS v2 (v2 branch)

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions