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 by project_id + excluding docs whose traversal_ids already match the new ancestry

Screenshots or screen recordings

N/A — backend only.

Before After

How to set up and validate locally

  1. Enable Elasticsearch indexing in GDK
  2. Create a group old-root with a subgroup child containing a project with some issues (project-level work items)
  3. Index: bundle exec rake gitlab:elastic:index
  4. Confirm docs exist in work_items index under routing group_<old-root-id> with no namespace_id field
  5. Transfer child group (or old-root) to a new root group
  6. Before this MR: stale docs remain in the old routing shard
  7. After this MR: DeleteWorker with task: :delete_project_work_items is enqueued per project, removing stale docs that don't match the new traversal_ids prefix

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.

Merge request reports

Loading