Loading
Transfer topics on organization group transfer
What does this MR do and why?
Implements transfer support for the topics and project_topic_uploads tables during organization group transfer.
Topics have a unique constraint on (organization_id, name), so they cannot be simply updated in place with update_organization_id_for. Instead, this MR introduces a dedicated Organizations::Transfer::TopicsService that uses a find-or-create + re-point pattern:
- For each topic in the old organization referenced by projects in the transferring group hierarchy, find or create a matching topic (by name) in the target organization
- Re-point
project_topicsfrom the old topic to the new topic, handling the case where a project already has the target topic assigned (delete the duplicate instead of violating the unique constraint) - Adjust
total_projects_countandnon_private_projects_countcounter caches via batched delta accumulation — deltas are accumulated per-topic during the loop and flushed in a single pass at the end, reducing counter UPDATE statements from 2N to N (one per affected topic)
Additional changes
db/docs/topics.yml: Marked assupportedsince topics are now handled by the transfer servicedb/docs/project_topic_uploads.yml: Marked asno_work_neededsince it derives itsorganization_idvia the topic'suploads_sharding_key- Spec housekeeping: Added
feature_category: :groups_and_projectstoproject_topic_spec.rbandtopic_spec.rb
Depends on: !243721 (merged)
References
Relates to #594592 (closed)
How to set up and validate locally
# In rails console
old_org = Organizations::Organization.find(...)
new_org = Organizations::Organization.find(...)
group = Group.find(...)
user = User.find(...)
# Verify topics exist on projects
group.all_projects.flat_map(&:topics).map(&:name)
# Execute transfer
result = Organizations::Transfer::GroupsService.new(
group: group, new_organization: new_org, current_user: user
).execute
# Verify topics were transferred
group.reload.all_projects.flat_map { |p| p.reload.topics }.map { |t| [t.name, t.organization_id] }MR acceptance checklist
- Tests added for all new functionality
- All existing tests pass
- RuboCop passes with no offenses
Edited by tim mccarthy