Skip to content

[COMMS-879] Restore semantic identifier in-memory after a failed project move#24203

Open
judithroth wants to merge 1 commit into
devfrom
bug/comms-879-numeric-id-shown-instead-of-semantic-one-on-the-error-message-while-moving-work-packages-between-projects-v2
Open

[COMMS-879] Restore semantic identifier in-memory after a failed project move#24203
judithroth wants to merge 1 commit into
devfrom
bug/comms-879-numeric-id-shown-instead-of-semantic-one-on-the-error-message-while-moving-work-packages-between-projects-v2

Conversation

@judithroth

Copy link
Copy Markdown
Contributor

https://community.openproject.org/wp/COMMS-879

What are you trying to accomplish?

Use the correct (semantic) identifier in the error message after failed project move.

What approach did you choose and why?

WorkPackages::SetAttributesService#clear_semantic_identifier nils out identifier/sequence_number in memory before contract validation runs, so a fresh one can be allocated after a successful move without violating the (project_id, sequence_number) unique index. If the move then fails contract validation, nothing is ever saved -- the DB row's real identifier is untouched -- but the work package object returned to the caller kept the cleared identifier, so anything reading formatted_id/display_id off it (error messages, to_s, ...) showed a bare numeric id instead.

Restore identifier/sequence_number from their pre-clear values via dirty tracking once SetAttributesService knows the contract rejected the change, so every consumer of the returned work package sees accurate data instead of only patching the one view that renders it.

An AR-level after_validation callback was considered but doesn't work: the model's own validations run before the contract's own validators add their errors (see ModelContract#valid?), so an after_validation hook can't see contract-only failures like an invalid assignee. Restoring once SetAttributesService's full validation result is known avoids that timing issue and the risk of resurrecting the same unique-constraint hazard on the success path.

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

…ect move

https://community.openproject.org/wp/COMMS-879

WorkPackages::SetAttributesService#clear_semantic_identifier nils out
identifier/sequence_number in memory before contract validation runs, so a
fresh one can be allocated after a successful move without violating the
(project_id, sequence_number) unique index. If the move then fails contract
validation, nothing is ever saved -- the DB row's real identifier is
untouched -- but the work package object returned to the caller kept the
cleared identifier, so anything reading formatted_id/display_id off it
(error messages, to_s, ...) showed a bare numeric id instead.

Restore identifier/sequence_number from their pre-clear values via dirty
tracking once SetAttributesService knows the contract rejected the change,
so every consumer of the returned work package sees accurate data instead
of only patching the one view that renders it.

An AR-level after_validation callback was considered but doesn't work: the
model's own validations run before the contract's own validators add their
errors (see ModelContract#valid?), so an after_validation hook can't see
contract-only failures like an invalid assignee. Restoring once
SetAttributesService's full validation result is known avoids that timing
issue and the risk of resurrecting the same unique-constraint hazard on the
success path.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ensures work packages keep their semantic identifier in-memory when a project move fails contract validation, so downstream consumers (e.g., controller flash/error messages) don’t fall back to showing the bare numeric ID.

Changes:

  • Restore identifier/sequence_number after a failed validation when they were cleared as part of a project move attempt.
  • Add service-level spec coverage to ensure the semantic identifier is restored on the returned work package.
  • Add controller spec coverage to ensure the error flash shows the semantic identifier (not #<id>) when the move fails.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
app/services/work_packages/set_attributes_service.rb Restores semantic identifier attributes after unsuccessful contract validation.
app/models/work_package/semantic_identifier.rb Adds restore_identifier_after_failed_move to rehydrate cleared identifier fields using dirty tracking.
spec/services/work_packages/set_attributes_service_spec.rb Verifies identifier/sequence_number/formatted_id are restored after a failed move validation.
spec/controllers/work_packages/moves_controller_spec.rb Verifies failure flash message contains semantic identifier and not the numeric #id.

@github-actions

Copy link
Copy Markdown

Warning

Flaky specs

  • rspec ./spec/features/types/subtypes_index_spec.rb[1:5]
🤖 Ask Copilot to investigate

Copy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer.

@copilot The following spec(s) are flaky in CI (first seen on PR #24203, linked for reference only):

- `rspec ./spec/features/types/subtypes_index_spec.rb[1:5]`

Treat this as a standalone task, unrelated to PR #24203. Create a new branch from origin/dev and open a new pull request targeting dev — do not stack it on PR #24203 or reuse that branch.

Follow the playbook in docs/development/testing/handling-flaky-tests/README.md to find the root cause and fix the underlying race — do not skip, delete, or weaken the spec to make it pass; disabling is a last resort per the playbook, and only with a bug ticket. Verify the fix by running the spec(s) repeatedly (e.g. `script/bulk_run_rspec --run-count 10`).

If you cannot reproduce the flake or are not confident in a fix after reasonable investigation, do not fabricate a change or skip the spec to force CI green. Instead, leave the pull request in draft and document what you tried, the suspected cause, and any leads in its description, then assign @judithroth to take over.

Once the fix is verified, title the PR after the spec(s) it fixes, and use the PR description to explain the root cause, how the change resolves it, and the before/after results. Label the PR `flaky-spec`, assign @judithroth, and request a review from @judithroth.
On every commit, set @judithroth as the sole co-author with a `Co-authored-by:` trailer (use their GitHub no-reply email so it links to their account), so it is traceable who dispatched the fix.

@judithroth judithroth marked this pull request as ready for review July 10, 2026 12:12
@github-actions

Copy link
Copy Markdown

Caution

The provided work package version does not match the core version

Details:

Please make sure that:

  • The work package version OR your pull request target branch is correct

@judithroth judithroth requested a review from a team July 10, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants