Transfer TLG to Org: Dynamically migrate project-associated org-sharded tables

Summary

Implement a dynamic approach to migrate project-associated models when transferring a top-level group to a new organization, similar to the approach used in !218968 (merged) for user-associated models.

Background

MR !218968 (merged) introduced a dynamic model discovery approach in Organizations::Transfer::UsersService that:

  1. Finds all ApplicationRecord descendants with exactly one User association AND one Organizations::Organization association
  2. Dynamically determines the foreign key via reflection
  3. Batch updates organization_id for rows matching the transferring user IDs

This issue applies the same pattern for project-associated models.

Proposal

Create a mechanism (new service or extend existing) that:

  1. Discovers models with exactly one Project association AND one Organizations::Organization association
  2. Excludes models that need special handling (e.g., Project itself, Note, Snippet)
  3. Uses reflection to find the project foreign key (project_id, etc.)
  4. Updates organization_id for rows belonging to projects being transferred

Candidate Models (to verify at implementation)

Based on codebase analysis, models that may be migratable:

  • PoolRepository
  • SnippetRepository
  • SlackIntegration
  • BulkImports::Entity
  • Integrations::SlackWorkspace::IntegrationApiScope
  • EE: PushRule, Vulnerabilities::Export, Dependencies::DependencyListExport, Ai::Catalog::Item

Models to skip (handled separately or special logic needed)

  • Project (already handled in GroupsService)
  • Note (has author replacement logic)
  • Snippet / ProjectSnippet (complex handling)
  • Todo (has bot author logic)
  • Label (marked as no_work_needed)

Implementation Notes

  • Reference: app/services/organizations/transfer/users_service.rb for the pattern
  • Service location TBD: could be new service or extension of GroupsService
  • Verify index exists on project foreign key for all affected models
  • Ensure spec/lib/gitlab/organizations/organization_transfer_support_spec.rb passes, update the relevant db/docs/*.yml files to mark tables as organization_transfer_support: supported

Acceptance Criteria

  • Dynamic model discovery implemented for project-associated models
  • Specs validate all discovered models are updated during transfer
  • db/docs/*.yml files updated for affected tables
  • Update config/organizations/transfer_support.yml — change status from issue URL to supported for affected tables

References

Edited by tim mccarthy