Claim ServiceDeskSetting project_key_address_slug

What does this MR do and why?

Claims uniqueness across cells for the column service_desk_settings.project_key_address_slug via the Topology Service.

The bucket type SERVICE_DESK_PROJECT_KEY_ADDRESS_SLUGS was already added to the topology service and is available through the vendored client gem, so this MR only wires up the model:

  • Adds cells_claims_attribute :project_key_address_slug behind the new default-off feature flag cells_claims_service_desk_settings_project_key_address_slugs
  • Extends cells_claims_scope so the verification service also scans records that only have a project_key_address_slug
  • Adds claim specs following the claims development docs

This is needed so incoming service desk emails using a custom project_key (incoming+<full-path-slug>-<project_key>@...) can be routed to the correct cell.

DB review

Migration UP
main: == [advisory_lock_connection] object_id: 162640, pg_backend_pid: 41030
main: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: migrating 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0383s
main: -- index_exists?(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :where=>"custom_email IS NOT NULL OR project_key IS NOT NULL", :algorithm=>:concurrently})
main:    -> 0.0025s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0006s
main: -- add_index(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :where=>"custom_email IS NOT NULL OR project_key IS NOT NULL", :algorithm=>:concurrently})
main:    -> 0.0047s
main: -- execute("RESET statement_timeout")
main:    -> 0.0147s
main: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: migrated (0.0829s) 

main: == [advisory_lock_connection] object_id: 162640, pg_backend_pid: 41030
ci: == [advisory_lock_connection] object_id: 162640, pg_backend_pid: 41035
ci: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: migrating 
ci: -- transaction_open?(nil)
ci:    -> 0.0000s
ci: -- view_exists?(:postgres_partitions)
ci:    -> 0.0005s
ci: -- index_exists?(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :where=>"custom_email IS NOT NULL OR project_key IS NOT NULL", :algorithm=>:concurrently})
ci:    -> 0.0028s
ci: -- execute("SET statement_timeout TO 0")
ci:    -> 0.0004s
ci: -- add_index(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :where=>"custom_email IS NOT NULL OR project_key IS NOT NULL", :algorithm=>:concurrently})
ci:    -> 0.0049s
ci: -- execute("RESET statement_timeout")
ci:    -> 0.0004s
ci: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: migrated (0.0271s) 

ci: == [advisory_lock_connection] object_id: 162640, pg_backend_pid: 41035
sec: == [advisory_lock_connection] object_id: 162640, pg_backend_pid: 41037
sec: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: migrating 
sec: -- transaction_open?(nil)
sec:    -> 0.0000s
sec: -- view_exists?(:postgres_partitions)
sec:    -> 0.0005s
sec: -- index_exists?(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :where=>"custom_email IS NOT NULL OR project_key IS NOT NULL", :algorithm=>:concurrently})
sec:    -> 0.0031s
sec: -- execute("SET statement_timeout TO 0")
sec:    -> 0.0004s
sec: -- add_index(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :where=>"custom_email IS NOT NULL OR project_key IS NOT NULL", :algorithm=>:concurrently})
sec:    -> 0.0043s
sec: -- execute("RESET statement_timeout")
sec:    -> 0.0005s
sec: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: migrated (0.0261s) 

sec: == [advisory_lock_connection] object_id: 162640, pg_backend_pid: 41037
Migration DOWN
bin/rails db:migrate:down:main db:migrate:down:ci db:migrate:down:sec VERSION=20260722025718                                         604184-claim-project-key-address-slug ✭ ✚
main: == [advisory_lock_connection] object_id: 161940, pg_backend_pid: 40490
main: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: reverting 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0446s
main: -- index_exists?(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :algorithm=>:concurrently})
main:    -> 0.0060s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0005s
main: -- remove_index(:service_desk_settings, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :algorithm=>:concurrently, :column=>:project_id})
main:    -> 0.0071s
main: -- execute("RESET statement_timeout")
main:    -> 0.0004s
main: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: reverted (0.0991s) 

main: == [advisory_lock_connection] object_id: 161940, pg_backend_pid: 40490
ci: == [advisory_lock_connection] object_id: 161940, pg_backend_pid: 40526
ci: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: reverting 
ci: -- transaction_open?(nil)
ci:    -> 0.0000s
ci: -- view_exists?(:postgres_partitions)
ci:    -> 0.0017s
ci: -- index_exists?(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :algorithm=>:concurrently})
ci:    -> 0.0168s
ci: -- execute("SET statement_timeout TO 0")
ci:    -> 0.0010s
ci: -- remove_index(:service_desk_settings, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :algorithm=>:concurrently, :column=>:project_id})
ci:    -> 0.0100s
ci: -- execute("RESET statement_timeout")
ci:    -> 0.0009s
ci: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: reverted (0.0791s) 

ci: == [advisory_lock_connection] object_id: 161940, pg_backend_pid: 40526
sec: == [advisory_lock_connection] object_id: 161940, pg_backend_pid: 40535
sec: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: reverting 
sec: -- transaction_open?(nil)
sec:    -> 0.0000s
sec: -- view_exists?(:postgres_partitions)
sec:    -> 0.0006s
sec: -- index_exists?(:service_desk_settings, :project_id, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :algorithm=>:concurrently})
sec:    -> 0.0044s
sec: -- execute("SET statement_timeout TO 0")
sec:    -> 0.0006s
sec: -- remove_index(:service_desk_settings, {:name=>"idx_service_desk_settings_where_custom_email_or_project_key", :algorithm=>:concurrently, :column=>:project_id})
sec:    -> 0.0057s
sec: -- execute("RESET statement_timeout")
sec:    -> 0.0007s
sec: == 20260722025718 AddServiceDeskSettingsCustomEmailOrProjectKeyPresentIndex: reverted (0.0382s) 

sec: == [advisory_lock_connection] object_id: 161940, pg_backend_pid: 40535
Select records for verification worker (with new index)

https://console.postgres.ai/gitlab/projects/gitlab-production-main/sessions/53963/commands/156339

SELECT * FROM service_desk_settings WHERE (custom_email IS NOT NULL OR project_key IS NOT NULL) AND project_id > 6163284 LIMIT 1000;
Select records for verification worker (without index)

https://console.postgres.ai/gitlab/projects/gitlab-production-main/sessions/53963/commands/156337

SELECT * FROM service_desk_settings WHERE (custom_email IS NOT NULL OR project_key IS NOT NULL) AND project_id > 6163284 LIMIT 1000;

References

Related to #604184

How to set up and validate locally

  1. Enable cells claims and the new flag:

    Feature.enable(:cells_claims_service_desk_settings_project_key_address_slugs)
  2. With a cell-enabled GDK and the Topology Service running, create or update a ServiceDeskSetting with a project_key and verify a claim is created for the derived project_key_address_slug.

Edited by Mario Celi

Merge request reports

Loading