Fix stale work item ES docs after group transfer
What does this MR do and why?
During a group transfer, project-level work items were not getting their stale
Elasticsearch documents cleaned up. The existing
ElasticGroupAssociationDeletionWorker filters by namespace_id, but
project-level work item ES docs don't have a namespace_id field in the index
(build_namespace_data only sets it for group namespaces — confirmed against a
live GDK index). This left stale docs in the old routing shard
(group_<old_root_ancestor_id>) after transfer, potentially causing duplicate
search results.
This MR adds delete_work_items_with_old_routing to
EE::Groups::TransferService to schedule DeleteWorker with
task: :delete_project_work_items for each project during group transfer,
mirroring the existing vulnerability cleanup pattern
(delete_vulnerabilities_with_old_routing).
References
- Spike issue: #596999 (closed)
Search::Elastic::Delete::ProjectWorkItemsService— the service that performs the actual cleanup, filtering byproject_id+ excluding docs whosetraversal_idsalready match the new ancestry
Screenshots or screen recordings
N/A — backend only.
| Before | After |
|---|---|
How to set up and validate locally
- Enable Elasticsearch indexing in GDK
- Create a group
old-rootwith a subgroupchildcontaining a project with some issues (project-level work items) - Index:
bundle exec rake gitlab:elastic:index - Confirm docs exist in
work_itemsindex under routinggroup_<old-root-id>with nonamespace_idfield - Transfer
childgroup (orold-root) to a new root group - Before this MR: stale docs remain in the old routing shard
- After this MR:
DeleteWorkerwithtask: :delete_project_work_itemsis enqueued per project, removing stale docs that don't match the newtraversal_idsprefix
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.