Skip to content

[19.0][FIX] base_tier_validation: don't promote later tiers out of sequence#53

Open
bosd wants to merge 1 commit into
OCA:19.0from
bosd:19.0-fix-sequential-premature-promotion
Open

[19.0][FIX] base_tier_validation: don't promote later tiers out of sequence#53
bosd wants to merge 1 commit into
OCA:19.0from
bosd:19.0-fix-sequential-premature-promotion

Conversation

@bosd

@bosd bosd commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Problem

With approve_sequence, a later-tier review could be promoted to pending before its predecessor is approved, which then:

  • hides it from that reviewer's own systray (can_review is False while the lower tier still holds the minimum sequence), and
  • mis-routes the notify_on_pending chatter message to the previous reviewer instead of the intended one.

Root cause

tier.review._update_review_status gates promotion on min(self.mapped("sequence")) — the minimum over the recordset it happens to be called on, not the whole record. res.users.review_user_count calls it as user.review_ids._update_review_status(), i.e. on a single user's reviews. For a second-tier reviewer that subset contains only their own (higher-sequence) review, so it becomes the "minimum" and is promoted prematurely the moment they open their systray.

The premature pending then cascades: can_review evaluates False (the lower tier holds the min sequence) → hidden from the systray; the notify_on_pending message is posted in that reviewer's own transaction → they are excluded as its author and the alert lands on the previous reviewer; and when the first tier is finally approved the review is already pending, so it is skipped and no correct notification ever fires.

Fix

Compute the gating sequence over the whole record's open reviews (per res_id), not the passed recordset. No behaviour change for the normal full-recordset call (request_validation_update_review_status).

Test

Adds test_19c_no_premature_promotion_on_subset, which runs _update_review_status on only the later-tier reviewer's review (the review_user_count path) and asserts it stays waiting and posts no message. test_19a only exercised the full-recordset path, so the regression slipped through.

``tier.review._update_review_status`` computed the "next sequence to promote"
with ``min(self.mapped("sequence"))`` -- over the recordset it was called on,
not the whole record. ``res.users.review_user_count`` calls it as
``user.review_ids._update_review_status()`` (one user's reviews). For a
second-tier reviewer that subset contains only their own (higher-sequence)
review, so it became the "minimum" and was promoted to ``pending`` before the
first tier was approved.

That single premature promotion cascaded:
- the review's ``can_review`` is then False (the lower, still-pending tier holds
  the minimum sequence), so it is hidden from the reviewer's own systray;
- the ``notify_on_pending`` message is posted in -- and authored by -- that
  reviewer's transaction, so they are excluded as the author and the alert is
  delivered to the *previous* tier's reviewer instead;
- when the first tier is later approved, the review is already ``pending`` and
  is skipped, so no correct notification ever fires.

Gate the sequence over the whole record's open reviews (per ``res_id``) instead
of the passed recordset. Add ``test_19c_no_premature_promotion_on_subset``
covering the subset path that ``test_19a`` (full-recordset) did not.
@OCA-git-bot

Copy link
Copy Markdown
Contributor

Hi @LoisRForgeFlow,
some modules you are maintaining are being modified, check this out!

@OCA-git-bot OCA-git-bot added mod:base_tier_validation Module base_tier_validation series:19.0 labels Jun 23, 2026
bosd pushed a commit to bosd/tier-validation that referenced this pull request Jun 23, 2026
Backport of the upstream fix (OCA#53) onto this branch.

_update_review_status gated promotion on min(self.mapped("sequence")) -- the
minimum over the recordset it was called on, not the whole record. Since
review_user_count runs it as user.review_ids._update_review_status() (one
user's reviews), a second-tier reviewer's review became the "minimum" of that
subset and was promoted to pending before the first tier was approved -- hiding
it from their systray and mis-routing the notify_on_pending message to the
previous reviewer. Gate on the whole record's open reviews instead.

Adds test_19c_no_premature_promotion_on_subset. Bump 19.0.1.0.4 -> 19.0.1.0.5.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:base_tier_validation Module base_tier_validation series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants