Add organization_id to integrations table

What does this MR do and why?

This MR adds organization_id foreign key to integrations table. Organization association presence is optional, since we can have integration associated with project or group. If integration has neither of those, it's considered instance integration, and should have organization_id set, in order to set sharding key as part of Cells work. For now, we set organization on new records and existing integration updates. In the future MR we are going to back fill existing instance integration records in a data migration and set default organization.

This MR ensures new instance integrations get their organization_id set to current integration.

Mentions #524675 (closed)

Migration output
main: == [advisory_lock_connection] object_id: 130960, pg_backend_pid: 90900
main: == 20250331144332 AddOrganizationIdFkToIntegrations: migrating ================
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- add_column(:integrations, :organization_id, :bigint, {:if_not_exists=>true})
main:    -> 0.0237s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- execute("ALTER TABLE integrations ADD CONSTRAINT fk_755d734f25 FOREIGN KEY (organization_id) REFERENCES organizations (id) ON DELETE CASCADE NOT VALID;")
main:    -> 0.0022s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0004s
main: -- execute("ALTER TABLE integrations VALIDATE CONSTRAINT fk_755d734f25;")
main:    -> 0.0032s
main: -- execute("RESET statement_timeout")
main:    -> 0.0004s
main: == 20250331144332 AddOrganizationIdFkToIntegrations: migrated (0.0940s) =======

main: == [advisory_lock_connection] object_id: 130960, pg_backend_pid: 90900
ci: == [advisory_lock_connection] object_id: 131360, pg_backend_pid: 90907
ci: == 20250331144332 AddOrganizationIdFkToIntegrations: migrating ================
ci: -- transaction_open?(nil)
ci:    -> 0.0000s
ci: -- add_column(:integrations, :organization_id, :bigint, {:if_not_exists=>true})
ci:    -> 0.0078s
ci: -- transaction_open?(nil)
ci:    -> 0.0000s
ci: -- transaction_open?(nil)
ci:    -> 0.0000s
ci: -- execute("ALTER TABLE integrations ADD CONSTRAINT fk_755d734f25 FOREIGN KEY (organization_id) REFERENCES organizations (id) ON DELETE CASCADE NOT VALID;")
ci:    -> 0.0216s
ci: -- execute("SET statement_timeout TO 0")
ci:    -> 0.0004s
ci: -- execute("ALTER TABLE integrations VALIDATE CONSTRAINT fk_755d734f25;")
ci:    -> 0.0067s
ci: -- execute("RESET statement_timeout")
ci:    -> 0.0005s
ci: == 20250331144332 AddOrganizationIdFkToIntegrations: migrated (0.0636s) =======

ci: == [advisory_lock_connection] object_id: 131360, pg_backend_pid: 90907
main: == [advisory_lock_connection] object_id: 131680, pg_backend_pid: 90911
main: == 20250423172844 AddIntegrationsOrganizationIdIndex: migrating ===============
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0006s
main: -- index_exists?(:integrations, :organization_id, {:name=>"index_integrations_on_organization_id", :algorithm=>:concurrently})
main:    -> 0.0049s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0006s
main: -- add_index(:integrations, :organization_id, {:name=>"index_integrations_on_organization_id", :algorithm=>:concurrently})
main:    -> 0.0102s
main: -- execute("RESET statement_timeout")
main:    -> 0.0005s
main: == 20250423172844 AddIntegrationsOrganizationIdIndex: migrated (0.0324s) ======

main: == [advisory_lock_connection] object_id: 131680, pg_backend_pid: 90911
ci: == [advisory_lock_connection] object_id: 131800, pg_backend_pid: 90913
ci: == 20250423172844 AddIntegrationsOrganizationIdIndex: migrating ===============
ci: -- transaction_open?(nil)
ci:    -> 0.0000s
ci: -- view_exists?(:postgres_partitions)
ci:    -> 0.0006s
ci: -- index_exists?(:integrations, :organization_id, {:name=>"index_integrations_on_organization_id", :algorithm=>:concurrently})
ci:    -> 0.0046s
ci: -- execute("SET statement_timeout TO 0")
ci:    -> 0.0004s
ci: -- add_index(:integrations, :organization_id, {:name=>"index_integrations_on_organization_id", :algorithm=>:concurrently})
ci:    -> 0.0026s
ci: -- execute("RESET statement_timeout")
ci:    -> 0.0004s
ci: == 20250423172844 AddIntegrationsOrganizationIdIndex: migrated (0.0282s) ======

ci: == [advisory_lock_connection] object_id: 131800, pg_backend_pid: 90913

References

Screenshots or screen recordings

Before After

How to set up and validate locally

  1. Go to /admin/application_settings/integrations/ as admin and create a new instance integration
  2. Check created integration in rails console and verify organization_id is set
  3. Create project/group integration, verify organization_id is not present for those records

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.

Edited by George Koltsov

Merge request reports

Loading