Skip to content

Reject an approved change set and publish items in a stable order - #2637

Merged
pournasserian merged 5 commits into
v2from
2616-reject-approved
Oct 19, 2026
Merged

pournasserian merged 5 commits into
v2from
2616-reject-approved

Conversation

@pournasserian

Copy link
Copy Markdown
Member

Closes #2616

What

A follow-up of F-CHG (#2418), from the post-merge review of publish (#2482) and revert (#2511).

  • Core (ChangeSetTransitions): the table gains approved → rejected.
  • Entries: a rejected set holds nothing in review (CNT-01), so the entries of an approved set that a person rejects leave review with no further change.
  • Publish moves its items sorted by item kind and id, then appends their events in the set's order. Two sets that publish the same items take their row locks in the same order: the later one waits, finds its base gone and fails with base_version_stale.
  • Deadlocks: a PostgreSQL deadlock (40P01) or serialization failure (40001) during a publish, or at the commit of any change set write, is answered with change_set_conflict instead of an exception, as a unique violation already is (DatabaseErrors.IsConcurrencyFailure).
  • Desk: the set view offers Reject on an approved set too, next to Publish. Its hint says to reject it with a reason if it can no longer publish.

Why

An approved set whose publish has gone stale could never leave approved. For example, two reverts of one set are both approved and the first publishes. The second then sat approved forever, and its entries stayed in review. Rebasing a stale set is out of scope: a person rejects it and the author opens a new set.

Publish moved items in the order the set lists them. On PostgreSQL, two sets that list the same items in opposite orders deadlocked, and one call threw.

Choices worth a look:

  • Lock order instead of retry. Sorting the pointer moves removes the cycle. The deadlock mapping stays as a safety net for writers outside publish.
  • The mapping has no test of its own. With the sort in place, two publishes no longer deadlock, and no other writer here takes two item rows. To check the race test, I removed the sort and the mapping on purpose: it failed on PostgreSQL with 40P01: deadlock detected, and with both back it passes.
  • Events keep the set's order, so the audit log reads as the set was written, whatever order the rows were locked in.
  • The desk change is two conditions and one hint. Without it, a person had no way to reach the new move from the admin.

Tests

Unit:

  • The transition table lists approved → rejected, and every other transition stays as it was.
  • Reject from approved succeeds with a reason, and stays refused where the table has no rejection.
  • The check engine cannot reject an approved set.
  • The set view offers Publish and Reject for an approved set.

Integration, each on SQLite and PostgreSQL:

  • Two reverts R1 and R2 of one published set are both approved, and R1 publishes. R2's publish then fails with base_version_stale, and its entry stays in review. A blank reason is refused. With a reason, R2 is rejected, the entry leaves review, and the original set stays reverted once.
  • Two approved sets update the same two content types from the same base, listed in opposite orders, and publish at the same time, five rounds in a row. Each round, one wins, the other fails with base_version_stale, and neither call throws.
  • The table-driven tests cover the new transition for agents (refused and logged) and for people (stored with its event).

dotnet build -warnaserror and the full suite pass locally on SQLite and against a postgres:17 container. No new package and no new project reference.

Checklist

  • Linked to an issue a maintainer has confirmed
  • Targets v2
  • Tests or docs updated where behaviour changed
  • No tool-generated co-author trailers or footers

@pournasserian pournasserian added this to the M1 Governance core milestone Oct 19, 2026
@pournasserian pournasserian added type:feature New capability v2 FluentCMS v2 (v2 branch) area:change-sets Change sets (CHG) labels Oct 19, 2026
@pournasserian
pournasserian merged commit 7dd21d8 into v2 Oct 19, 2026
2 checks passed
@pournasserian
pournasserian deleted the 2616-reject-approved branch October 19, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:change-sets Change sets (CHG) type:feature New capability v2 FluentCMS v2 (v2 branch)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reject an approved change set and publish items in a stable order

1 participant