From 7950e105af764bc16e68ee2d9be2cea6246de831 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 00:29:57 +0200 Subject: [PATCH 01/54] Update datatype model and runtime function (definition) models --- Gemfile | 2 +- Gemfile.lock | 4 +- app/models/data_type.rb | 1 + app/models/data_type_identifier.rb | 21 +++ app/models/function_definition.rb | 2 +- app/models/function_generic_mapper.rb | 19 +++ app/models/generic_mapper.rb | 19 +++ app/models/generic_type.rb | 7 + app/models/parameter_definition.rb | 2 +- app/models/runtime_function_definition.rb | 3 +- app/models/runtime_parameter_definition.rb | 2 +- .../runtimes/data_types/update_service.rb | 1 + .../update_service.rb | 31 +++- bin/rake | 0 .../20250525192143_implement_generics.rb | 86 ++++++++++ db/schema_migrations/20250525192143 | 1 + db/structure.sql | 153 ++++++++++++++++-- spec/factories/data_type_identifiers.rb | 9 ++ spec/factories/data_types.rb | 1 + spec/factories/function_definitions.rb | 2 +- spec/factories/function_generic_mappers.rb | 10 ++ spec/factories/generic_mappers.rb | 9 ++ spec/factories/generic_types.rb | 8 + .../factories/runtime_function_definitions.rb | 2 +- .../runtime_parameter_definitions.rb | 2 +- spec/models/data_type_identifier_spec.rb | 38 +++++ spec/models/function_definition_spec.rb | 2 +- spec/models/function_generic_mapper_spec.rb | 41 +++++ spec/models/generic_mapper_spec.rb | 48 ++++++ spec/models/generic_type_spec.rb | 22 +++ spec/models/parameter_definition_spec.rb | 8 +- ...ime_function_definition_error_type_spec.rb | 2 +- .../runtime_function_definition_spec.rb | 2 + .../runtime_parameter_definition_spec.rb | 4 +- ...untime_function_definition_service_spec.rb | 31 ++-- 35 files changed, 556 insertions(+), 39 deletions(-) create mode 100644 app/models/data_type_identifier.rb create mode 100644 app/models/function_generic_mapper.rb create mode 100644 app/models/generic_mapper.rb create mode 100644 app/models/generic_type.rb mode change 100644 => 100755 bin/rake create mode 100644 db/migrate/20250525192143_implement_generics.rb create mode 100644 db/schema_migrations/20250525192143 create mode 100644 spec/factories/data_type_identifiers.rb create mode 100644 spec/factories/function_generic_mappers.rb create mode 100644 spec/factories/generic_mappers.rb create mode 100644 spec/factories/generic_types.rb create mode 100644 spec/models/data_type_identifier_spec.rb create mode 100644 spec/models/function_generic_mapper_spec.rb create mode 100644 spec/models/generic_mapper_spec.rb create mode 100644 spec/models/generic_type_spec.rb diff --git a/Gemfile b/Gemfile index e976db39..5ceadfd1 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.25' +gem 'tucana', '0.0.26' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 6c6c666a..5dec9ce4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -356,7 +356,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.25) + tucana (0.0.26) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -409,7 +409,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.25) + tucana (= 0.0.26) tzinfo-data RUBY VERSION diff --git a/app/models/data_type.rb b/app/models/data_type.rb index 38fa46e5..e162af9f 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -19,6 +19,7 @@ class DataType < ApplicationRecord has_many :child_types, class_name: 'DataType', inverse_of: :parent_type has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :rules, class_name: 'DataTypeRule', inverse_of: :data_type + has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :data_type validates :variant, presence: true, inclusion: { diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb new file mode 100644 index 00000000..657ab83f --- /dev/null +++ b/app/models/data_type_identifier.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class DataTypeIdentifier < ApplicationRecord + belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers + belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier + + has_many :generic_types, inverse_of: :data_type_identifier + has_many :generic_mappers, inverse_of: :data_type_identifier + has_many :function_generic_mappers, class_name: 'GenericMapper', inverse_of: :data_type_identifier + + validate :exactly_one_of_generic_key_data_type_id_generic_type_id + + private + + def exactly_one_of_generic_key_data_type_id_generic_type_id + values = [generic_key.present?, data_type_id.present?, generic_type_id.present?] + return if values.count(true) == 1 + + errors.add(:base, 'Exactly one of generic_key, data_type_id, or generic_type_id must be present') + end +end diff --git a/app/models/function_definition.rb b/app/models/function_definition.rb index b34a7a38..389961a7 100644 --- a/app/models/function_definition.rb +++ b/app/models/function_definition.rb @@ -2,7 +2,7 @@ class FunctionDefinition < ApplicationRecord belongs_to :runtime_function_definition - belongs_to :return_type, class_name: 'DataType', optional: true + belongs_to :return_type, class_name: 'DataTypeIdentifier', optional: true has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb new file mode 100644 index 00000000..32489de2 --- /dev/null +++ b/app/models/function_generic_mapper.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class FunctionGenericMapper < ApplicationRecord + belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers + belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, + inverse_of: :generic_mappers + + validates :target, presence: true + validate :exactly_one_of_generic_key_or_data_type_identifier_id + + private + + def exactly_one_of_generic_key_or_data_type_identifier_id + values = [generic_key.present?, data_type_identifier_id.present?] + return if values.count(true) == 1 + + errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') + end +end diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb new file mode 100644 index 00000000..d2ed8fd8 --- /dev/null +++ b/app/models/generic_mapper.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class GenericMapper < ApplicationRecord + belongs_to :generic_type, inverse_of: :generic_mappers + belongs_to :data_type_identifier, optional: true, inverse_of: :generic_mappers + + validates :target, presence: true + validate :exactly_one_of_generic_key_or_data_type_identifier_id, :generic_key_changed? + validate :exactly_one_of_generic_key_or_data_type_identifier_id, :data_type_identifier_changed? + + private + + def exactly_one_of_generic_key_or_data_type_identifier_id + values = [generic_key.present?, data_type_identifier_id.present?] + return if values.count(true) == 1 + + errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') + end +end diff --git a/app/models/generic_type.rb b/app/models/generic_type.rb new file mode 100644 index 00000000..c8c1aa1d --- /dev/null +++ b/app/models/generic_type.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class GenericType < ApplicationRecord + belongs_to :data_type_identifier, inverse_of: :generic_type + + has_many :generic_mappers, inverse_of: :generic_type +end diff --git a/app/models/parameter_definition.rb b/app/models/parameter_definition.rb index c1288b49..1ae25b5d 100644 --- a/app/models/parameter_definition.rb +++ b/app/models/parameter_definition.rb @@ -2,7 +2,7 @@ class ParameterDefinition < ApplicationRecord belongs_to :runtime_parameter_definition - belongs_to :data_type + belongs_to :data_type, class_name: 'DataTypeIdentifier' has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner diff --git a/app/models/runtime_function_definition.rb b/app/models/runtime_function_definition.rb index ef295afa..f22f6ee8 100644 --- a/app/models/runtime_function_definition.rb +++ b/app/models/runtime_function_definition.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true class RuntimeFunctionDefinition < ApplicationRecord - belongs_to :return_type, class_name: 'DataType', optional: true + belongs_to :return_type, class_name: 'DataTypeIdentifier', optional: true belongs_to :runtime has_many :function_definitions, inverse_of: :runtime_function_definition has_many :parameters, class_name: 'RuntimeParameterDefinition', inverse_of: :runtime_function_definition has_many :error_types, class_name: 'RuntimeFunctionDefinitionErrorType', inverse_of: :runtime_function_definition + has_many :generic_mappers, class_name: 'FunctionGenericMapper', inverse_of: :runtime_function_definition has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner diff --git a/app/models/runtime_parameter_definition.rb b/app/models/runtime_parameter_definition.rb index 3548c6f7..ad47dbb7 100644 --- a/app/models/runtime_parameter_definition.rb +++ b/app/models/runtime_parameter_definition.rb @@ -2,7 +2,7 @@ class RuntimeParameterDefinition < ApplicationRecord belongs_to :runtime_function_definition, inverse_of: :parameters - belongs_to :data_type + belongs_to :data_type, class_name: 'DataTypeIdentifier' has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner diff --git a/app/services/runtimes/data_types/update_service.rb b/app/services/runtimes/data_types/update_service.rb index 5cb49453..70473f20 100644 --- a/app/services/runtimes/data_types/update_service.rb +++ b/app/services/runtimes/data_types/update_service.rb @@ -58,6 +58,7 @@ def update_datatype(data_type, t) end db_object.rules = update_rules(data_type.rules, db_object) db_object.names = update_translations(data_type.name, db_object.names) + db_object.generic_keys = data_type.generic_keys.to_a db_object.save end diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index a0d3f70b..89603888 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -38,7 +38,8 @@ def update_runtime_function_definition(runtime_function_definition, t) ) db_object.removed_at = nil db_object.return_type = if runtime_function_definition.return_type_identifier.present? - find_data_type(runtime_function_definition.return_type_identifier, t) + find_data_type_identifier(runtime_function_definition.return_type_identifier, + runtime_function_definition.generic_mappers, t) end db_object.parameters = update_parameters(runtime_function_definition.runtime_parameter_definitions, db_object.parameters, t) @@ -66,6 +67,32 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object end + # These mappers can be either generic mappers or generic function mappers. + def find_data_type_identifier(identifier, _generic_mappers, t) + if identifier.data_type_identifier.present? + data_type_identifier = DataTypeIdentifier.find_by(data_type: find_data_type(identifier.data_type_identifier, + t)) + + if data_type_identifier.nil? + t.rollback_and_return! ServiceResponse.error( + message: "Could not find datatype identifier with identifier #{identifier}", + payload: :no_datatype_identifier_for_identifier + ) + end + + return data_type_identifier + end + if identifier.generic_type.present? + return find_data_type_identifier(identifier.generic_type.identifier, identifier.generic_type.generic_mappers, + t) + end + if identifier.generic_key.present? + return DataTypeIdentifier.find_or_create_by(runtime: current_runtime, generic_key: identifier.generic_key) + end + + raise ArgumentError, "Invalid identifier: #{identifier.inspect}" + end + def find_data_type(identifier, t) data_type = DataType.find_by(runtime: current_runtime, identifier: identifier) @@ -90,7 +117,7 @@ def update_parameters(parameters, db_parameters, t) end db_param.runtime_name = real_param.runtime_name db_param.removed_at = nil - db_param.data_type = find_data_type(real_param.data_type_identifier, t) + db_param.data_type = find_data_type_identifier(real_param.data_type_identifier, [], t) db_param.names = update_translations(real_param.name, db_param.names) db_param.descriptions = update_translations(real_param.description, db_param.descriptions) diff --git a/bin/rake b/bin/rake old mode 100644 new mode 100755 diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb new file mode 100644 index 00000000..416af4a0 --- /dev/null +++ b/db/migrate/20250525192143_implement_generics.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +class ImplementGenerics < Code0::ZeroTrack::Database::Migration[1.0] + def change + # See: + # https://github.com/code0-tech/tucana/pull/93 + + add_column :data_types, :generic_keys, 'text[]', null: false, default: [] + + create_table :data_type_identifiers do |t| + # One of them needs to be set + t.text :generic_key, null: true + t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } + + t.timestamps_with_timezone + end + + create_table :generic_types do |t| + t.references :data_type_identifier, null: false, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + + t.timestamps_with_timezone + end + + create_table :generic_mappers do |t| + t.text :target, null: false + # One of them needs to be set + t.text :generic_key, null: true + t.references :data_type_identifier, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:generic_mappers, :source, :one_of) + + t.references :generic_type, null: false, foreign_key: { to_table: :generic_types, on_delete: :cascade } + + t.timestamps_with_timezone + end + + add_reference :data_type_identifiers, :generic_type, null: true, + foreign_key: { to_table: :generic_types, on_delete: :cascade } + + add_check_constraint :data_type_identifiers, '(num_nonnulls(generic_key, data_type_id, generic_type_id) = 1)', + name: check_constraint_name(:data_type_identifiers, :type, :one_of) + + create_table :function_generic_mappers do |t| + t.references :data_type_identifier, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + t.text :generic_key, null: true + + t.text :target, null: false + t.text :parameter_id, null: true + + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:function_generic_mappers, :source, :one_of) + + t.references :runtime_function_definition, null: true, + foreign_key: { to_table: :runtime_function_definitions, + on_delete: :cascade } + + t.timestamps_with_timezone + end + + remove_column :runtime_function_definitions, :return_type_id + add_reference :runtime_function_definitions, :return_type, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true + + add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] + + remove_column :runtime_parameter_definitions, :data_type_id + add_reference :runtime_parameter_definitions, :data_type, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true + + remove_column :parameter_definitions, :data_type_id + add_reference :parameter_definitions, :data_type, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true + + # remove_column :runtime_function_definition_error_types, :data_type_id + # add_reference :runtime_function_definition_error_types, :data_type, + # foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: false + + remove_column :function_definitions, :return_type_id + add_reference :function_definitions, :return_type, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true + end +end diff --git a/db/schema_migrations/20250525192143 b/db/schema_migrations/20250525192143 new file mode 100644 index 00000000..09c3ca43 --- /dev/null +++ b/db/schema_migrations/20250525192143 @@ -0,0 +1 @@ +1cfd7c1ab7044f53a45e081214bc16d9f5d4cfbcbf27838207cabb30fae17dfa \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 0a3e0546..9d1cc7b6 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -121,6 +121,25 @@ CREATE SEQUENCE backup_codes_id_seq ALTER SEQUENCE backup_codes_id_seq OWNED BY backup_codes.id; +CREATE TABLE data_type_identifiers ( + id bigint NOT NULL, + generic_key text, + data_type_id bigint, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + generic_type_id bigint, + CONSTRAINT check_480d44acbd CHECK ((num_nonnulls(generic_key, data_type_id, generic_type_id) = 1)) +); + +CREATE SEQUENCE data_type_identifiers_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE data_type_identifiers_id_seq OWNED BY data_type_identifiers.id; + CREATE TABLE data_type_rules ( id bigint NOT NULL, data_type_id bigint NOT NULL, @@ -148,6 +167,7 @@ CREATE TABLE data_types ( parent_type_id bigint, runtime_id bigint NOT NULL, removed_at timestamp with time zone, + generic_keys text[] DEFAULT '{}'::text[] NOT NULL, CONSTRAINT check_3a7198812e CHECK ((char_length(identifier) <= 50)) ); @@ -204,9 +224,9 @@ ALTER SEQUENCE flow_types_id_seq OWNED BY flow_types.id; CREATE TABLE function_definitions ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, - return_type_id bigint, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL + updated_at timestamp with time zone NOT NULL, + return_type_id bigint ); CREATE SEQUENCE function_definitions_id_seq @@ -218,6 +238,63 @@ CREATE SEQUENCE function_definitions_id_seq ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; +CREATE TABLE function_generic_mappers ( + id bigint NOT NULL, + data_type_identifier_id bigint, + generic_key text, + target text NOT NULL, + parameter_id text, + runtime_function_definition_id bigint, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) +); + +CREATE SEQUENCE function_generic_mappers_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers.id; + +CREATE TABLE generic_mappers ( + id bigint NOT NULL, + target text NOT NULL, + generic_key text, + data_type_identifier_id bigint, + generic_type_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) +); + +CREATE SEQUENCE generic_mappers_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; + +CREATE TABLE generic_types ( + id bigint NOT NULL, + data_type_identifier_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE generic_types_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE generic_types_id_seq OWNED BY generic_types.id; + CREATE TABLE good_job_batches ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, @@ -472,10 +549,10 @@ ALTER SEQUENCE organizations_id_seq OWNED BY organizations.id; CREATE TABLE parameter_definitions ( id bigint NOT NULL, runtime_parameter_definition_id bigint NOT NULL, - data_type_id bigint NOT NULL, default_value jsonb, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL + updated_at timestamp with time zone NOT NULL, + data_type_id bigint ); CREATE SEQUENCE parameter_definitions_id_seq @@ -506,12 +583,13 @@ ALTER SEQUENCE runtime_function_definition_error_types_id_seq OWNED BY runtime_f CREATE TABLE runtime_function_definitions ( id bigint NOT NULL, - return_type_id bigint, runtime_id bigint NOT NULL, runtime_name text NOT NULL, removed_at timestamp with time zone, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, + return_type_id bigint, + generic_keys text[] DEFAULT '{}'::text[] NOT NULL, CONSTRAINT check_fe8fff4f27 CHECK ((char_length(runtime_name) <= 50)) ); @@ -527,12 +605,12 @@ ALTER SEQUENCE runtime_function_definitions_id_seq OWNED BY runtime_function_def CREATE TABLE runtime_parameter_definitions ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, - data_type_id bigint NOT NULL, runtime_name text NOT NULL, removed_at timestamp with time zone, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, default_value jsonb, + data_type_id bigint, CONSTRAINT check_c1156ce358 CHECK ((char_length(runtime_name) <= 50)) ); @@ -665,6 +743,8 @@ ALTER TABLE ONLY audit_events ALTER COLUMN id SET DEFAULT nextval('audit_events_ ALTER TABLE ONLY backup_codes ALTER COLUMN id SET DEFAULT nextval('backup_codes_id_seq'::regclass); +ALTER TABLE ONLY data_type_identifiers ALTER COLUMN id SET DEFAULT nextval('data_type_identifiers_id_seq'::regclass); + ALTER TABLE ONLY data_type_rules ALTER COLUMN id SET DEFAULT nextval('data_type_rules_id_seq'::regclass); ALTER TABLE ONLY data_types ALTER COLUMN id SET DEFAULT nextval('data_types_id_seq'::regclass); @@ -675,6 +755,12 @@ ALTER TABLE ONLY flow_types ALTER COLUMN id SET DEFAULT nextval('flow_types_id_s ALTER TABLE ONLY function_definitions ALTER COLUMN id SET DEFAULT nextval('function_definitions_id_seq'::regclass); +ALTER TABLE ONLY function_generic_mappers ALTER COLUMN id SET DEFAULT nextval('function_generic_mappers_id_seq'::regclass); + +ALTER TABLE ONLY generic_mappers ALTER COLUMN id SET DEFAULT nextval('generic_mappers_id_seq'::regclass); + +ALTER TABLE ONLY generic_types ALTER COLUMN id SET DEFAULT nextval('generic_types_id_seq'::regclass); + ALTER TABLE ONLY namespace_licenses ALTER COLUMN id SET DEFAULT nextval('namespace_licenses_id_seq'::regclass); ALTER TABLE ONLY namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('namespace_member_roles_id_seq'::regclass); @@ -734,6 +820,9 @@ ALTER TABLE ONLY audit_events ALTER TABLE ONLY backup_codes ADD CONSTRAINT backup_codes_pkey PRIMARY KEY (id); +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT data_type_identifiers_pkey PRIMARY KEY (id); + ALTER TABLE ONLY data_type_rules ADD CONSTRAINT data_type_rules_pkey PRIMARY KEY (id); @@ -749,6 +838,15 @@ ALTER TABLE ONLY flow_types ALTER TABLE ONLY function_definitions ADD CONSTRAINT function_definitions_pkey PRIMARY KEY (id); +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT function_generic_mappers_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY generic_mappers + ADD CONSTRAINT generic_mappers_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY generic_types + ADD CONSTRAINT generic_types_pkey PRIMARY KEY (id); + ALTER TABLE ONLY good_job_batches ADD CONSTRAINT good_job_batches_pkey PRIMARY KEY (id); @@ -830,6 +928,8 @@ CREATE UNIQUE INDEX idx_on_role_id_project_id_5d4b5917dc ON namespace_role_proje CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_data_type_id_b6aa8fe066 ON runtime_function_definition_error_types USING btree (runtime_function_definition_id, data_type_id); +CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON function_generic_mappers USING btree (runtime_function_definition_id); + CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); @@ -850,6 +950,10 @@ CREATE INDEX index_audit_events_on_author_id ON audit_events USING btree (author CREATE UNIQUE INDEX "index_backup_codes_on_user_id_LOWER_token" ON backup_codes USING btree (user_id, lower(token)); +CREATE INDEX index_data_type_identifiers_on_data_type_id ON data_type_identifiers USING btree (data_type_id); + +CREATE INDEX index_data_type_identifiers_on_generic_type_id ON data_type_identifiers USING btree (generic_type_id); + CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id); CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (parent_type_id); @@ -870,6 +974,14 @@ CREATE INDEX index_function_definitions_on_return_type_id ON function_definition CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); +CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); + +CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); + +CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); + +CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); + CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON good_job_executions USING btree (active_job_id, created_at); CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON good_job_executions USING btree (process_id, created_at); @@ -965,7 +1077,7 @@ ALTER TABLE ONLY runtime_function_definition_error_types ADD CONSTRAINT fk_rails_070c5bfcf0 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY function_definitions - ADD CONSTRAINT fk_rails_0c2eb746ef FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_0c2eb746ef FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_118c914ed0 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; @@ -976,6 +1088,12 @@ ALTER TABLE ONLY namespace_roles ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; +ALTER TABLE ONLY generic_types + ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + +ALTER TABLE ONLY generic_mappers + ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -985,6 +1103,9 @@ ALTER TABLE ONLY parameter_definitions ALTER TABLE ONLY runtime_function_definition_error_types ADD CONSTRAINT fk_rails_408d037751 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_40d8496abb FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; @@ -1006,6 +1127,9 @@ ALTER TABLE ONLY namespace_member_roles ALTER TABLE ONLY namespace_role_project_assignments ADD CONSTRAINT fk_rails_623f8a5b72 FOREIGN KEY (role_id) REFERENCES namespace_roles(id); +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_65151da1fb FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; + ALTER TABLE ONLY user_identities ADD CONSTRAINT fk_rails_684b0e1ce0 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -1022,7 +1146,7 @@ ALTER TABLE ONLY namespace_role_abilities ADD CONSTRAINT fk_rails_6f3304b078 FOREIGN KEY (namespace_role_id) REFERENCES namespace_roles(id) ON DELETE CASCADE; ALTER TABLE ONLY runtime_function_definitions - ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; @@ -1033,6 +1157,9 @@ ALTER TABLE ONLY namespace_projects ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; + ALTER TABLE ONLY user_sessions ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -1055,17 +1182,23 @@ ALTER TABLE ONLY namespace_project_runtime_assignments ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY parameter_definitions - ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY namespace_projects ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY generic_mappers + ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; + ALTER TABLE ONLY runtime_parameter_definitions - ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY runtimes ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ALTER TABLE ONLY audit_events ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; diff --git a/spec/factories/data_type_identifiers.rb b/spec/factories/data_type_identifiers.rb new file mode 100644 index 00000000..7ef0303c --- /dev/null +++ b/spec/factories/data_type_identifiers.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :data_type_identifier do + generic_key { nil } + data_type { nil } + generic_type { nil } + end +end diff --git a/spec/factories/data_types.rb b/spec/factories/data_types.rb index a8b122de..2e2f4efb 100644 --- a/spec/factories/data_types.rb +++ b/spec/factories/data_types.rb @@ -8,5 +8,6 @@ runtime identifier { generate(:data_type_name) } parent_type { nil } + generic_keys { [] } end end diff --git a/spec/factories/function_definitions.rb b/spec/factories/function_definitions.rb index 0f74a251..91ecd68e 100644 --- a/spec/factories/function_definitions.rb +++ b/spec/factories/function_definitions.rb @@ -2,7 +2,7 @@ FactoryBot.define do factory :function_definition do - return_type factory: :data_type + return_type { nil } runtime_function_definition end end diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb new file mode 100644 index 00000000..e5579f87 --- /dev/null +++ b/spec/factories/function_generic_mappers.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :function_generic_mapper do + target { nil } + parameter_id { nil } + generic_key { nil } + data_type_identifier { nil } + end +end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb new file mode 100644 index 00000000..b601b3c5 --- /dev/null +++ b/spec/factories/generic_mappers.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :generic_mapper do + target { nil } + generic_key { nil } + data_type_identifier { nil } + end +end diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb new file mode 100644 index 00000000..f26bc778 --- /dev/null +++ b/spec/factories/generic_types.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :generic_type do + generic_mappers { [] } + data_type_identifier { nil } + end +end diff --git a/spec/factories/runtime_function_definitions.rb b/spec/factories/runtime_function_definitions.rb index 370ecbd6..e61c3771 100644 --- a/spec/factories/runtime_function_definitions.rb +++ b/spec/factories/runtime_function_definitions.rb @@ -5,7 +5,7 @@ factory :runtime_function_definition do runtime_name { generate(:runtime_function_definition_name) } - return_type factory: :data_type + return_type { nil } runtime end end diff --git a/spec/factories/runtime_parameter_definitions.rb b/spec/factories/runtime_parameter_definitions.rb index 3db68c0e..e571ecf4 100644 --- a/spec/factories/runtime_parameter_definitions.rb +++ b/spec/factories/runtime_parameter_definitions.rb @@ -5,7 +5,7 @@ factory :runtime_parameter_definition do runtime_function_definition - data_type + data_type { nil } runtime_name { generate(:runtime_parameter_definition_name) } end end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb new file mode 100644 index 00000000..e27ff00e --- /dev/null +++ b/spec/models/data_type_identifier_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +# spec/models/data_type_identifier_spec.rb +require 'rails_helper' + +RSpec.describe DataTypeIdentifier do + describe 'associations' do + it { is_expected.to belong_to(:data_type).optional } + it { is_expected.to belong_to(:generic_type).optional } + it { is_expected.to have_many(:generic_types) } + it { is_expected.to have_many(:generic_mappers) } + end + + describe 'validations' do + it 'is valid with exactly one of generic_key, data_type_id, or generic_type_id' do + expect(build(:data_type_identifier, generic_key: 'key')).to be_valid + expect(build(:data_type_identifier, data_type: create(:data_type))).to be_valid + expect(build(:data_type_identifier, + generic_type: create(:generic_type, + data_type_identifier: create(:data_type_identifier, + generic_key: 'x')))).to be_valid + end + + it 'is invalid when none of generic_key, data_type_id, or generic_type_id are set' do + dti = build(:data_type_identifier, generic_key: nil, data_type: nil, generic_type: nil) + expect(dti).not_to be_valid + expect(dti.errors[:base]) + .to include('Exactly one of generic_key, data_type_id, or generic_type_id must be present') + end + + it 'is invalid when more than one of generic_key, data_type_id, or generic_type_id are set' do + dti = build(:data_type_identifier, generic_key: 'key', data_type: create(:data_type)) + expect(dti).not_to be_valid + expect(dti.errors[:base]) + .to include('Exactly one of generic_key, data_type_id, or generic_type_id must be present') + end + end +end diff --git a/spec/models/function_definition_spec.rb b/spec/models/function_definition_spec.rb index d5a09e0a..fafdd6eb 100644 --- a/spec/models/function_definition_spec.rb +++ b/spec/models/function_definition_spec.rb @@ -7,7 +7,7 @@ describe 'associations' do it { is_expected.to belong_to(:runtime_function_definition) } - it { is_expected.to belong_to(:return_type).class_name('DataType').optional } + it { is_expected.to belong_to(:return_type).class_name('DataTypeIdentifier').optional } it { is_expected.to have_many(:names).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:descriptions).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:documentations).class_name('Translation').inverse_of(:owner) } diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb new file mode 100644 index 00000000..f22a01fa --- /dev/null +++ b/spec/models/function_generic_mapper_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe FunctionGenericMapper do + describe 'associations' do + it { is_expected.to belong_to(:data_type_identifier).optional } + + it { + is_expected.to belong_to(:runtime_function_definition).class_name('RuntimeFunctionDefinition') + .optional.inverse_of(:generic_mappers) + } + end + + describe 'validations' do + it 'is valid with target and one of generic_key or data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'x') + expect(build(:function_generic_mapper, target: 'do_something', generic_key: 'param')).to be_valid + expect(build(:function_generic_mapper, target: 'do_something', data_type_identifier: dti)).to be_valid + end + + it 'is invalid with both generic_key and data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'x') + mapper = build(:function_generic_mapper, target: 'x', generic_key: 'param', data_type_identifier: dti) + expect(mapper).not_to be_valid + expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid with neither generic_key nor data_type_identifier' do + mapper = build(:function_generic_mapper, target: 'x', generic_key: nil, data_type_identifier: nil) + expect(mapper).not_to be_valid + expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid without a target' do + mapper = build(:function_generic_mapper, target: nil, generic_key: 'something') + expect(mapper).not_to be_valid + expect(mapper.errors[:target]).to include("can't be blank") + end + end +end diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb new file mode 100644 index 00000000..419407c7 --- /dev/null +++ b/spec/models/generic_mapper_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +# spec/models/generic_mapper_spec.rb +require 'rails_helper' + +RSpec.describe GenericMapper do + describe 'associations' do + it { is_expected.to belong_to(:generic_type) } + it { is_expected.to belong_to(:data_type_identifier).optional } + end + + describe 'validations' do + it 'is valid with target and exactly one of generic_key or data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + + expect(build(:generic_mapper, target: 'target', generic_key: 'key1', generic_type: generic_type)).to be_valid + expect(build(:generic_mapper, target: 'target', data_type_identifier: dti, + generic_type: generic_type)).to be_valid + end + + it 'is invalid without a target' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: nil, generic_key: 'key1', generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:target]).to include("can't be blank") + end + + it 'is invalid when neither generic_key nor data_type_identifier is set' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, + generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid when both generic_key and data_type_identifier are set' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, + generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + end +end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb new file mode 100644 index 00000000..9a2aae5c --- /dev/null +++ b/spec/models/generic_type_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# spec/models/generic_type_spec.rb +require 'rails_helper' + +RSpec.describe GenericType do + describe 'associations' do + it { is_expected.to belong_to(:data_type_identifier) } + it { is_expected.to have_many(:generic_mappers) } + end + + describe 'validations' do + it 'is valid with a data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'key') + expect(build(:generic_type, data_type_identifier: dti)).to be_valid + end + + it 'is invalid without a data_type_identifier' do + expect(build(:generic_type, data_type_identifier: nil)).not_to be_valid + end + end +end diff --git a/spec/models/parameter_definition_spec.rb b/spec/models/parameter_definition_spec.rb index 07c883e6..812cf537 100644 --- a/spec/models/parameter_definition_spec.rb +++ b/spec/models/parameter_definition_spec.rb @@ -3,7 +3,13 @@ require 'rails_helper' RSpec.describe ParameterDefinition do - subject { create(:parameter_definition) } + subject do + create(:parameter_definition, + runtime_parameter_definition: create(:runtime_parameter_definition, data_type: data_type_identifier), + data_type: data_type_identifier) + end + + let(:data_type_identifier) { create(:data_type_identifier, generic_key: 'T') } describe 'associations' do it { is_expected.to belong_to(:runtime_parameter_definition) } diff --git a/spec/models/runtime_function_definition_error_type_spec.rb b/spec/models/runtime_function_definition_error_type_spec.rb index db400875..03f0016a 100644 --- a/spec/models/runtime_function_definition_error_type_spec.rb +++ b/spec/models/runtime_function_definition_error_type_spec.rb @@ -5,6 +5,6 @@ RSpec.describe RuntimeFunctionDefinitionErrorType do describe 'associations' do it { is_expected.to belong_to(:runtime_function_definition) } - it { is_expected.to belong_to(:data_type) } + it { is_expected.to belong_to(:data_type).class_name('DataType') } end end diff --git a/spec/models/runtime_function_definition_spec.rb b/spec/models/runtime_function_definition_spec.rb index dc56ceb9..67b8b0b0 100644 --- a/spec/models/runtime_function_definition_spec.rb +++ b/spec/models/runtime_function_definition_spec.rb @@ -22,6 +22,8 @@ .inverse_of(:runtime_function_definition) end + it { is_expected.to have_many(:generic_mappers).inverse_of(:runtime_function_definition) } + it { is_expected.to have_many(:names).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:descriptions).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:documentations).class_name('Translation').inverse_of(:owner) } diff --git a/spec/models/runtime_parameter_definition_spec.rb b/spec/models/runtime_parameter_definition_spec.rb index 60b44112..f882c4b2 100644 --- a/spec/models/runtime_parameter_definition_spec.rb +++ b/spec/models/runtime_parameter_definition_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe RuntimeParameterDefinition do - subject { create(:runtime_parameter_definition) } + subject { create(:runtime_parameter_definition, data_type: create(:data_type_identifier, generic_key: 'T')) } describe 'validations' do it { is_expected.to validate_presence_of(:runtime_name) } @@ -17,7 +17,7 @@ describe 'associations' do it { is_expected.to belong_to(:runtime_function_definition) } - it { is_expected.to belong_to(:data_type) } + it { is_expected.to belong_to(:data_type).class_name('DataTypeIdentifier') } it { is_expected.to have_many(:parameter_definitions).inverse_of(:runtime_parameter_definition) } it { is_expected.to have_many(:names).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:descriptions).class_name('Translation').inverse_of(:owner) } diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 7af390f2..2e70e488 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -10,8 +10,8 @@ describe 'Update' do context 'when create' do let(:runtime) { create(:runtime) } - let(:parameter_type) { create(:data_type, runtime: runtime) } - let(:return_type) { create(:data_type, runtime: runtime) } + let(:parameter_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } + let(:return_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } let(:error_type) { create(:data_type, runtime: runtime) } let(:runtime_functions) do @@ -30,11 +30,15 @@ deprecation_message: [ { code: 'de_DE', content: 'Eine Deprecationsmeldung' } ], - return_type_identifier: return_type.identifier, + return_type_identifier: { + data_type_identifier: return_type.data_type.identifier, + }, error_type_identifiers: [error_type.identifier], runtime_parameter_definitions: [ { - data_type_identifier: parameter_type.identifier, + data_type_identifier: { + data_type_identifier: parameter_type.data_type.identifier, + }, runtime_name: 'runtime_parameter_definition_id', default_value: Tucana::Shared::Value.from_ruby({ 'key' => 'value' }), name: [ @@ -61,14 +65,14 @@ function = RuntimeFunctionDefinition.last expect(function.runtime_name).to eq('runtime_function_id') - expect(function.return_type.identifier).to eq(return_type.identifier) + expect(function.return_type.data_type.identifier).to eq(return_type.data_type.identifier) expect(function.names.first.content).to eq('Eine Funktion') expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation') expect(function.deprecation_messages.first.content).to eq('Eine Deprecationsmeldung') expect(function.error_types.first.data_type.identifier).to eq(error_type.identifier) parameter = function.parameters.first - expect(parameter.data_type.identifier).to eq(parameter_type.identifier) + expect(parameter.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter.runtime_name).to eq('runtime_parameter_definition_id') expect(parameter.names.first.content).to eq('Ein Parameter') expect(parameter.descriptions.first.content).to eq('Eine Parameterbeschreibung') @@ -79,9 +83,9 @@ expect(function_definition.names.first.content).to eq('Eine Funktion') expect(function_definition.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function_definition.documentations.first.content).to eq('Eine Funktionsdokumentation') - expect(function_definition.return_type.identifier).to eq(return_type.identifier) + expect(function_definition.return_type.data_type.identifier).to eq(return_type.data_type.identifier) parameter_definition = ParameterDefinition.first - expect(parameter_definition.data_type.identifier).to eq(parameter_type.identifier) + expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter_definition.names.first.content).to eq('Ein Parameter') expect(parameter_definition.descriptions.first.content).to eq('Eine Parameterbeschreibung') expect(parameter_definition.documentations.first.content).to eq('Eine Parameterdokumentation') @@ -91,7 +95,7 @@ context 'when update' do let(:runtime) { create(:runtime) } - let(:data_type) { create(:data_type, runtime: runtime) } + let(:data_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } let(:existing_runtime_function_definition) do create(:runtime_function_definition, @@ -109,7 +113,9 @@ ], runtime_parameter_definitions: [ { - data_type_identifier: data_type.identifier, + data_type_identifier: { + data_type_identifier: data_type.data_type.identifier, + }, runtime_name: 'runtime_parameter_definition_id', name: [ { code: 'de_DE', content: 'Ein Parameter' } @@ -133,7 +139,7 @@ expect(function.runtime_name).to eq('runtime_function_id') expect(function.names.first.content).to eq('Eine Funktion') parameter = function.parameters.first - expect(parameter.data_type.identifier).to eq(data_type.identifier) + expect(parameter.data_type.data_type.identifier).to eq(data_type.data_type.identifier) expect(parameter.runtime_name).to eq('runtime_parameter_definition_id') expect(parameter.names.first.content).to eq('Ein Parameter') @@ -151,7 +157,8 @@ end let!(:existing_runtime_parameter_definition) do - create(:runtime_parameter_definition, runtime_function_definition: existing_runtime_function_definition) + create(:runtime_parameter_definition, data_type: create(:data_type_identifier, data_type: create(:data_type)), + runtime_function_definition: existing_runtime_function_definition) end let(:message) do From cdf6cd58e71852f76fc0e8c4df762d795f61e273 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 13:37:18 +0200 Subject: [PATCH 02/54] Adjust models and tests --- Gemfile | 2 +- Gemfile.lock | 4 +- app/models/data_type_identifier.rb | 3 +- app/models/function_generic_mapper.rb | 4 +- app/models/generic_mapper.rb | 8 +- app/models/generic_type.rb | 1 + app/models/runtime.rb | 3 + app/models/runtime_parameter_definition.rb | 1 + .../update_service.rb | 88 ++++++++++++++++--- .../20250525192143_implement_generics.rb | 22 +++-- db/structure.sql | 64 ++++++-------- spec/factories/data_type_identifiers.rb | 1 + spec/factories/function_generic_mappers.rb | 2 +- spec/factories/generic_mappers.rb | 1 + spec/factories/generic_types.rb | 1 + spec/models/data_type_identifier_spec.rb | 1 + spec/models/function_generic_mapper_spec.rb | 1 + spec/models/generic_mapper_spec.rb | 7 +- spec/models/generic_type_spec.rb | 1 + .../runtime_parameter_definition_spec.rb | 2 + spec/models/runtime_spec.rb | 3 + .../sagittarius/data_type_service_spec.rb | 3 + ...untime_function_definition_service_spec.rb | 56 ++++++++++-- 23 files changed, 205 insertions(+), 74 deletions(-) diff --git a/Gemfile b/Gemfile index 5ceadfd1..fa653e3a 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.26' +gem 'tucana', '0.0.27' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 5dec9ce4..729121d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -356,7 +356,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.26) + tucana (0.0.27) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -409,7 +409,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.26) + tucana (= 0.0.27) tzinfo-data RUBY VERSION diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 657ab83f..8b28aaad 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -3,6 +3,7 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier + belongs_to :runtime, inverse_of: :data_type_identifiers has_many :generic_types, inverse_of: :data_type_identifier has_many :generic_mappers, inverse_of: :data_type_identifier @@ -13,7 +14,7 @@ class DataTypeIdentifier < ApplicationRecord private def exactly_one_of_generic_key_data_type_id_generic_type_id - values = [generic_key.present?, data_type_id.present?, generic_type_id.present?] + values = [generic_key.present?, data_type.present?, generic_type.present?] return if values.count(true) == 1 errors.add(:base, 'Exactly one of generic_key, data_type_id, or generic_type_id must be present') diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 32489de2..0612a21a 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -4,6 +4,8 @@ class FunctionGenericMapper < ApplicationRecord belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers + belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, + inverse_of: :function_generic_mappers validates :target, presence: true validate :exactly_one_of_generic_key_or_data_type_identifier_id @@ -11,7 +13,7 @@ class FunctionGenericMapper < ApplicationRecord private def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier_id.present?] + values = [generic_key.present?, data_type_identifier.present?] return if values.count(true) == 1 errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb index d2ed8fd8..117b44dc 100644 --- a/app/models/generic_mapper.rb +++ b/app/models/generic_mapper.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class GenericMapper < ApplicationRecord - belongs_to :generic_type, inverse_of: :generic_mappers + belongs_to :generic_type, inverse_of: :generic_mappers, optional: true belongs_to :data_type_identifier, optional: true, inverse_of: :generic_mappers + belongs_to :runtime, inverse_of: :generic_mappers + belongs_to :runtime_parameter_definition, optional: true, inverse_of: :generic_mappers validates :target, presence: true validate :exactly_one_of_generic_key_or_data_type_identifier_id, :generic_key_changed? @@ -11,9 +13,9 @@ class GenericMapper < ApplicationRecord private def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier_id.present?] + values = [generic_key.present?, data_type_identifier.present?] return if values.count(true) == 1 - errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') + errors.add(:base, 'Exactly one of generic_key or data_type_identifier must be present') end end diff --git a/app/models/generic_type.rb b/app/models/generic_type.rb index c8c1aa1d..bb7cba2f 100644 --- a/app/models/generic_type.rb +++ b/app/models/generic_type.rb @@ -2,6 +2,7 @@ class GenericType < ApplicationRecord belongs_to :data_type_identifier, inverse_of: :generic_type + belongs_to :runtime, class_name: 'Runtime', inverse_of: :generic_types has_many :generic_mappers, inverse_of: :generic_type end diff --git a/app/models/runtime.rb b/app/models/runtime.rb index a959b34b..13df93e1 100644 --- a/app/models/runtime.rb +++ b/app/models/runtime.rb @@ -13,6 +13,9 @@ class Runtime < ApplicationRecord has_many :projects, class_name: 'NamespaceProject', through: :project_assignments, inverse_of: :runtimes has_many :data_types, inverse_of: :runtime + has_many :data_type_identifiers, inverse_of: :runtime + has_many :generic_types, inverse_of: :runtime + has_many :generic_mappers, inverse_of: :runtime has_many :flow_types, inverse_of: :runtime diff --git a/app/models/runtime_parameter_definition.rb b/app/models/runtime_parameter_definition.rb index ad47dbb7..15d5c076 100644 --- a/app/models/runtime_parameter_definition.rb +++ b/app/models/runtime_parameter_definition.rb @@ -9,6 +9,7 @@ class RuntimeParameterDefinition < ApplicationRecord has_many :documentations, -> { by_purpose(:documentation) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :parameter_definitions, inverse_of: :runtime_parameter_definition + has_many :function_generic_mappers, class_name: 'FunctionGenericMapper', inverse_of: :runtime_parameter_definition validates :runtime_name, length: { minimum: 3, maximum: 50 }, presence: true, uniqueness: { case_sensitive: false, scope: :runtime_function_definition_id } diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 89603888..e61b1c88 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -51,6 +51,7 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.deprecation_messages) db_object.error_types = update_error_types(runtime_function_definition.error_type_identifiers, db_object, t) + db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object) if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -68,31 +69,92 @@ def update_runtime_function_definition(runtime_function_definition, t) end # These mappers can be either generic mappers or generic function mappers. - def find_data_type_identifier(identifier, _generic_mappers, t) - if identifier.data_type_identifier.present? - data_type_identifier = DataTypeIdentifier.find_by(data_type: find_data_type(identifier.data_type_identifier, - t)) + def update_mappers(generic_mappers, runtime_function_definition = nil) + generic_mappers.to_a.map do |generic_mapper| + if generic_mapper.is_a? Tucana::Shared::GenericMapper + mapper = GenericMapper.create_or_find_by(runtime: current_runtime, + target: generic_mapper.target, + generic_key: generic_mapper.generic_key, + data_type_identifier: + (generic_mapper.generic_key.nil? ? data_type_identifier : nil)) - if data_type_identifier.nil? + end + if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper + mapper = FunctionGenericMapper.create_or_find_by( + runtime_id: current_runtime.id, + runtime_function_definition: runtime_function_definition, + data_type_identifier: (generic_mapper.generic_key.nil? ? data_type_identifier : nil), + target: generic_mapper.target, + generic_key: generic_mapper.generic_key, + parameter_id: generic_mapper.parameter_id + ) + end + + if mapper.nil? || !mapper.save t.rollback_and_return! ServiceResponse.error( - message: "Could not find datatype identifier with identifier #{identifier}", - payload: :no_datatype_identifier_for_identifier + message: "Could not find or create generic mapper (#{generic_mapper})", + payload: :error_creating_generic_mapper ) end + mapper + end + end - return data_type_identifier + def find_data_type_identifier(identifier, generic_mappers, t) + if identifier.data_type_identifier.present? + return create_data_type_identifier(t, data_type_id: find_data_type(identifier.data_type_identifier, t).id) end + if identifier.generic_type.present? - return find_data_type_identifier(identifier.generic_type.identifier, identifier.generic_type.generic_mappers, - t) - end - if identifier.generic_key.present? - return DataTypeIdentifier.find_or_create_by(runtime: current_runtime, generic_key: identifier.generic_key) + arr = generic_mappers.to_a + identifier.generic_type.generic_mappers.each do |generic_mapper| + arr << generic_mapper + end + data_type_identifier = find_data_type_identifier(identifier.generic_type.data_type_identifier, arr, t) + + generic_type = GenericType.find_by( + runtime_id: current_runtime.id, + data_type_identifier_id: data_type_identifier.id + ) + if generic_type.nil? + generic_type = GenericType.create( + runtime_id: current_runtime.id, + data_type_identifier_id: data_type_identifier.id + ) + end + + if generic_type.nil? + t.rollback_and_return! ServiceResponse.error( + message: "Could not find generic type with identifier #{identifier.generic_type.data_type_identifier}", + payload: :no_generic_type_for_identifier + ) + end + + generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers)) + + return create_data_type_identifier(t, generic_type_id: generic_type.id) end + return create_data_type_identifier(t, generic_key: identifier.generic_key) if identifier.generic_key.present? raise ArgumentError, "Invalid identifier: #{identifier.inspect}" end + def create_data_type_identifier(t, **kwargs) + data_type_identifier = DataTypeIdentifier.find_by(runtime_id: current_runtime.id, **kwargs) + if data_type_identifier.nil? + data_type_identifier = DataTypeIdentifier.create_or_find_by(runtime_id: current_runtime.id, **kwargs) + end + + if data_type_identifier.nil? + t.rollback_and_return! ServiceResponse.error( + message: "Could not find datatype identifier with #{kwargs}", + payload: :no_datatype_identifier_for_generic_key + ) + end + + data_type_identifier + end + def find_data_type(identifier, t) data_type = DataType.find_by(runtime: current_runtime, identifier: identifier) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 416af4a0..4151d076 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -11,6 +11,8 @@ def change # One of them needs to be set t.text :generic_key, null: true t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -18,6 +20,8 @@ def change create_table :generic_types do |t| t.references :data_type_identifier, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -32,7 +36,9 @@ def change t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', name: check_constraint_name(:generic_mappers, :source, :one_of) - t.references :generic_type, null: false, foreign_key: { to_table: :generic_types, on_delete: :cascade } + t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -48,15 +54,21 @@ def change foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } t.text :generic_key, null: true + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.text :target, null: false t.text :parameter_id, null: true - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.references :runtime_parameter_definition, null: true, + foreign_key: { to_table: :runtime_parameter_definitions, + on_delete: :cascade } t.references :runtime_function_definition, null: true, foreign_key: { to_table: :runtime_function_definitions, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -75,10 +87,6 @@ def change add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - # remove_column :runtime_function_definition_error_types, :data_type_id - # add_reference :runtime_function_definition_error_types, :data_type, - # foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: false - remove_column :function_definitions, :return_type_id add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true diff --git a/db/structure.sql b/db/structure.sql index 9d1cc7b6..88922ba7 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -125,6 +125,7 @@ CREATE TABLE data_type_identifiers ( id bigint NOT NULL, generic_key text, data_type_id bigint, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, generic_type_id bigint, @@ -244,7 +245,9 @@ CREATE TABLE function_generic_mappers ( generic_key text, target text NOT NULL, parameter_id text, + runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) @@ -264,7 +267,8 @@ CREATE TABLE generic_mappers ( target text NOT NULL, generic_key text, data_type_identifier_id bigint, - generic_type_id bigint NOT NULL, + generic_type_id bigint, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) @@ -282,6 +286,7 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, data_type_identifier_id bigint NOT NULL, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); @@ -423,23 +428,6 @@ CREATE SEQUENCE namespace_members_id_seq ALTER SEQUENCE namespace_members_id_seq OWNED BY namespace_members.id; -CREATE TABLE namespace_project_runtime_assignments ( - id bigint NOT NULL, - runtime_id bigint NOT NULL, - namespace_project_id bigint NOT NULL, - created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL -); - -CREATE SEQUENCE namespace_project_runtime_assignments_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -ALTER SEQUENCE namespace_project_runtime_assignments_id_seq OWNED BY namespace_project_runtime_assignments.id; - CREATE TABLE namespace_projects ( id bigint NOT NULL, name text NOT NULL, @@ -447,7 +435,6 @@ CREATE TABLE namespace_projects ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, namespace_id bigint NOT NULL, - primary_runtime_id bigint, CONSTRAINT check_09e881e641 CHECK ((char_length(name) <= 50)), CONSTRAINT check_a77bf7c685 CHECK ((char_length(description) <= 500)) ); @@ -767,8 +754,6 @@ ALTER TABLE ONLY namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('nam ALTER TABLE ONLY namespace_members ALTER COLUMN id SET DEFAULT nextval('namespace_members_id_seq'::regclass); -ALTER TABLE ONLY namespace_project_runtime_assignments ALTER COLUMN id SET DEFAULT nextval('namespace_project_runtime_assignments_id_seq'::regclass); - ALTER TABLE ONLY namespace_projects ALTER COLUMN id SET DEFAULT nextval('namespace_projects_id_seq'::regclass); ALTER TABLE ONLY namespace_role_abilities ALTER COLUMN id SET DEFAULT nextval('namespace_role_abilities_id_seq'::regclass); @@ -871,9 +856,6 @@ ALTER TABLE ONLY namespace_member_roles ALTER TABLE ONLY namespace_members ADD CONSTRAINT namespace_members_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_project_runtime_assignments - ADD CONSTRAINT namespace_project_runtime_assignments_pkey PRIMARY KEY (id); - ALTER TABLE ONLY namespace_projects ADD CONSTRAINT namespace_projects_pkey PRIMARY KEY (id); @@ -932,10 +914,10 @@ CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON function_generi CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); -CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); - CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON runtime_function_definitions USING btree (runtime_id, runtime_name); +CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON function_generic_mappers USING btree (runtime_parameter_definition_id); + CREATE INDEX index_active_storage_attachments_on_blob_id ON active_storage_attachments USING btree (blob_id); CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON active_storage_attachments USING btree (record_type, record_id, name, blob_id); @@ -954,6 +936,8 @@ CREATE INDEX index_data_type_identifiers_on_data_type_id ON data_type_identifier CREATE INDEX index_data_type_identifiers_on_generic_type_id ON data_type_identifiers USING btree (generic_type_id); +CREATE INDEX index_data_type_identifiers_on_runtime_id ON data_type_identifiers USING btree (runtime_id); + CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id); CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (parent_type_id); @@ -976,12 +960,18 @@ CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON fun CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); +CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); + CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); +CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); + CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); +CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); + CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON good_job_executions USING btree (active_job_id, created_at); CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON good_job_executions USING btree (process_id, created_at); @@ -1030,8 +1020,6 @@ CREATE INDEX index_namespace_members_on_user_id ON namespace_members USING btree CREATE INDEX index_namespace_projects_on_namespace_id ON namespace_projects USING btree (namespace_id); -CREATE INDEX index_namespace_projects_on_primary_runtime_id ON namespace_projects USING btree (primary_runtime_id); - CREATE INDEX index_namespace_role_project_assignments_on_project_id ON namespace_role_project_assignments USING btree (project_id); CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON namespace_roles USING btree (namespace_id, lower(name)); @@ -1085,9 +1073,15 @@ ALTER TABLE ONLY data_types ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY generic_types + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; + ALTER TABLE ONLY generic_types ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; @@ -1109,6 +1103,9 @@ ALTER TABLE ONLY data_type_identifiers ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1151,8 +1148,8 @@ ALTER TABLE ONLY runtime_function_definitions ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY namespace_projects - ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); @@ -1172,14 +1169,11 @@ ALTER TABLE ONLY flow_type_settings ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY namespace_project_runtime_assignments - ADD CONSTRAINT fk_rails_c019e5b233 FOREIGN KEY (namespace_project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; - ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); -ALTER TABLE ONLY namespace_project_runtime_assignments - ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY generic_mappers + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; diff --git a/spec/factories/data_type_identifiers.rb b/spec/factories/data_type_identifiers.rb index 7ef0303c..f3103216 100644 --- a/spec/factories/data_type_identifiers.rb +++ b/spec/factories/data_type_identifiers.rb @@ -5,5 +5,6 @@ generic_key { nil } data_type { nil } generic_type { nil } + runtime end end diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb index e5579f87..96e28ab6 100644 --- a/spec/factories/function_generic_mappers.rb +++ b/spec/factories/function_generic_mappers.rb @@ -3,7 +3,7 @@ FactoryBot.define do factory :function_generic_mapper do target { nil } - parameter_id { nil } + runtime_parameter_definition { nil } generic_key { nil } data_type_identifier { nil } end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index b601b3c5..33a5cd58 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :generic_mapper do + runtime target { nil } generic_key { nil } data_type_identifier { nil } diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index f26bc778..a4eef104 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :generic_type do + runtime generic_mappers { [] } data_type_identifier { nil } end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index e27ff00e..11d422d7 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -7,6 +7,7 @@ describe 'associations' do it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } + it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_types) } it { is_expected.to have_many(:generic_mappers) } end diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index f22a01fa..c83b8546 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -5,6 +5,7 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do it { is_expected.to belong_to(:data_type_identifier).optional } + it { is_expected.to belong_to(:runtime_parameter_definition).optional } it { is_expected.to belong_to(:runtime_function_definition).class_name('RuntimeFunctionDefinition') diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index 419407c7..bdc7873f 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -5,7 +5,8 @@ RSpec.describe GenericMapper do describe 'associations' do - it { is_expected.to belong_to(:generic_type) } + it { is_expected.to belong_to(:generic_type).optional } + it { is_expected.to belong_to(:runtime) } it { is_expected.to belong_to(:data_type_identifier).optional } end @@ -33,7 +34,7 @@ gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, generic_type: generic_type) expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') end it 'is invalid when both generic_key and data_type_identifier are set' do @@ -42,7 +43,7 @@ gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, generic_type: generic_type) expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') end end end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index 9a2aae5c..b97b9ca7 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -6,6 +6,7 @@ RSpec.describe GenericType do describe 'associations' do it { is_expected.to belong_to(:data_type_identifier) } + it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_mappers) } end diff --git a/spec/models/runtime_parameter_definition_spec.rb b/spec/models/runtime_parameter_definition_spec.rb index f882c4b2..1b71cf02 100644 --- a/spec/models/runtime_parameter_definition_spec.rb +++ b/spec/models/runtime_parameter_definition_spec.rb @@ -8,6 +8,8 @@ describe 'validations' do it { is_expected.to validate_presence_of(:runtime_name) } + it { is_expected.to have_many(:function_generic_mappers) } + it { is_expected.to validate_uniqueness_of(:runtime_name).case_insensitive.scoped_to(:runtime_function_definition_id) } diff --git a/spec/models/runtime_spec.rb b/spec/models/runtime_spec.rb index bfdfd83a..d2fd63cb 100644 --- a/spec/models/runtime_spec.rb +++ b/spec/models/runtime_spec.rb @@ -8,6 +8,9 @@ describe 'associations' do it { is_expected.to belong_to(:namespace).optional } it { is_expected.to have_many(:data_types).inverse_of(:runtime) } + it { is_expected.to have_many(:data_type_identifiers).inverse_of(:runtime) } + it { is_expected.to have_many(:generic_types).inverse_of(:runtime) } + it { is_expected.to have_many(:generic_mappers).inverse_of(:runtime) } it { is_expected.to have_many(:flow_types).inverse_of(:runtime) } end diff --git a/spec/requests/grpc/sagittarius/data_type_service_spec.rb b/spec/requests/grpc/sagittarius/data_type_service_spec.rb index c6cbba44..c79812e9 100644 --- a/spec/requests/grpc/sagittarius/data_type_service_spec.rb +++ b/spec/requests/grpc/sagittarius/data_type_service_spec.rb @@ -58,6 +58,7 @@ rules: [ Tucana::Shared::DataTypeRule.create(:number_range, { from: 9 }) ], + generic_keys: ['T'], }, { variant: :PRIMITIVE, @@ -80,6 +81,8 @@ expect(positive_number).to be_present expect(small_positive_number).to be_present + expect(positive_number.generic_keys).to be_empty + expect(small_positive_number.generic_keys).to eq(['T']) expect(small_positive_number.parent_type).to eq(positive_number) end diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 2e70e488..5473a97a 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -10,8 +10,20 @@ describe 'Update' do context 'when create' do let(:runtime) { create(:runtime) } - let(:parameter_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } - let(:return_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } + let!(:parameter_type) do + create(:data_type_identifier, runtime: runtime, data_type: create(:data_type, runtime: runtime)) + end + + let!(:generic_type) do + create(:generic_type, + runtime: runtime, + data_type_identifier: + create(:data_type_identifier, + runtime: runtime, + data_type: create(:data_type, + runtime: runtime).reload).reload).reload + end + let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload } let(:error_type) { create(:data_type, runtime: runtime) } let(:runtime_functions) do @@ -31,8 +43,21 @@ { code: 'de_DE', content: 'Eine Deprecationsmeldung' } ], return_type_identifier: { - data_type_identifier: return_type.data_type.identifier, + generic_type: { + data_type_identifier: { # Without reloads it just fails + data_type_identifier: return_type.reload.generic_type + .reload.data_type_identifier.reload.data_type.reload.identifier, + }, + generic_mappers: [{ generic_key: 'T', target: 'V' }], + }, }, + generic_mappers: [ + { + generic_key: 'X', + target: 'Y', + parameter_id: 'some_id', + } + ], error_type_identifiers: [error_type.identifier], runtime_parameter_definitions: [ { @@ -63,9 +88,16 @@ it 'creates a correct functions' do expect(stub.update(message, authorization(runtime)).success).to be(true) + expect(GenericMapper.count).to eq(1) + expect(GenericMapper.last.generic_key).to eq('T') + expect(GenericMapper.last.target).to eq('V') + + expect(GenericType.count).to eq(1) + function = RuntimeFunctionDefinition.last expect(function.runtime_name).to eq('runtime_function_id') - expect(function.return_type.data_type.identifier).to eq(return_type.data_type.identifier) + expect(function.return_type.generic_type.reload.data_type_identifier.data_type.identifier) + .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) expect(function.names.first.content).to eq('Eine Funktion') expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation') @@ -83,19 +115,27 @@ expect(function_definition.names.first.content).to eq('Eine Funktion') expect(function_definition.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function_definition.documentations.first.content).to eq('Eine Funktionsdokumentation') - expect(function_definition.return_type.data_type.identifier).to eq(return_type.data_type.identifier) + expect(function_definition.return_type.generic_type.reload.data_type_identifier.data_type.identifier) + .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) parameter_definition = ParameterDefinition.first expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter_definition.names.first.content).to eq('Ein Parameter') expect(parameter_definition.descriptions.first.content).to eq('Eine Parameterbeschreibung') expect(parameter_definition.documentations.first.content).to eq('Eine Parameterdokumentation') expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) + + expect(FunctionGenericMapper.count).to eq(1) + expect(FunctionGenericMapper.last.generic_key).to eq('X') + expect(FunctionGenericMapper.last.target).to eq('Y') + expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end end context 'when update' do let(:runtime) { create(:runtime) } - let(:data_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } + let(:data_type) do + create(:data_type_identifier, runtime: runtime, data_type: create(:data_type, runtime: runtime)) + end let(:existing_runtime_function_definition) do create(:runtime_function_definition, @@ -157,7 +197,9 @@ end let!(:existing_runtime_parameter_definition) do - create(:runtime_parameter_definition, data_type: create(:data_type_identifier, data_type: create(:data_type)), + create(:runtime_parameter_definition, data_type: create(:data_type_identifier, + runtime: runtime, + data_type: create(:data_type, runtime: runtime)), runtime_function_definition: existing_runtime_function_definition) end From 34b580b1594cb269579adc38dcd1f7d9111287f2 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 19:47:38 +0200 Subject: [PATCH 03/54] Add Rails helper requirement to ping service spec --- spec/requests/grpc/internal/ping_service_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/requests/grpc/internal/ping_service_spec.rb b/spec/requests/grpc/internal/ping_service_spec.rb index 2dc5f522..989951e8 100644 --- a/spec/requests/grpc/internal/ping_service_spec.rb +++ b/spec/requests/grpc/internal/ping_service_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'rails_helper' + RSpec.describe 'sagittarius.PingService', :need_grpc_server do include GrpcHelpers From ed6786f51cbe1b7fc4bc46ca09e1be2fb384630c Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 20:00:22 +0200 Subject: [PATCH 04/54] Refactor foreign key constraints in generics implementation --- .../20250525192143_implement_generics.rb | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 4151d076..9271d6a4 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -8,20 +8,20 @@ def change add_column :data_types, :generic_keys, 'text[]', null: false, default: [] create_table :data_type_identifiers do |t| - # One of them needs to be set + # One of them needs to be set will be enforced later t.text :generic_key, null: true t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end create_table :generic_types do |t| t.references :data_type_identifier, null: false, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } + + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end @@ -31,14 +31,14 @@ def change # One of them needs to be set t.text :generic_key, null: true t.references :data_type_identifier, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', name: check_constraint_name(:generic_mappers, :source, :one_of) - t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :cascade } + t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :restrict } # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end @@ -51,7 +51,7 @@ def change create_table :function_generic_mappers do |t| t.references :data_type_identifier, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } t.text :generic_key, null: true t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', @@ -62,13 +62,13 @@ def change t.references :runtime_parameter_definition, null: true, foreign_key: { to_table: :runtime_parameter_definitions, - on_delete: :cascade } + on_delete: :restrict } t.references :runtime_function_definition, null: true, foreign_key: { to_table: :runtime_function_definitions, - on_delete: :cascade } + on_delete: :restrict } # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end From d5f457d7a05a62a0090bc3a48517897cbfa5feb1 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 20:19:13 +0200 Subject: [PATCH 05/54] Recompile structure.sql --- db/structure.sql | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index 88922ba7..700d13ea 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1074,19 +1074,19 @@ ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -1104,7 +1104,7 @@ ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1149,13 +1149,13 @@ ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY user_sessions ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -1173,7 +1173,7 @@ ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1182,7 +1182,7 @@ ALTER TABLE ONLY namespace_projects ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1191,7 +1191,7 @@ ALTER TABLE ONLY runtimes ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY audit_events ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; From 2e8cc1157c71f12528379bd1184ba868d8b8ee26 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Tue, 27 May 2025 18:22:19 +0200 Subject: [PATCH 06/54] Make migration reversible --- db/migrate/20250525192143_implement_generics.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 9271d6a4..d6656f11 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -73,21 +73,21 @@ def change t.timestamps_with_timezone end - remove_column :runtime_function_definitions, :return_type_id + remove_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] - remove_column :runtime_parameter_definitions, :data_type_id + remove_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_column :parameter_definitions, :data_type_id + remove_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_column :function_definitions, :return_type_id + remove_reference :function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true end From 51591c4aedc61eb74d53b71195b9bf118818d47d Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Tue, 27 May 2025 21:42:20 +0200 Subject: [PATCH 07/54] Fix rubocop vulnerabilities --- db/migrate/20250525192143_implement_generics.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index d6656f11..29d5b367 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -73,13 +73,15 @@ def change t.timestamps_with_timezone end - remove_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_reference :runtime_function_definitions, :return_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] - remove_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_reference :runtime_parameter_definitions, :data_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true From 770abe6bf8cd7af67878e06aeeb68001a97a19c4 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Tue, 27 May 2025 23:33:59 +0200 Subject: [PATCH 08/54] Refactor generic type and mapper associations (tucana 0.0.28) --- Gemfile | 2 +- Gemfile.lock | 4 +- app/grpc/concerns/grpc_stream_handler.rb | 4 +- app/models/data_type.rb | 5 ++- app/models/data_type_identifier.rb | 7 ++-- app/models/flow_type.rb | 1 + app/models/function_generic_mapper.rb | 12 +----- app/models/generic_mapper.rb | 11 +----- app/models/generic_type.rb | 4 +- .../update_service.rb | 22 +++++------ .../20250525192143_implement_generics.rb | 25 +++--------- db/structure.sql | 34 +++++++--------- spec/factories/function_generic_mappers.rb | 3 +- spec/factories/generic_mappers.rb | 3 +- spec/factories/generic_types.rb | 2 +- spec/models/data_type_identifier_spec.rb | 9 ++--- spec/models/function_generic_mapper_spec.rb | 29 +------------- spec/models/generic_mapper_spec.rb | 39 +------------------ spec/models/generic_type_spec.rb | 13 +------ ...untime_function_definition_service_spec.rb | 29 +++++--------- 20 files changed, 68 insertions(+), 190 deletions(-) diff --git a/Gemfile b/Gemfile index fa653e3a..713ce561 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.27' +gem 'tucana', '0.0.28' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 729121d8..c08fc171 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -356,7 +356,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.27) + tucana (0.0.28) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -409,7 +409,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.27) + tucana (= 0.0.28) tzinfo-data RUBY VERSION diff --git a/app/grpc/concerns/grpc_stream_handler.rb b/app/grpc/concerns/grpc_stream_handler.rb index 46af0b52..3f82334c 100644 --- a/app/grpc/concerns/grpc_stream_handler.rb +++ b/app/grpc/concerns/grpc_stream_handler.rb @@ -12,7 +12,7 @@ def grpc_stream(method) create_enumerator(self.class, method, current_runtime_id, call.instance_variable_get(:@wrapped)) end - define_method("send_#{method}") do |grpc_object, runtime_id| + define_singleton_method("send_#{method}") do |grpc_object, runtime_id| logger.info(message: 'Sending data', runtime_id: runtime_id, method: method) encoded_data = self.class.encoders[method].call(grpc_object) @@ -23,7 +23,7 @@ def grpc_stream(method) ActiveRecord::Base.connection.raw_connection .exec("NOTIFY grpc_streams, '#{self.class},#{method},#{runtime_id},#{encoded_data64}'") end - define_method("end_#{method}") do |runtime_id| + define_singleton_method("end_#{method}") do |runtime_id| ActiveRecord::Base.connection.raw_connection .exec("NOTIFY grpc_streams, '#{self.class},#{method},#{runtime_id},end'") end diff --git a/app/models/data_type.rb b/app/models/data_type.rb index e162af9f..8cc41553 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -7,8 +7,8 @@ class DataType < ApplicationRecord object: 3, datatype: 4, array: 5, - generic: 6, - function: 7, + error: 6, + node: 7, }.with_indifferent_access enum :variant, VARIANTS, prefix: :variant @@ -20,6 +20,7 @@ class DataType < ApplicationRecord has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :rules, class_name: 'DataTypeRule', inverse_of: :data_type has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :data_type + has_many :generic_types, class_name: 'GenericType', inverse_of: :data_type validates :variant, presence: true, inclusion: { diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 8b28aaad..bd76551a 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -2,12 +2,11 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers - belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier + belongs_to :generic_type, optional: true, inverse_of: :data_type_identifiers belongs_to :runtime, inverse_of: :data_type_identifiers - has_many :generic_types, inverse_of: :data_type_identifier - has_many :generic_mappers, inverse_of: :data_type_identifier - has_many :function_generic_mappers, class_name: 'GenericMapper', inverse_of: :data_type_identifier + has_many :generic_mappers, inverse_of: :source + has_many :function_generic_mappers, class_name: 'FunctionGenericMapper', inverse_of: :source validate :exactly_one_of_generic_key_data_type_id_generic_type_id diff --git a/app/models/flow_type.rb b/app/models/flow_type.rb index fc846f75..0654f541 100644 --- a/app/models/flow_type.rb +++ b/app/models/flow_type.rb @@ -13,4 +13,5 @@ class FlowType < ApplicationRecord has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner + has_many :documentations, -> { by_purpose(:documentation) }, class_name: 'Translation', as: :owner, inverse_of: :owner end diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 0612a21a..10d8b015 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -1,21 +1,11 @@ # frozen_string_literal: true class FunctionGenericMapper < ApplicationRecord - belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers + belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, inverse_of: :function_generic_mappers validates :target, presence: true - validate :exactly_one_of_generic_key_or_data_type_identifier_id - - private - - def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier.present?] - return if values.count(true) == 1 - - errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') - end end diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb index 117b44dc..a48c6a33 100644 --- a/app/models/generic_mapper.rb +++ b/app/models/generic_mapper.rb @@ -2,20 +2,11 @@ class GenericMapper < ApplicationRecord belongs_to :generic_type, inverse_of: :generic_mappers, optional: true - belongs_to :data_type_identifier, optional: true, inverse_of: :generic_mappers + belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :generic_mappers belongs_to :runtime, inverse_of: :generic_mappers belongs_to :runtime_parameter_definition, optional: true, inverse_of: :generic_mappers validates :target, presence: true - validate :exactly_one_of_generic_key_or_data_type_identifier_id, :generic_key_changed? - validate :exactly_one_of_generic_key_or_data_type_identifier_id, :data_type_identifier_changed? - private - def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier.present?] - return if values.count(true) == 1 - - errors.add(:base, 'Exactly one of generic_key or data_type_identifier must be present') - end end diff --git a/app/models/generic_type.rb b/app/models/generic_type.rb index bb7cba2f..2d879924 100644 --- a/app/models/generic_type.rb +++ b/app/models/generic_type.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class GenericType < ApplicationRecord - belongs_to :data_type_identifier, inverse_of: :generic_type + belongs_to :data_type, class_name: 'DataType', inverse_of: :generic_types belongs_to :runtime, class_name: 'Runtime', inverse_of: :generic_types has_many :generic_mappers, inverse_of: :generic_type + has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :generic_type + end diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index e61b1c88..537d28fd 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -51,7 +51,7 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.deprecation_messages) db_object.error_types = update_error_types(runtime_function_definition.error_type_identifiers, db_object, t) - db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object) + db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object, t) if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -69,23 +69,20 @@ def update_runtime_function_definition(runtime_function_definition, t) end # These mappers can be either generic mappers or generic function mappers. - def update_mappers(generic_mappers, runtime_function_definition = nil) + def update_mappers(generic_mappers, runtime_function_definition, t) generic_mappers.to_a.map do |generic_mapper| if generic_mapper.is_a? Tucana::Shared::GenericMapper mapper = GenericMapper.create_or_find_by(runtime: current_runtime, target: generic_mapper.target, - generic_key: generic_mapper.generic_key, - data_type_identifier: - (generic_mapper.generic_key.nil? ? data_type_identifier : nil)) - + source: find_data_type_identifier(generic_mapper.source, + generic_mappers, t)) end if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper mapper = FunctionGenericMapper.create_or_find_by( runtime_id: current_runtime.id, runtime_function_definition: runtime_function_definition, - data_type_identifier: (generic_mapper.generic_key.nil? ? data_type_identifier : nil), + source: find_data_type_identifier(generic_mapper.source, generic_mappers, t), target: generic_mapper.target, - generic_key: generic_mapper.generic_key, parameter_id: generic_mapper.parameter_id ) end @@ -110,16 +107,16 @@ def find_data_type_identifier(identifier, generic_mappers, t) identifier.generic_type.generic_mappers.each do |generic_mapper| arr << generic_mapper end - data_type_identifier = find_data_type_identifier(identifier.generic_type.data_type_identifier, arr, t) + data_type = find_data_type(identifier.generic_type.data_type_identifier, t) generic_type = GenericType.find_by( runtime_id: current_runtime.id, - data_type_identifier_id: data_type_identifier.id + data_type: data_type ) if generic_type.nil? generic_type = GenericType.create( runtime_id: current_runtime.id, - data_type_identifier_id: data_type_identifier.id + data_type: data_type ) end @@ -130,7 +127,8 @@ def find_data_type_identifier(identifier, generic_mappers, t) ) end - generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers)) + generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers, nil, + t)) return create_data_type_identifier(t, generic_type_id: generic_type.id) end diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 29d5b367..747303a3 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -18,27 +18,18 @@ def change end create_table :generic_types do |t| - t.references :data_type_identifier, null: false, - foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + t.references :data_type, null: false, foreign_key: { to_table: :data_types, on_delete: :cascade } t.timestamps_with_timezone end create_table :generic_mappers do |t| - t.text :target, null: false - # One of them needs to be set - t.text :generic_key, null: true - t.references :data_type_identifier, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } - - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:generic_mappers, :source, :one_of) + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + t.text :target, null: false + t.references :source, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :restrict } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end @@ -50,12 +41,8 @@ def change name: check_constraint_name(:data_type_identifiers, :type, :one_of) create_table :function_generic_mappers do |t| - t.references :data_type_identifier, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } - t.text :generic_key, null: true - - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.references :source, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } t.text :target, null: false t.text :parameter_id, null: true diff --git a/db/structure.sql b/db/structure.sql index 700d13ea..d249e41a 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -241,16 +241,14 @@ ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; CREATE TABLE function_generic_mappers ( id bigint NOT NULL, - data_type_identifier_id bigint, - generic_key text, + source_id bigint, target text NOT NULL, parameter_id text, runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) + updated_at timestamp with time zone NOT NULL ); CREATE SEQUENCE function_generic_mappers_id_seq @@ -264,14 +262,12 @@ ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers CREATE TABLE generic_mappers ( id bigint NOT NULL, + runtime_id bigint NOT NULL, target text NOT NULL, - generic_key text, - data_type_identifier_id bigint, + source_id bigint NOT NULL, generic_type_id bigint, - runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) + updated_at timestamp with time zone NOT NULL ); CREATE SEQUENCE generic_mappers_id_seq @@ -285,8 +281,8 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, - data_type_identifier_id bigint NOT NULL, runtime_id bigint NOT NULL, + data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); @@ -958,17 +954,17 @@ CREATE INDEX index_function_definitions_on_return_type_id ON function_definition CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); -CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); - CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); -CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); +CREATE INDEX index_function_generic_mappers_on_source_id ON function_generic_mappers USING btree (source_id); CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); -CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); +CREATE INDEX index_generic_mappers_on_source_id ON generic_mappers USING btree (source_id); + +CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); @@ -1083,10 +1079,10 @@ ALTER TABLE ONLY function_generic_mappers ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_2adace81b8 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -1166,6 +1162,9 @@ ALTER TABLE ONLY namespace_members ALTER TABLE ONLY flow_type_settings ADD CONSTRAINT fk_rails_a1471d011d FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_be1833ba72 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; @@ -1190,9 +1189,6 @@ ALTER TABLE ONLY runtime_parameter_definitions ALTER TABLE ONLY runtimes ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; - ALTER TABLE ONLY audit_events ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb index 96e28ab6..e448ce1d 100644 --- a/spec/factories/function_generic_mappers.rb +++ b/spec/factories/function_generic_mappers.rb @@ -4,7 +4,6 @@ factory :function_generic_mapper do target { nil } runtime_parameter_definition { nil } - generic_key { nil } - data_type_identifier { nil } + source { nil } end end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index 33a5cd58..36a7fdc9 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -4,7 +4,6 @@ factory :generic_mapper do runtime target { nil } - generic_key { nil } - data_type_identifier { nil } + source { nil } end end diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index a4eef104..a7601bec 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -4,6 +4,6 @@ factory :generic_type do runtime generic_mappers { [] } - data_type_identifier { nil } + data_type end end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index 11d422d7..a2270dcd 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -8,18 +8,17 @@ it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to have_many(:generic_types) } - it { is_expected.to have_many(:generic_mappers) } + it { is_expected.to have_many(:generic_mappers).inverse_of(:source) } + it { is_expected.to have_many(:function_generic_mappers).inverse_of(:source) } end describe 'validations' do it 'is valid with exactly one of generic_key, data_type_id, or generic_type_id' do expect(build(:data_type_identifier, generic_key: 'key')).to be_valid expect(build(:data_type_identifier, data_type: create(:data_type))).to be_valid + generic_type = create(:generic_type, data_type: create(:data_type)) expect(build(:data_type_identifier, - generic_type: create(:generic_type, - data_type_identifier: create(:data_type_identifier, - generic_key: 'x')))).to be_valid + generic_type: generic_type)).to be_valid end it 'is invalid when none of generic_key, data_type_id, or generic_type_id are set' do diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index c83b8546..6dd7b9b6 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -4,7 +4,7 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do - it { is_expected.to belong_to(:data_type_identifier).optional } + it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier').inverse_of(:function_generic_mappers) } it { is_expected.to belong_to(:runtime_parameter_definition).optional } it { @@ -12,31 +12,4 @@ .optional.inverse_of(:generic_mappers) } end - - describe 'validations' do - it 'is valid with target and one of generic_key or data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'x') - expect(build(:function_generic_mapper, target: 'do_something', generic_key: 'param')).to be_valid - expect(build(:function_generic_mapper, target: 'do_something', data_type_identifier: dti)).to be_valid - end - - it 'is invalid with both generic_key and data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'x') - mapper = build(:function_generic_mapper, target: 'x', generic_key: 'param', data_type_identifier: dti) - expect(mapper).not_to be_valid - expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') - end - - it 'is invalid with neither generic_key nor data_type_identifier' do - mapper = build(:function_generic_mapper, target: 'x', generic_key: nil, data_type_identifier: nil) - expect(mapper).not_to be_valid - expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') - end - - it 'is invalid without a target' do - mapper = build(:function_generic_mapper, target: nil, generic_key: 'something') - expect(mapper).not_to be_valid - expect(mapper.errors[:target]).to include("can't be blank") - end - end end diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index bdc7873f..843a3649 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -7,43 +7,6 @@ describe 'associations' do it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to belong_to(:data_type_identifier).optional } - end - - describe 'validations' do - it 'is valid with target and exactly one of generic_key or data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - - expect(build(:generic_mapper, target: 'target', generic_key: 'key1', generic_type: generic_type)).to be_valid - expect(build(:generic_mapper, target: 'target', data_type_identifier: dti, - generic_type: generic_type)).to be_valid - end - - it 'is invalid without a target' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: nil, generic_key: 'key1', generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:target]).to include("can't be blank") - end - - it 'is invalid when neither generic_key nor data_type_identifier is set' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, - generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') - end - - it 'is invalid when both generic_key and data_type_identifier are set' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, - generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') - end + it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier') } end end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index b97b9ca7..86ff0fec 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -5,19 +5,8 @@ RSpec.describe GenericType do describe 'associations' do - it { is_expected.to belong_to(:data_type_identifier) } + it { is_expected.to belong_to(:data_type) } it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_mappers) } end - - describe 'validations' do - it 'is valid with a data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'key') - expect(build(:generic_type, data_type_identifier: dti)).to be_valid - end - - it 'is invalid without a data_type_identifier' do - expect(build(:generic_type, data_type_identifier: nil)).not_to be_valid - end - end end diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 5473a97a..8aada144 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -15,13 +15,7 @@ end let!(:generic_type) do - create(:generic_type, - runtime: runtime, - data_type_identifier: - create(:data_type_identifier, - runtime: runtime, - data_type: create(:data_type, - runtime: runtime).reload).reload).reload + create(:generic_type, runtime: runtime, data_type: create(:data_type, runtime: runtime)) end let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload } let(:error_type) { create(:data_type, runtime: runtime) } @@ -44,16 +38,13 @@ ], return_type_identifier: { generic_type: { - data_type_identifier: { # Without reloads it just fails - data_type_identifier: return_type.reload.generic_type - .reload.data_type_identifier.reload.data_type.reload.identifier, - }, - generic_mappers: [{ generic_key: 'T', target: 'V' }], + data_type_identifier: return_type.generic_type.data_type.identifier, + generic_mappers: [{ source: { generic_key: 'T' }, target: 'V' }], }, }, generic_mappers: [ { - generic_key: 'X', + source: { generic_key: 'X' }, target: 'Y', parameter_id: 'some_id', } @@ -89,15 +80,15 @@ expect(stub.update(message, authorization(runtime)).success).to be(true) expect(GenericMapper.count).to eq(1) - expect(GenericMapper.last.generic_key).to eq('T') + expect(GenericMapper.last.source.generic_key).to eq('T') expect(GenericMapper.last.target).to eq('V') expect(GenericType.count).to eq(1) function = RuntimeFunctionDefinition.last expect(function.runtime_name).to eq('runtime_function_id') - expect(function.return_type.generic_type.reload.data_type_identifier.data_type.identifier) - .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) + expect(function.return_type.generic_type.reload.data_type.identifier) + .to eq(return_type.generic_type.data_type.identifier) expect(function.names.first.content).to eq('Eine Funktion') expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation') @@ -115,8 +106,8 @@ expect(function_definition.names.first.content).to eq('Eine Funktion') expect(function_definition.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function_definition.documentations.first.content).to eq('Eine Funktionsdokumentation') - expect(function_definition.return_type.generic_type.reload.data_type_identifier.data_type.identifier) - .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) + expect(function_definition.return_type.generic_type.reload.data_type.identifier) + .to eq(return_type.generic_type.data_type.identifier) parameter_definition = ParameterDefinition.first expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter_definition.names.first.content).to eq('Ein Parameter') @@ -125,7 +116,7 @@ expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) expect(FunctionGenericMapper.count).to eq(1) - expect(FunctionGenericMapper.last.generic_key).to eq('X') + expect(FunctionGenericMapper.last.source.generic_key).to eq('X') expect(FunctionGenericMapper.last.target).to eq('Y') expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end From f69ad492c5a96e6be648d5cf907e974fecdcef15 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 15:11:08 +0200 Subject: [PATCH 09/54] Recompile structure.sql --- db/structure.sql | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/db/structure.sql b/db/structure.sql index d249e41a..8f18d1f5 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -424,6 +424,23 @@ CREATE SEQUENCE namespace_members_id_seq ALTER SEQUENCE namespace_members_id_seq OWNED BY namespace_members.id; +CREATE TABLE namespace_project_runtime_assignments ( + id bigint NOT NULL, + runtime_id bigint NOT NULL, + namespace_project_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE namespace_project_runtime_assignments_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE namespace_project_runtime_assignments_id_seq OWNED BY namespace_project_runtime_assignments.id; + CREATE TABLE namespace_projects ( id bigint NOT NULL, name text NOT NULL, @@ -750,6 +767,8 @@ ALTER TABLE ONLY namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('nam ALTER TABLE ONLY namespace_members ALTER COLUMN id SET DEFAULT nextval('namespace_members_id_seq'::regclass); +ALTER TABLE ONLY namespace_project_runtime_assignments ALTER COLUMN id SET DEFAULT nextval('namespace_project_runtime_assignments_id_seq'::regclass); + ALTER TABLE ONLY namespace_projects ALTER COLUMN id SET DEFAULT nextval('namespace_projects_id_seq'::regclass); ALTER TABLE ONLY namespace_role_abilities ALTER COLUMN id SET DEFAULT nextval('namespace_role_abilities_id_seq'::regclass); @@ -852,6 +871,9 @@ ALTER TABLE ONLY namespace_member_roles ALTER TABLE ONLY namespace_members ADD CONSTRAINT namespace_members_pkey PRIMARY KEY (id); +ALTER TABLE ONLY namespace_project_runtime_assignments + ADD CONSTRAINT namespace_project_runtime_assignments_pkey PRIMARY KEY (id); + ALTER TABLE ONLY namespace_projects ADD CONSTRAINT namespace_projects_pkey PRIMARY KEY (id); @@ -910,6 +932,8 @@ CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON function_generi CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); +CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); + CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON runtime_function_definitions USING btree (runtime_id, runtime_name); CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON function_generic_mappers USING btree (runtime_parameter_definition_id); @@ -1168,9 +1192,15 @@ ALTER TABLE ONLY function_generic_mappers ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY namespace_project_runtime_assignments + ADD CONSTRAINT fk_rails_c019e5b233 FOREIGN KEY (namespace_project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; + ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); +ALTER TABLE ONLY namespace_project_runtime_assignments + ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ALTER TABLE ONLY generic_mappers ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; From 87fc3462ae5e60fd440946f7f57b486b3167083e Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 15:22:05 +0200 Subject: [PATCH 10/54] Fix rubocop vulnerabilities --- app/models/generic_mapper.rb | 2 -- app/models/generic_type.rb | 1 - 2 files changed, 3 deletions(-) diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb index a48c6a33..d85b60f9 100644 --- a/app/models/generic_mapper.rb +++ b/app/models/generic_mapper.rb @@ -7,6 +7,4 @@ class GenericMapper < ApplicationRecord belongs_to :runtime_parameter_definition, optional: true, inverse_of: :generic_mappers validates :target, presence: true - - end diff --git a/app/models/generic_type.rb b/app/models/generic_type.rb index 2d879924..a60a0cc3 100644 --- a/app/models/generic_type.rb +++ b/app/models/generic_type.rb @@ -6,5 +6,4 @@ class GenericType < ApplicationRecord has_many :generic_mappers, inverse_of: :generic_type has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :generic_type - end From 7528ffb431a0fd586ae196d1489fa1d8b4130cd3 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Thu, 29 May 2025 02:32:25 +0200 Subject: [PATCH 11/54] Recompile structure.sql --- db/structure.sql | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/db/structure.sql b/db/structure.sql index 8f18d1f5..0fd91ca5 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -448,6 +448,7 @@ CREATE TABLE namespace_projects ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, namespace_id bigint NOT NULL, + primary_runtime_id bigint, CONSTRAINT check_09e881e641 CHECK ((char_length(name) <= 50)), CONSTRAINT check_a77bf7c685 CHECK ((char_length(description) <= 500)) ); @@ -1040,6 +1041,8 @@ CREATE INDEX index_namespace_members_on_user_id ON namespace_members USING btree CREATE INDEX index_namespace_projects_on_namespace_id ON namespace_projects USING btree (namespace_id); +CREATE INDEX index_namespace_projects_on_primary_runtime_id ON namespace_projects USING btree (primary_runtime_id); + CREATE INDEX index_namespace_role_project_assignments_on_project_id ON namespace_role_project_assignments USING btree (project_id); CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON namespace_roles USING btree (namespace_id, lower(name)); @@ -1168,6 +1171,9 @@ ALTER TABLE ONLY runtime_function_definitions ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY namespace_projects + ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ALTER TABLE ONLY data_type_identifiers ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; From 13bad43b36d066ad65b0a193d76672fb789e7383 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 13:37:18 +0200 Subject: [PATCH 12/54] Adjust models and tests --- .../update_service.rb | 22 ++--- db/structure.sql | 84 ++++++------------- ...untime_function_definition_service_spec.rb | 29 ++++--- 3 files changed, 57 insertions(+), 78 deletions(-) diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 537d28fd..e61b1c88 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -51,7 +51,7 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.deprecation_messages) db_object.error_types = update_error_types(runtime_function_definition.error_type_identifiers, db_object, t) - db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object, t) + db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object) if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -69,20 +69,23 @@ def update_runtime_function_definition(runtime_function_definition, t) end # These mappers can be either generic mappers or generic function mappers. - def update_mappers(generic_mappers, runtime_function_definition, t) + def update_mappers(generic_mappers, runtime_function_definition = nil) generic_mappers.to_a.map do |generic_mapper| if generic_mapper.is_a? Tucana::Shared::GenericMapper mapper = GenericMapper.create_or_find_by(runtime: current_runtime, target: generic_mapper.target, - source: find_data_type_identifier(generic_mapper.source, - generic_mappers, t)) + generic_key: generic_mapper.generic_key, + data_type_identifier: + (generic_mapper.generic_key.nil? ? data_type_identifier : nil)) + end if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper mapper = FunctionGenericMapper.create_or_find_by( runtime_id: current_runtime.id, runtime_function_definition: runtime_function_definition, - source: find_data_type_identifier(generic_mapper.source, generic_mappers, t), + data_type_identifier: (generic_mapper.generic_key.nil? ? data_type_identifier : nil), target: generic_mapper.target, + generic_key: generic_mapper.generic_key, parameter_id: generic_mapper.parameter_id ) end @@ -107,16 +110,16 @@ def find_data_type_identifier(identifier, generic_mappers, t) identifier.generic_type.generic_mappers.each do |generic_mapper| arr << generic_mapper end - data_type = find_data_type(identifier.generic_type.data_type_identifier, t) + data_type_identifier = find_data_type_identifier(identifier.generic_type.data_type_identifier, arr, t) generic_type = GenericType.find_by( runtime_id: current_runtime.id, - data_type: data_type + data_type_identifier_id: data_type_identifier.id ) if generic_type.nil? generic_type = GenericType.create( runtime_id: current_runtime.id, - data_type: data_type + data_type_identifier_id: data_type_identifier.id ) end @@ -127,8 +130,7 @@ def find_data_type_identifier(identifier, generic_mappers, t) ) end - generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers, nil, - t)) + generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers)) return create_data_type_identifier(t, generic_type_id: generic_type.id) end diff --git a/db/structure.sql b/db/structure.sql index 0fd91ca5..88922ba7 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -241,14 +241,16 @@ ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; CREATE TABLE function_generic_mappers ( id bigint NOT NULL, - source_id bigint, + data_type_identifier_id bigint, + generic_key text, target text NOT NULL, parameter_id text, runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL + updated_at timestamp with time zone NOT NULL, + CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) ); CREATE SEQUENCE function_generic_mappers_id_seq @@ -262,12 +264,14 @@ ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers CREATE TABLE generic_mappers ( id bigint NOT NULL, - runtime_id bigint NOT NULL, target text NOT NULL, - source_id bigint NOT NULL, + generic_key text, + data_type_identifier_id bigint, generic_type_id bigint, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL + updated_at timestamp with time zone NOT NULL, + CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) ); CREATE SEQUENCE generic_mappers_id_seq @@ -281,8 +285,8 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, + data_type_identifier_id bigint NOT NULL, runtime_id bigint NOT NULL, - data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); @@ -424,23 +428,6 @@ CREATE SEQUENCE namespace_members_id_seq ALTER SEQUENCE namespace_members_id_seq OWNED BY namespace_members.id; -CREATE TABLE namespace_project_runtime_assignments ( - id bigint NOT NULL, - runtime_id bigint NOT NULL, - namespace_project_id bigint NOT NULL, - created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL -); - -CREATE SEQUENCE namespace_project_runtime_assignments_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -ALTER SEQUENCE namespace_project_runtime_assignments_id_seq OWNED BY namespace_project_runtime_assignments.id; - CREATE TABLE namespace_projects ( id bigint NOT NULL, name text NOT NULL, @@ -448,7 +435,6 @@ CREATE TABLE namespace_projects ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, namespace_id bigint NOT NULL, - primary_runtime_id bigint, CONSTRAINT check_09e881e641 CHECK ((char_length(name) <= 50)), CONSTRAINT check_a77bf7c685 CHECK ((char_length(description) <= 500)) ); @@ -768,8 +754,6 @@ ALTER TABLE ONLY namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('nam ALTER TABLE ONLY namespace_members ALTER COLUMN id SET DEFAULT nextval('namespace_members_id_seq'::regclass); -ALTER TABLE ONLY namespace_project_runtime_assignments ALTER COLUMN id SET DEFAULT nextval('namespace_project_runtime_assignments_id_seq'::regclass); - ALTER TABLE ONLY namespace_projects ALTER COLUMN id SET DEFAULT nextval('namespace_projects_id_seq'::regclass); ALTER TABLE ONLY namespace_role_abilities ALTER COLUMN id SET DEFAULT nextval('namespace_role_abilities_id_seq'::regclass); @@ -872,9 +856,6 @@ ALTER TABLE ONLY namespace_member_roles ALTER TABLE ONLY namespace_members ADD CONSTRAINT namespace_members_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_project_runtime_assignments - ADD CONSTRAINT namespace_project_runtime_assignments_pkey PRIMARY KEY (id); - ALTER TABLE ONLY namespace_projects ADD CONSTRAINT namespace_projects_pkey PRIMARY KEY (id); @@ -933,8 +914,6 @@ CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON function_generi CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); -CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); - CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON runtime_function_definitions USING btree (runtime_id, runtime_name); CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON function_generic_mappers USING btree (runtime_parameter_definition_id); @@ -979,17 +958,17 @@ CREATE INDEX index_function_definitions_on_return_type_id ON function_definition CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); +CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); + CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); -CREATE INDEX index_function_generic_mappers_on_source_id ON function_generic_mappers USING btree (source_id); +CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); -CREATE INDEX index_generic_mappers_on_source_id ON generic_mappers USING btree (source_id); - -CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); +CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); @@ -1041,8 +1020,6 @@ CREATE INDEX index_namespace_members_on_user_id ON namespace_members USING btree CREATE INDEX index_namespace_projects_on_namespace_id ON namespace_projects USING btree (namespace_id); -CREATE INDEX index_namespace_projects_on_primary_runtime_id ON namespace_projects USING btree (primary_runtime_id); - CREATE INDEX index_namespace_role_project_assignments_on_project_id ON namespace_role_project_assignments USING btree (project_id); CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON namespace_roles USING btree (namespace_id, lower(name)); @@ -1097,19 +1074,19 @@ ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_2adace81b8 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -1127,7 +1104,7 @@ ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1171,17 +1148,14 @@ ALTER TABLE ONLY runtime_function_definitions ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY namespace_projects - ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; - ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY user_sessions ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -1192,23 +1166,14 @@ ALTER TABLE ONLY namespace_members ALTER TABLE ONLY flow_type_settings ADD CONSTRAINT fk_rails_a1471d011d FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_be1833ba72 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; - ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY namespace_project_runtime_assignments - ADD CONSTRAINT fk_rails_c019e5b233 FOREIGN KEY (namespace_project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; - ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); -ALTER TABLE ONLY namespace_project_runtime_assignments - ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; - ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1217,7 +1182,7 @@ ALTER TABLE ONLY namespace_projects ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1225,6 +1190,9 @@ ALTER TABLE ONLY runtime_parameter_definitions ALTER TABLE ONLY runtimes ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ALTER TABLE ONLY audit_events ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 8aada144..5473a97a 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -15,7 +15,13 @@ end let!(:generic_type) do - create(:generic_type, runtime: runtime, data_type: create(:data_type, runtime: runtime)) + create(:generic_type, + runtime: runtime, + data_type_identifier: + create(:data_type_identifier, + runtime: runtime, + data_type: create(:data_type, + runtime: runtime).reload).reload).reload end let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload } let(:error_type) { create(:data_type, runtime: runtime) } @@ -38,13 +44,16 @@ ], return_type_identifier: { generic_type: { - data_type_identifier: return_type.generic_type.data_type.identifier, - generic_mappers: [{ source: { generic_key: 'T' }, target: 'V' }], + data_type_identifier: { # Without reloads it just fails + data_type_identifier: return_type.reload.generic_type + .reload.data_type_identifier.reload.data_type.reload.identifier, + }, + generic_mappers: [{ generic_key: 'T', target: 'V' }], }, }, generic_mappers: [ { - source: { generic_key: 'X' }, + generic_key: 'X', target: 'Y', parameter_id: 'some_id', } @@ -80,15 +89,15 @@ expect(stub.update(message, authorization(runtime)).success).to be(true) expect(GenericMapper.count).to eq(1) - expect(GenericMapper.last.source.generic_key).to eq('T') + expect(GenericMapper.last.generic_key).to eq('T') expect(GenericMapper.last.target).to eq('V') expect(GenericType.count).to eq(1) function = RuntimeFunctionDefinition.last expect(function.runtime_name).to eq('runtime_function_id') - expect(function.return_type.generic_type.reload.data_type.identifier) - .to eq(return_type.generic_type.data_type.identifier) + expect(function.return_type.generic_type.reload.data_type_identifier.data_type.identifier) + .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) expect(function.names.first.content).to eq('Eine Funktion') expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation') @@ -106,8 +115,8 @@ expect(function_definition.names.first.content).to eq('Eine Funktion') expect(function_definition.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function_definition.documentations.first.content).to eq('Eine Funktionsdokumentation') - expect(function_definition.return_type.generic_type.reload.data_type.identifier) - .to eq(return_type.generic_type.data_type.identifier) + expect(function_definition.return_type.generic_type.reload.data_type_identifier.data_type.identifier) + .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) parameter_definition = ParameterDefinition.first expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter_definition.names.first.content).to eq('Ein Parameter') @@ -116,7 +125,7 @@ expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) expect(FunctionGenericMapper.count).to eq(1) - expect(FunctionGenericMapper.last.source.generic_key).to eq('X') + expect(FunctionGenericMapper.last.generic_key).to eq('X') expect(FunctionGenericMapper.last.target).to eq('Y') expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end From 67622d60748f299f0f3f24cbdeef87d1a5c3a08b Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 00:29:57 +0200 Subject: [PATCH 13/54] Update datatype model and runtime function (definition) models --- Gemfile | 2 +- Gemfile.lock | 4 +- app/models/data_type.rb | 5 +- app/models/data_type_identifier.rb | 10 ++-- app/models/function_generic_mapper.rb | 14 ++++-- app/models/generic_mapper.rb | 17 +++++-- app/models/generic_type.rb | 4 +- .../20250525192143_implement_generics.rb | 49 ++++++++++--------- db/structure.sql | 32 +----------- spec/factories/data_type_identifiers.rb | 1 - spec/factories/function_generic_mappers.rb | 5 +- spec/factories/generic_mappers.rb | 4 +- spec/factories/generic_types.rb | 3 +- spec/models/data_type_identifier_spec.rb | 10 ++-- spec/models/function_generic_mapper_spec.rb | 30 +++++++++++- spec/models/generic_mapper_spec.rb | 42 ++++++++++++++-- spec/models/generic_type_spec.rb | 14 +++++- 17 files changed, 152 insertions(+), 94 deletions(-) diff --git a/Gemfile b/Gemfile index 713ce561..5ceadfd1 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.28' +gem 'tucana', '0.0.26' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index c08fc171..5dec9ce4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -356,7 +356,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.28) + tucana (0.0.26) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -409,7 +409,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.28) + tucana (= 0.0.26) tzinfo-data RUBY VERSION diff --git a/app/models/data_type.rb b/app/models/data_type.rb index 8cc41553..e162af9f 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -7,8 +7,8 @@ class DataType < ApplicationRecord object: 3, datatype: 4, array: 5, - error: 6, - node: 7, + generic: 6, + function: 7, }.with_indifferent_access enum :variant, VARIANTS, prefix: :variant @@ -20,7 +20,6 @@ class DataType < ApplicationRecord has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :rules, class_name: 'DataTypeRule', inverse_of: :data_type has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :data_type - has_many :generic_types, class_name: 'GenericType', inverse_of: :data_type validates :variant, presence: true, inclusion: { diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index bd76551a..657ab83f 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -2,18 +2,18 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers - belongs_to :generic_type, optional: true, inverse_of: :data_type_identifiers - belongs_to :runtime, inverse_of: :data_type_identifiers + belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier - has_many :generic_mappers, inverse_of: :source - has_many :function_generic_mappers, class_name: 'FunctionGenericMapper', inverse_of: :source + has_many :generic_types, inverse_of: :data_type_identifier + has_many :generic_mappers, inverse_of: :data_type_identifier + has_many :function_generic_mappers, class_name: 'GenericMapper', inverse_of: :data_type_identifier validate :exactly_one_of_generic_key_data_type_id_generic_type_id private def exactly_one_of_generic_key_data_type_id_generic_type_id - values = [generic_key.present?, data_type.present?, generic_type.present?] + values = [generic_key.present?, data_type_id.present?, generic_type_id.present?] return if values.count(true) == 1 errors.add(:base, 'Exactly one of generic_key, data_type_id, or generic_type_id must be present') diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 10d8b015..32489de2 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -1,11 +1,19 @@ # frozen_string_literal: true class FunctionGenericMapper < ApplicationRecord - belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mappers + belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers - belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, - inverse_of: :function_generic_mappers validates :target, presence: true + validate :exactly_one_of_generic_key_or_data_type_identifier_id + + private + + def exactly_one_of_generic_key_or_data_type_identifier_id + values = [generic_key.present?, data_type_identifier_id.present?] + return if values.count(true) == 1 + + errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') + end end diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb index d85b60f9..d2ed8fd8 100644 --- a/app/models/generic_mapper.rb +++ b/app/models/generic_mapper.rb @@ -1,10 +1,19 @@ # frozen_string_literal: true class GenericMapper < ApplicationRecord - belongs_to :generic_type, inverse_of: :generic_mappers, optional: true - belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :generic_mappers - belongs_to :runtime, inverse_of: :generic_mappers - belongs_to :runtime_parameter_definition, optional: true, inverse_of: :generic_mappers + belongs_to :generic_type, inverse_of: :generic_mappers + belongs_to :data_type_identifier, optional: true, inverse_of: :generic_mappers validates :target, presence: true + validate :exactly_one_of_generic_key_or_data_type_identifier_id, :generic_key_changed? + validate :exactly_one_of_generic_key_or_data_type_identifier_id, :data_type_identifier_changed? + + private + + def exactly_one_of_generic_key_or_data_type_identifier_id + values = [generic_key.present?, data_type_identifier_id.present?] + return if values.count(true) == 1 + + errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') + end end diff --git a/app/models/generic_type.rb b/app/models/generic_type.rb index a60a0cc3..c8c1aa1d 100644 --- a/app/models/generic_type.rb +++ b/app/models/generic_type.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true class GenericType < ApplicationRecord - belongs_to :data_type, class_name: 'DataType', inverse_of: :generic_types - belongs_to :runtime, class_name: 'Runtime', inverse_of: :generic_types + belongs_to :data_type_identifier, inverse_of: :generic_type has_many :generic_mappers, inverse_of: :generic_type - has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :generic_type end diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 747303a3..416af4a0 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -8,28 +8,31 @@ def change add_column :data_types, :generic_keys, 'text[]', null: false, default: [] create_table :data_type_identifiers do |t| - # One of them needs to be set will be enforced later + # One of them needs to be set t.text :generic_key, null: true t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } - t.timestamps_with_timezone end create_table :generic_types do |t| - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } - t.references :data_type, null: false, foreign_key: { to_table: :data_types, on_delete: :cascade } + t.references :data_type_identifier, null: false, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } t.timestamps_with_timezone end create_table :generic_mappers do |t| - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } - t.text :target, null: false - t.references :source, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } - t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :restrict } + # One of them needs to be set + t.text :generic_key, null: true + t.references :data_type_identifier, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:generic_mappers, :source, :one_of) + + t.references :generic_type, null: false, foreign_key: { to_table: :generic_types, on_delete: :cascade } t.timestamps_with_timezone end @@ -41,42 +44,42 @@ def change name: check_constraint_name(:data_type_identifiers, :type, :one_of) create_table :function_generic_mappers do |t| - t.references :source, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } + t.references :data_type_identifier, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + t.text :generic_key, null: true t.text :target, null: false t.text :parameter_id, null: true - t.references :runtime_parameter_definition, null: true, - foreign_key: { to_table: :runtime_parameter_definitions, - on_delete: :restrict } + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:function_generic_mappers, :source, :one_of) t.references :runtime_function_definition, null: true, foreign_key: { to_table: :runtime_function_definitions, - on_delete: :restrict } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + on_delete: :cascade } t.timestamps_with_timezone end - remove_reference :runtime_function_definitions, :return_type, - foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_column :runtime_function_definitions, :return_type_id add_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] - remove_reference :runtime_parameter_definitions, :data_type, - foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_column :runtime_parameter_definitions, :data_type_id add_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_column :parameter_definitions, :data_type_id add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_reference :function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } + # remove_column :runtime_function_definition_error_types, :data_type_id + # add_reference :runtime_function_definition_error_types, :data_type, + # foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: false + + remove_column :function_definitions, :return_type_id add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true end diff --git a/db/structure.sql b/db/structure.sql index 88922ba7..09321dc3 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -125,7 +125,6 @@ CREATE TABLE data_type_identifiers ( id bigint NOT NULL, generic_key text, data_type_id bigint, - runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, generic_type_id bigint, @@ -245,9 +244,7 @@ CREATE TABLE function_generic_mappers ( generic_key text, target text NOT NULL, parameter_id text, - runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, - runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) @@ -267,8 +264,7 @@ CREATE TABLE generic_mappers ( target text NOT NULL, generic_key text, data_type_identifier_id bigint, - generic_type_id bigint, - runtime_id bigint NOT NULL, + generic_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) @@ -286,7 +282,6 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, data_type_identifier_id bigint NOT NULL, - runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); @@ -916,8 +911,6 @@ CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31b CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON runtime_function_definitions USING btree (runtime_id, runtime_name); -CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON function_generic_mappers USING btree (runtime_parameter_definition_id); - CREATE INDEX index_active_storage_attachments_on_blob_id ON active_storage_attachments USING btree (blob_id); CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON active_storage_attachments USING btree (record_type, record_id, name, blob_id); @@ -936,8 +929,6 @@ CREATE INDEX index_data_type_identifiers_on_data_type_id ON data_type_identifier CREATE INDEX index_data_type_identifiers_on_generic_type_id ON data_type_identifiers USING btree (generic_type_id); -CREATE INDEX index_data_type_identifiers_on_runtime_id ON data_type_identifiers USING btree (runtime_id); - CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id); CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (parent_type_id); @@ -960,18 +951,12 @@ CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON fun CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); -CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); - CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); -CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); - CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); -CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); - CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON good_job_executions USING btree (active_job_id, created_at); CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON good_job_executions USING btree (process_id, created_at); @@ -1073,15 +1058,9 @@ ALTER TABLE ONLY data_types ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; -ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; - ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; - ALTER TABLE ONLY generic_types ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; @@ -1103,9 +1082,6 @@ ALTER TABLE ONLY data_type_identifiers ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; - ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1148,9 +1124,6 @@ ALTER TABLE ONLY runtime_function_definitions ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; - ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); @@ -1172,9 +1145,6 @@ ALTER TABLE ONLY flow_types ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); -ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; - ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; diff --git a/spec/factories/data_type_identifiers.rb b/spec/factories/data_type_identifiers.rb index f3103216..7ef0303c 100644 --- a/spec/factories/data_type_identifiers.rb +++ b/spec/factories/data_type_identifiers.rb @@ -5,6 +5,5 @@ generic_key { nil } data_type { nil } generic_type { nil } - runtime end end diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb index e448ce1d..e5579f87 100644 --- a/spec/factories/function_generic_mappers.rb +++ b/spec/factories/function_generic_mappers.rb @@ -3,7 +3,8 @@ FactoryBot.define do factory :function_generic_mapper do target { nil } - runtime_parameter_definition { nil } - source { nil } + parameter_id { nil } + generic_key { nil } + data_type_identifier { nil } end end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index 36a7fdc9..b601b3c5 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -2,8 +2,8 @@ FactoryBot.define do factory :generic_mapper do - runtime target { nil } - source { nil } + generic_key { nil } + data_type_identifier { nil } end end diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index a7601bec..f26bc778 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -2,8 +2,7 @@ FactoryBot.define do factory :generic_type do - runtime generic_mappers { [] } - data_type + data_type_identifier { nil } end end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index a2270dcd..e27ff00e 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -7,18 +7,18 @@ describe 'associations' do it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } - it { is_expected.to belong_to(:runtime) } - it { is_expected.to have_many(:generic_mappers).inverse_of(:source) } - it { is_expected.to have_many(:function_generic_mappers).inverse_of(:source) } + it { is_expected.to have_many(:generic_types) } + it { is_expected.to have_many(:generic_mappers) } end describe 'validations' do it 'is valid with exactly one of generic_key, data_type_id, or generic_type_id' do expect(build(:data_type_identifier, generic_key: 'key')).to be_valid expect(build(:data_type_identifier, data_type: create(:data_type))).to be_valid - generic_type = create(:generic_type, data_type: create(:data_type)) expect(build(:data_type_identifier, - generic_type: generic_type)).to be_valid + generic_type: create(:generic_type, + data_type_identifier: create(:data_type_identifier, + generic_key: 'x')))).to be_valid end it 'is invalid when none of generic_key, data_type_id, or generic_type_id are set' do diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index 6dd7b9b6..f22a01fa 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -4,12 +4,38 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do - it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier').inverse_of(:function_generic_mappers) } - it { is_expected.to belong_to(:runtime_parameter_definition).optional } + it { is_expected.to belong_to(:data_type_identifier).optional } it { is_expected.to belong_to(:runtime_function_definition).class_name('RuntimeFunctionDefinition') .optional.inverse_of(:generic_mappers) } end + + describe 'validations' do + it 'is valid with target and one of generic_key or data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'x') + expect(build(:function_generic_mapper, target: 'do_something', generic_key: 'param')).to be_valid + expect(build(:function_generic_mapper, target: 'do_something', data_type_identifier: dti)).to be_valid + end + + it 'is invalid with both generic_key and data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'x') + mapper = build(:function_generic_mapper, target: 'x', generic_key: 'param', data_type_identifier: dti) + expect(mapper).not_to be_valid + expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid with neither generic_key nor data_type_identifier' do + mapper = build(:function_generic_mapper, target: 'x', generic_key: nil, data_type_identifier: nil) + expect(mapper).not_to be_valid + expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid without a target' do + mapper = build(:function_generic_mapper, target: nil, generic_key: 'something') + expect(mapper).not_to be_valid + expect(mapper.errors[:target]).to include("can't be blank") + end + end end diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index 843a3649..419407c7 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -5,8 +5,44 @@ RSpec.describe GenericMapper do describe 'associations' do - it { is_expected.to belong_to(:generic_type).optional } - it { is_expected.to belong_to(:runtime) } - it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier') } + it { is_expected.to belong_to(:generic_type) } + it { is_expected.to belong_to(:data_type_identifier).optional } + end + + describe 'validations' do + it 'is valid with target and exactly one of generic_key or data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + + expect(build(:generic_mapper, target: 'target', generic_key: 'key1', generic_type: generic_type)).to be_valid + expect(build(:generic_mapper, target: 'target', data_type_identifier: dti, + generic_type: generic_type)).to be_valid + end + + it 'is invalid without a target' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: nil, generic_key: 'key1', generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:target]).to include("can't be blank") + end + + it 'is invalid when neither generic_key nor data_type_identifier is set' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, + generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid when both generic_key and data_type_identifier are set' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, + generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end end end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index 86ff0fec..9a2aae5c 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -5,8 +5,18 @@ RSpec.describe GenericType do describe 'associations' do - it { is_expected.to belong_to(:data_type) } - it { is_expected.to belong_to(:runtime) } + it { is_expected.to belong_to(:data_type_identifier) } it { is_expected.to have_many(:generic_mappers) } end + + describe 'validations' do + it 'is valid with a data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'key') + expect(build(:generic_type, data_type_identifier: dti)).to be_valid + end + + it 'is invalid without a data_type_identifier' do + expect(build(:generic_type, data_type_identifier: nil)).not_to be_valid + end + end end From 025e13631b0d6cc302959f8b56c8bef69bc9c4e4 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 13:37:18 +0200 Subject: [PATCH 14/54] Adjust models and tests --- Gemfile | 2 +- Gemfile.lock | 4 +-- app/models/data_type_identifier.rb | 3 +- app/models/function_generic_mapper.rb | 4 ++- app/models/generic_mapper.rb | 8 +++-- app/models/generic_type.rb | 1 + .../20250525192143_implement_generics.rb | 22 +++++++++---- db/structure.sql | 32 ++++++++++++++++++- spec/factories/data_type_identifiers.rb | 1 + spec/factories/function_generic_mappers.rb | 2 +- spec/factories/generic_mappers.rb | 1 + spec/factories/generic_types.rb | 1 + spec/models/data_type_identifier_spec.rb | 1 + spec/models/function_generic_mapper_spec.rb | 1 + spec/models/generic_mapper_spec.rb | 7 ++-- spec/models/generic_type_spec.rb | 1 + 16 files changed, 71 insertions(+), 20 deletions(-) diff --git a/Gemfile b/Gemfile index 5ceadfd1..fa653e3a 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.26' +gem 'tucana', '0.0.27' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 5dec9ce4..729121d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -356,7 +356,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.26) + tucana (0.0.27) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -409,7 +409,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.26) + tucana (= 0.0.27) tzinfo-data RUBY VERSION diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 657ab83f..8b28aaad 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -3,6 +3,7 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier + belongs_to :runtime, inverse_of: :data_type_identifiers has_many :generic_types, inverse_of: :data_type_identifier has_many :generic_mappers, inverse_of: :data_type_identifier @@ -13,7 +14,7 @@ class DataTypeIdentifier < ApplicationRecord private def exactly_one_of_generic_key_data_type_id_generic_type_id - values = [generic_key.present?, data_type_id.present?, generic_type_id.present?] + values = [generic_key.present?, data_type.present?, generic_type.present?] return if values.count(true) == 1 errors.add(:base, 'Exactly one of generic_key, data_type_id, or generic_type_id must be present') diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 32489de2..0612a21a 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -4,6 +4,8 @@ class FunctionGenericMapper < ApplicationRecord belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers + belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, + inverse_of: :function_generic_mappers validates :target, presence: true validate :exactly_one_of_generic_key_or_data_type_identifier_id @@ -11,7 +13,7 @@ class FunctionGenericMapper < ApplicationRecord private def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier_id.present?] + values = [generic_key.present?, data_type_identifier.present?] return if values.count(true) == 1 errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb index d2ed8fd8..117b44dc 100644 --- a/app/models/generic_mapper.rb +++ b/app/models/generic_mapper.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class GenericMapper < ApplicationRecord - belongs_to :generic_type, inverse_of: :generic_mappers + belongs_to :generic_type, inverse_of: :generic_mappers, optional: true belongs_to :data_type_identifier, optional: true, inverse_of: :generic_mappers + belongs_to :runtime, inverse_of: :generic_mappers + belongs_to :runtime_parameter_definition, optional: true, inverse_of: :generic_mappers validates :target, presence: true validate :exactly_one_of_generic_key_or_data_type_identifier_id, :generic_key_changed? @@ -11,9 +13,9 @@ class GenericMapper < ApplicationRecord private def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier_id.present?] + values = [generic_key.present?, data_type_identifier.present?] return if values.count(true) == 1 - errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') + errors.add(:base, 'Exactly one of generic_key or data_type_identifier must be present') end end diff --git a/app/models/generic_type.rb b/app/models/generic_type.rb index c8c1aa1d..bb7cba2f 100644 --- a/app/models/generic_type.rb +++ b/app/models/generic_type.rb @@ -2,6 +2,7 @@ class GenericType < ApplicationRecord belongs_to :data_type_identifier, inverse_of: :generic_type + belongs_to :runtime, class_name: 'Runtime', inverse_of: :generic_types has_many :generic_mappers, inverse_of: :generic_type end diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 416af4a0..4151d076 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -11,6 +11,8 @@ def change # One of them needs to be set t.text :generic_key, null: true t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -18,6 +20,8 @@ def change create_table :generic_types do |t| t.references :data_type_identifier, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -32,7 +36,9 @@ def change t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', name: check_constraint_name(:generic_mappers, :source, :one_of) - t.references :generic_type, null: false, foreign_key: { to_table: :generic_types, on_delete: :cascade } + t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -48,15 +54,21 @@ def change foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } t.text :generic_key, null: true + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.text :target, null: false t.text :parameter_id, null: true - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.references :runtime_parameter_definition, null: true, + foreign_key: { to_table: :runtime_parameter_definitions, + on_delete: :cascade } t.references :runtime_function_definition, null: true, foreign_key: { to_table: :runtime_function_definitions, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -75,10 +87,6 @@ def change add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - # remove_column :runtime_function_definition_error_types, :data_type_id - # add_reference :runtime_function_definition_error_types, :data_type, - # foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: false - remove_column :function_definitions, :return_type_id add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true diff --git a/db/structure.sql b/db/structure.sql index 09321dc3..88922ba7 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -125,6 +125,7 @@ CREATE TABLE data_type_identifiers ( id bigint NOT NULL, generic_key text, data_type_id bigint, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, generic_type_id bigint, @@ -244,7 +245,9 @@ CREATE TABLE function_generic_mappers ( generic_key text, target text NOT NULL, parameter_id text, + runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) @@ -264,7 +267,8 @@ CREATE TABLE generic_mappers ( target text NOT NULL, generic_key text, data_type_identifier_id bigint, - generic_type_id bigint NOT NULL, + generic_type_id bigint, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) @@ -282,6 +286,7 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, data_type_identifier_id bigint NOT NULL, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); @@ -911,6 +916,8 @@ CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31b CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON runtime_function_definitions USING btree (runtime_id, runtime_name); +CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON function_generic_mappers USING btree (runtime_parameter_definition_id); + CREATE INDEX index_active_storage_attachments_on_blob_id ON active_storage_attachments USING btree (blob_id); CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON active_storage_attachments USING btree (record_type, record_id, name, blob_id); @@ -929,6 +936,8 @@ CREATE INDEX index_data_type_identifiers_on_data_type_id ON data_type_identifier CREATE INDEX index_data_type_identifiers_on_generic_type_id ON data_type_identifiers USING btree (generic_type_id); +CREATE INDEX index_data_type_identifiers_on_runtime_id ON data_type_identifiers USING btree (runtime_id); + CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id); CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (parent_type_id); @@ -951,12 +960,18 @@ CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON fun CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); +CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); + CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); +CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); + CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); +CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); + CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON good_job_executions USING btree (active_job_id, created_at); CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON good_job_executions USING btree (process_id, created_at); @@ -1058,9 +1073,15 @@ ALTER TABLE ONLY data_types ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY generic_types + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; + ALTER TABLE ONLY generic_types ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; @@ -1082,6 +1103,9 @@ ALTER TABLE ONLY data_type_identifiers ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1124,6 +1148,9 @@ ALTER TABLE ONLY runtime_function_definitions ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); @@ -1145,6 +1172,9 @@ ALTER TABLE ONLY flow_types ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); +ALTER TABLE ONLY generic_mappers + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; diff --git a/spec/factories/data_type_identifiers.rb b/spec/factories/data_type_identifiers.rb index 7ef0303c..f3103216 100644 --- a/spec/factories/data_type_identifiers.rb +++ b/spec/factories/data_type_identifiers.rb @@ -5,5 +5,6 @@ generic_key { nil } data_type { nil } generic_type { nil } + runtime end end diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb index e5579f87..96e28ab6 100644 --- a/spec/factories/function_generic_mappers.rb +++ b/spec/factories/function_generic_mappers.rb @@ -3,7 +3,7 @@ FactoryBot.define do factory :function_generic_mapper do target { nil } - parameter_id { nil } + runtime_parameter_definition { nil } generic_key { nil } data_type_identifier { nil } end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index b601b3c5..33a5cd58 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :generic_mapper do + runtime target { nil } generic_key { nil } data_type_identifier { nil } diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index f26bc778..a4eef104 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :generic_type do + runtime generic_mappers { [] } data_type_identifier { nil } end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index e27ff00e..11d422d7 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -7,6 +7,7 @@ describe 'associations' do it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } + it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_types) } it { is_expected.to have_many(:generic_mappers) } end diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index f22a01fa..c83b8546 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -5,6 +5,7 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do it { is_expected.to belong_to(:data_type_identifier).optional } + it { is_expected.to belong_to(:runtime_parameter_definition).optional } it { is_expected.to belong_to(:runtime_function_definition).class_name('RuntimeFunctionDefinition') diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index 419407c7..bdc7873f 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -5,7 +5,8 @@ RSpec.describe GenericMapper do describe 'associations' do - it { is_expected.to belong_to(:generic_type) } + it { is_expected.to belong_to(:generic_type).optional } + it { is_expected.to belong_to(:runtime) } it { is_expected.to belong_to(:data_type_identifier).optional } end @@ -33,7 +34,7 @@ gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, generic_type: generic_type) expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') end it 'is invalid when both generic_key and data_type_identifier are set' do @@ -42,7 +43,7 @@ gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, generic_type: generic_type) expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') end end end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index 9a2aae5c..b97b9ca7 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -6,6 +6,7 @@ RSpec.describe GenericType do describe 'associations' do it { is_expected.to belong_to(:data_type_identifier) } + it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_mappers) } end From f134b7dd1c27959c71cab631b5deca43bfacf156 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 13:37:18 +0200 Subject: [PATCH 15/54] Adjust models and tests --- db/structure.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/db/structure.sql b/db/structure.sql index 88922ba7..a63f6d6e 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -618,7 +618,6 @@ CREATE TABLE runtimes ( namespace_id bigint, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, - status integer DEFAULT 0 NOT NULL, CONSTRAINT check_090cd49d30 CHECK ((char_length(name) <= 50)), CONSTRAINT check_f3c2ba8db3 CHECK ((char_length(description) <= 500)) ); From 1842be27e52261740c6278910352fdc17a749dbf Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 15:59:03 +0200 Subject: [PATCH 16/54] Create flow model and everything associated with it (no functionality yet) --- app/models/flow.rb | 11 + app/models/flow_setting.rb | 6 + app/models/flow_setting_definition.rb | 5 + app/models/node_function.rb | 8 + app/models/node_parameter.rb | 19 ++ app/models/reference_path.rb | 5 + app/models/reference_value.rb | 7 + db/migrate/20250526124346_create_flows.rb | 82 ++++++ db/schema_migrations/20250526124346 | 1 + db/structure.sql | 238 ++++++++++++++++++ spec/factories/flow_setting_definitions.rb | 8 + spec/factories/flow_settings.rb | 9 + spec/factories/flows.rb | 9 + spec/factories/node_functions.rb | 9 + spec/factories/node_parameters.rb | 10 + spec/factories/reference_paths.rb | 9 + spec/factories/reference_values.rb | 10 + .../runtime_parameter_definitions.rb | 2 +- spec/models/flow_setting_definition_spec.rb | 11 + spec/models/flow_setting_spec.rb | 12 + spec/models/flow_spec.rb | 13 + spec/models/node_function_spec.rb | 14 ++ spec/models/node_parameter_spec.rb | 29 +++ spec/models/reference_path_spec.rb | 15 ++ spec/models/reference_value_spec.rb | 14 ++ 25 files changed, 555 insertions(+), 1 deletion(-) create mode 100644 app/models/flow.rb create mode 100644 app/models/flow_setting.rb create mode 100644 app/models/flow_setting_definition.rb create mode 100644 app/models/node_function.rb create mode 100644 app/models/node_parameter.rb create mode 100644 app/models/reference_path.rb create mode 100644 app/models/reference_value.rb create mode 100644 db/migrate/20250526124346_create_flows.rb create mode 100644 db/schema_migrations/20250526124346 create mode 100644 spec/factories/flow_setting_definitions.rb create mode 100644 spec/factories/flow_settings.rb create mode 100644 spec/factories/flows.rb create mode 100644 spec/factories/node_functions.rb create mode 100644 spec/factories/node_parameters.rb create mode 100644 spec/factories/reference_paths.rb create mode 100644 spec/factories/reference_values.rb create mode 100644 spec/models/flow_setting_definition_spec.rb create mode 100644 spec/models/flow_setting_spec.rb create mode 100644 spec/models/flow_spec.rb create mode 100644 spec/models/node_function_spec.rb create mode 100644 spec/models/node_parameter_spec.rb create mode 100644 spec/models/reference_path_spec.rb create mode 100644 spec/models/reference_value_spec.rb diff --git a/app/models/flow.rb b/app/models/flow.rb new file mode 100644 index 00000000..969d5e57 --- /dev/null +++ b/app/models/flow.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class Flow < ApplicationRecord + belongs_to :project, class_name: 'NamespaceProject' + belongs_to :flow_type + belongs_to :input_type_identifier, class_name: 'DataTypeIdentifier', optional: true + belongs_to :return_type_identifier, class_name: 'DataTypeIdentifier', optional: true + belongs_to :starting_node, class_name: 'NodeFunction' + + has_many :flow_settings, dependent: :destroy +end diff --git a/app/models/flow_setting.rb b/app/models/flow_setting.rb new file mode 100644 index 00000000..0b3311c0 --- /dev/null +++ b/app/models/flow_setting.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class FlowSetting < ApplicationRecord + belongs_to :flow, optional: true + belongs_to :definition, class_name: 'FlowSettingDefinition' +end diff --git a/app/models/flow_setting_definition.rb b/app/models/flow_setting_definition.rb new file mode 100644 index 00000000..e907599a --- /dev/null +++ b/app/models/flow_setting_definition.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class FlowSettingDefinition < ApplicationRecord + has_many :flow_settings, inverse_of: :definition +end diff --git a/app/models/node_function.rb b/app/models/node_function.rb new file mode 100644 index 00000000..e639bd0b --- /dev/null +++ b/app/models/node_function.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class NodeFunction < ApplicationRecord + belongs_to :runtime_function, class_name: 'RuntimeFunctionDefinition' + belongs_to :next_node, class_name: 'NodeFunction', optional: true + + has_many :node_parameters, inverse_of: :function_value +end diff --git a/app/models/node_parameter.rb b/app/models/node_parameter.rb new file mode 100644 index 00000000..ea4690c6 --- /dev/null +++ b/app/models/node_parameter.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class NodeParameter < ApplicationRecord + belongs_to :runtime_parameter, class_name: 'RuntimeParameterDefinition' + belongs_to :reference_value, optional: true + belongs_to :function_value, class_name: 'NodeFunction', optional: true + + validate :only_one_value_present + + private + + def only_one_value_present + values = [literal_value.present?, reference_value.present?, function_value.present?] + return if values.count(true) == 1 + + errors.add(:base, + 'Exactly one of literal_value, reference_value, or function_value must be present') + end +end diff --git a/app/models/reference_path.rb b/app/models/reference_path.rb new file mode 100644 index 00000000..5cbff11f --- /dev/null +++ b/app/models/reference_path.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ReferencePath < ApplicationRecord + belongs_to :reference_value +end diff --git a/app/models/reference_value.rb b/app/models/reference_value.rb new file mode 100644 index 00000000..e8d77a4d --- /dev/null +++ b/app/models/reference_value.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class ReferenceValue < ApplicationRecord + belongs_to :data_type_identifier + has_many :reference_paths, inverse_of: :reference_value + has_many :node_parameters, inverse_of: :reference_value +end diff --git a/db/migrate/20250526124346_create_flows.rb b/db/migrate/20250526124346_create_flows.rb new file mode 100644 index 00000000..7bbae6b0 --- /dev/null +++ b/db/migrate/20250526124346_create_flows.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +class CreateFlows < Code0::ZeroTrack::Database::Migration[1.0] + def change + create_table :reference_values do |t| + t.references :data_type_identifier, null: false, foreign_key: { to_table: :data_type_identifiers, + on_delete: :restrict } + t.integer :primary_level, null: false + t.integer :secondary_level, null: false + t.integer :tertiary_level, null: true + + t.timestamps_with_timezone + end + + create_table :reference_paths do |t| + t.text :path, null: true + t.integer :array_index, null: true + + t.references :reference_value, null: false, foreign_key: { to_table: :reference_values, + on_delete: :cascade } + + t.timestamps_with_timezone + end + + create_table :node_functions do |t| + t.references :runtime_function, null: false, foreign_key: { to_table: :runtime_function_definitions, + on_delete: :cascade } + t.references :next_node, null: true, foreign_key: { to_table: :node_functions, on_delete: :cascade } + + t.timestamps_with_timezone + end + + create_table :node_parameters do |t| + t.references :runtime_parameter, null: false, foreign_key: { to_table: :runtime_parameter_definitions, + on_delete: :cascade } + + t.jsonb :literal_value, null: true + t.references :reference_value, null: true, foreign_key: { to_table: :reference_values, + on_delete: :restrict } + t.references :function_value, null: true, foreign_key: { to_table: :node_functions, + on_delete: :cascade } + + t.check_constraint '(num_nonnulls(literal_value, reference_value_id, function_value_id) = 1)', + name: check_constraint_name(:node_parameters, :value, :one_of) + + t.timestamps_with_timezone + end + + create_table :flows do |t| + t.references :project, null: false, foreign_key: { to_table: :namespace_projects, + on_delete: :cascade } + t.references :flow_type, null: false, foreign_key: { to_table: :flow_types, on_delete: :cascade } + + t.references :input_type_identifier, null: true, foreign_key: { to_table: :data_type_identifiers, + on_delete: :restrict } + t.references :return_type_identifier, null: true, foreign_key: { to_table: :data_type_identifiers, + on_delete: :restrict } + + t.references :starting_node, null: false, foreign_key: { to_table: :node_functions, on_delete: :restrict } + + t.timestamps_with_timezone + end + + add_reference :data_types, :flows, null: true, foreign_key: { to_table: :flows, on_delete: :restrict } + + create_table :flow_setting_definitions do |t| + t.text :identifier, null: false + t.text :key, null: false + + t.timestamps_with_timezone + end + + create_table :flow_settings do |t| + t.references :flow, null: true, foreign_key: { to_table: :flows, on_delete: :cascade } + + t.references :definition, null: false, foreign_key: { to_table: :flow_setting_definitions, on_delete: :cascade } + t.jsonb :object, null: false + + t.timestamps_with_timezone + end + end +end diff --git a/db/schema_migrations/20250526124346 b/db/schema_migrations/20250526124346 new file mode 100644 index 00000000..7e32302b --- /dev/null +++ b/db/schema_migrations/20250526124346 @@ -0,0 +1 @@ +730aa97154edcf9a3a3d039f8cd3a794b778600a343e4971c9c9d5412d8ab64a \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index a63f6d6e..01102245 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -169,6 +169,7 @@ CREATE TABLE data_types ( runtime_id bigint NOT NULL, removed_at timestamp with time zone, generic_keys text[] DEFAULT '{}'::text[] NOT NULL, + flows_id bigint, CONSTRAINT check_3a7198812e CHECK ((char_length(identifier) <= 50)) ); @@ -181,6 +182,41 @@ CREATE SEQUENCE data_types_id_seq ALTER SEQUENCE data_types_id_seq OWNED BY data_types.id; +CREATE TABLE flow_setting_definitions ( + id bigint NOT NULL, + identifier text NOT NULL, + key text NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE flow_setting_definitions_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE flow_setting_definitions_id_seq OWNED BY flow_setting_definitions.id; + +CREATE TABLE flow_settings ( + id bigint NOT NULL, + flow_id bigint, + definition_id bigint NOT NULL, + object jsonb NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE flow_settings_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE flow_settings_id_seq OWNED BY flow_settings.id; + CREATE TABLE flow_type_settings ( id bigint NOT NULL, flow_type_id bigint NOT NULL, @@ -222,6 +258,26 @@ CREATE SEQUENCE flow_types_id_seq ALTER SEQUENCE flow_types_id_seq OWNED BY flow_types.id; +CREATE TABLE flows ( + id bigint NOT NULL, + project_id bigint NOT NULL, + flow_type_id bigint NOT NULL, + input_type_identifier_id bigint, + return_type_identifier_id bigint, + starting_node_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE flows_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE flows_id_seq OWNED BY flows.id; + CREATE TABLE function_definitions ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, @@ -516,6 +572,41 @@ CREATE SEQUENCE namespaces_id_seq ALTER SEQUENCE namespaces_id_seq OWNED BY namespaces.id; +CREATE TABLE node_functions ( + id bigint NOT NULL, + runtime_function_id bigint NOT NULL, + next_node_id bigint, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE node_functions_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE node_functions_id_seq OWNED BY node_functions.id; + +CREATE TABLE node_parameters ( + id bigint NOT NULL, + runtime_parameter_id bigint NOT NULL, + literal_value jsonb, + reference_value_id bigint, + function_value_id bigint, + CONSTRAINT check_fdac0ea550 CHECK ((num_nonnulls(literal_value, reference_value_id, function_value_id) = 1)) +); + +CREATE SEQUENCE node_parameters_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE node_parameters_id_seq OWNED BY node_parameters.id; + CREATE TABLE organizations ( id bigint NOT NULL, name text NOT NULL, @@ -551,6 +642,43 @@ CREATE SEQUENCE parameter_definitions_id_seq ALTER SEQUENCE parameter_definitions_id_seq OWNED BY parameter_definitions.id; +CREATE TABLE reference_paths ( + id bigint NOT NULL, + path text, + array_index integer, + reference_value_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE reference_paths_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE reference_paths_id_seq OWNED BY reference_paths.id; + +CREATE TABLE reference_values ( + id bigint NOT NULL, + data_type_identifier_id bigint NOT NULL, + primary_level integer NOT NULL, + secondary_level integer NOT NULL, + tertiary_level integer, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE reference_values_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE reference_values_id_seq OWNED BY reference_values.id; + CREATE TABLE runtime_function_definition_error_types ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, @@ -735,10 +863,16 @@ ALTER TABLE ONLY data_type_rules ALTER COLUMN id SET DEFAULT nextval('data_type_ ALTER TABLE ONLY data_types ALTER COLUMN id SET DEFAULT nextval('data_types_id_seq'::regclass); +ALTER TABLE ONLY flow_setting_definitions ALTER COLUMN id SET DEFAULT nextval('flow_setting_definitions_id_seq'::regclass); + +ALTER TABLE ONLY flow_settings ALTER COLUMN id SET DEFAULT nextval('flow_settings_id_seq'::regclass); + ALTER TABLE ONLY flow_type_settings ALTER COLUMN id SET DEFAULT nextval('flow_type_settings_id_seq'::regclass); ALTER TABLE ONLY flow_types ALTER COLUMN id SET DEFAULT nextval('flow_types_id_seq'::regclass); +ALTER TABLE ONLY flows ALTER COLUMN id SET DEFAULT nextval('flows_id_seq'::regclass); + ALTER TABLE ONLY function_definitions ALTER COLUMN id SET DEFAULT nextval('function_definitions_id_seq'::regclass); ALTER TABLE ONLY function_generic_mappers ALTER COLUMN id SET DEFAULT nextval('function_generic_mappers_id_seq'::regclass); @@ -763,10 +897,18 @@ ALTER TABLE ONLY namespace_roles ALTER COLUMN id SET DEFAULT nextval('namespace_ ALTER TABLE ONLY namespaces ALTER COLUMN id SET DEFAULT nextval('namespaces_id_seq'::regclass); +ALTER TABLE ONLY node_functions ALTER COLUMN id SET DEFAULT nextval('node_functions_id_seq'::regclass); + +ALTER TABLE ONLY node_parameters ALTER COLUMN id SET DEFAULT nextval('node_parameters_id_seq'::regclass); + ALTER TABLE ONLY organizations ALTER COLUMN id SET DEFAULT nextval('organizations_id_seq'::regclass); ALTER TABLE ONLY parameter_definitions ALTER COLUMN id SET DEFAULT nextval('parameter_definitions_id_seq'::regclass); +ALTER TABLE ONLY reference_paths ALTER COLUMN id SET DEFAULT nextval('reference_paths_id_seq'::regclass); + +ALTER TABLE ONLY reference_values ALTER COLUMN id SET DEFAULT nextval('reference_values_id_seq'::regclass); + ALTER TABLE ONLY runtime_function_definition_error_types ALTER COLUMN id SET DEFAULT nextval('runtime_function_definition_error_types_id_seq'::regclass); ALTER TABLE ONLY runtime_function_definitions ALTER COLUMN id SET DEFAULT nextval('runtime_function_definitions_id_seq'::regclass); @@ -813,12 +955,21 @@ ALTER TABLE ONLY data_type_rules ALTER TABLE ONLY data_types ADD CONSTRAINT data_types_pkey PRIMARY KEY (id); +ALTER TABLE ONLY flow_setting_definitions + ADD CONSTRAINT flow_setting_definitions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY flow_settings + ADD CONSTRAINT flow_settings_pkey PRIMARY KEY (id); + ALTER TABLE ONLY flow_type_settings ADD CONSTRAINT flow_type_settings_pkey PRIMARY KEY (id); ALTER TABLE ONLY flow_types ADD CONSTRAINT flow_types_pkey PRIMARY KEY (id); +ALTER TABLE ONLY flows + ADD CONSTRAINT flows_pkey PRIMARY KEY (id); + ALTER TABLE ONLY function_definitions ADD CONSTRAINT function_definitions_pkey PRIMARY KEY (id); @@ -870,12 +1021,24 @@ ALTER TABLE ONLY namespace_roles ALTER TABLE ONLY namespaces ADD CONSTRAINT namespaces_pkey PRIMARY KEY (id); +ALTER TABLE ONLY node_functions + ADD CONSTRAINT node_functions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT node_parameters_pkey PRIMARY KEY (id); + ALTER TABLE ONLY organizations ADD CONSTRAINT organizations_pkey PRIMARY KEY (id); ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT parameter_definitions_pkey PRIMARY KEY (id); +ALTER TABLE ONLY reference_paths + ADD CONSTRAINT reference_paths_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY reference_values + ADD CONSTRAINT reference_values_pkey PRIMARY KEY (id); + ALTER TABLE ONLY runtime_function_definition_error_types ADD CONSTRAINT runtime_function_definition_error_types_pkey PRIMARY KEY (id); @@ -939,10 +1102,16 @@ CREATE INDEX index_data_type_identifiers_on_runtime_id ON data_type_identifiers CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id); +CREATE INDEX index_data_types_on_flows_id ON data_types USING btree (flows_id); + CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (parent_type_id); CREATE UNIQUE INDEX index_data_types_on_runtime_id_and_identifier ON data_types USING btree (runtime_id, identifier); +CREATE INDEX index_flow_settings_on_definition_id ON flow_settings USING btree (definition_id); + +CREATE INDEX index_flow_settings_on_flow_id ON flow_settings USING btree (flow_id); + CREATE INDEX index_flow_type_settings_on_data_type_id ON flow_type_settings USING btree (data_type_id); CREATE UNIQUE INDEX index_flow_type_settings_on_flow_type_id_and_identifier ON flow_type_settings USING btree (flow_type_id, identifier); @@ -953,6 +1122,16 @@ CREATE INDEX index_flow_types_on_return_type_id ON flow_types USING btree (retur CREATE UNIQUE INDEX index_flow_types_on_runtime_id_and_identifier ON flow_types USING btree (runtime_id, identifier); +CREATE INDEX index_flows_on_flow_type_id ON flows USING btree (flow_type_id); + +CREATE INDEX index_flows_on_input_type_identifier_id ON flows USING btree (input_type_identifier_id); + +CREATE INDEX index_flows_on_project_id ON flows USING btree (project_id); + +CREATE INDEX index_flows_on_return_type_identifier_id ON flows USING btree (return_type_identifier_id); + +CREATE INDEX index_flows_on_starting_node_id ON flows USING btree (starting_node_id); + CREATE INDEX index_function_definitions_on_return_type_id ON function_definitions USING btree (return_type_id); CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); @@ -1025,12 +1204,26 @@ CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON namesp CREATE UNIQUE INDEX index_namespaces_on_parent_id_and_parent_type ON namespaces USING btree (parent_id, parent_type); +CREATE INDEX index_node_functions_on_next_node_id ON node_functions USING btree (next_node_id); + +CREATE INDEX index_node_functions_on_runtime_function_id ON node_functions USING btree (runtime_function_id); + +CREATE INDEX index_node_parameters_on_function_value_id ON node_parameters USING btree (function_value_id); + +CREATE INDEX index_node_parameters_on_reference_value_id ON node_parameters USING btree (reference_value_id); + +CREATE INDEX index_node_parameters_on_runtime_parameter_id ON node_parameters USING btree (runtime_parameter_id); + CREATE UNIQUE INDEX "index_organizations_on_LOWER_name" ON organizations USING btree (lower(name)); CREATE INDEX index_parameter_definitions_on_data_type_id ON parameter_definitions USING btree (data_type_id); CREATE INDEX index_parameter_definitions_on_runtime_parameter_definition_id ON parameter_definitions USING btree (runtime_parameter_definition_id); +CREATE INDEX index_reference_paths_on_reference_value_id ON reference_paths USING btree (reference_value_id); + +CREATE INDEX index_reference_values_on_data_type_identifier_id ON reference_values USING btree (data_type_identifier_id); + CREATE INDEX index_runtime_function_definitions_on_return_type_id ON runtime_function_definitions USING btree (return_type_id); CREATE INDEX index_runtime_parameter_definitions_on_data_type_id ON runtime_parameter_definitions USING btree (data_type_id); @@ -1066,6 +1259,12 @@ ALTER TABLE ONLY runtime_function_definition_error_types ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_0c2eb746ef FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT fk_rails_0ff4fd0049 FOREIGN KEY (runtime_parameter_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; + +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_10bea7d7dc FOREIGN KEY (return_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_118c914ed0 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; @@ -1087,6 +1286,9 @@ ALTER TABLE ONLY generic_types ALTER TABLE ONLY generic_mappers ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_362b88d836 FOREIGN KEY (input_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -1108,6 +1310,9 @@ ALTER TABLE ONLY function_generic_mappers ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; +ALTER TABLE ONLY data_types + ADD CONSTRAINT fk_rails_490081f598 FOREIGN KEY (flows_id) REFERENCES flows(id) ON DELETE RESTRICT; + ALTER TABLE ONLY runtime_function_definitions ADD CONSTRAINT fk_rails_5161ff47e6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; @@ -1123,6 +1328,9 @@ ALTER TABLE ONLY namespace_member_roles ALTER TABLE ONLY namespace_role_project_assignments ADD CONSTRAINT fk_rails_623f8a5b72 FOREIGN KEY (role_id) REFERENCES namespace_roles(id); +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT fk_rails_646d4dbfbc FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; + ALTER TABLE ONLY data_type_identifiers ADD CONSTRAINT fk_rails_65151da1fb FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; @@ -1144,12 +1352,27 @@ ALTER TABLE ONLY namespace_role_abilities ALTER TABLE ONLY runtime_function_definitions ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT fk_rails_74b7800b37 FOREIGN KEY (function_value_id) REFERENCES node_functions(id) ON DELETE CASCADE; + ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_7de9ce6578 FOREIGN KEY (starting_node_id) REFERENCES node_functions(id) ON DELETE RESTRICT; + +ALTER TABLE ONLY node_functions + ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; + +ALTER TABLE ONLY flow_settings + ADD CONSTRAINT fk_rails_8c9f4f986e FOREIGN KEY (definition_id) REFERENCES flow_setting_definitions(id) ON DELETE CASCADE; + ALTER TABLE ONLY data_type_identifiers ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; +ALTER TABLE ONLY reference_paths + ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE CASCADE; + ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); @@ -1165,6 +1388,12 @@ ALTER TABLE ONLY namespace_members ALTER TABLE ONLY flow_type_settings ADD CONSTRAINT fk_rails_a1471d011d FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_ab927e0ecb FOREIGN KEY (project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; + +ALTER TABLE ONLY reference_values + ADD CONSTRAINT fk_rails_bb34a5d62c FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; @@ -1180,6 +1409,12 @@ ALTER TABLE ONLY parameter_definitions ALTER TABLE ONLY namespace_projects ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_d9ad50fe4b FOREIGN KEY (flow_type_id) REFERENCES flow_types(id) ON DELETE CASCADE; + +ALTER TABLE ONLY flow_settings + ADD CONSTRAINT fk_rails_da3b2fb3c5 FOREIGN KEY (flow_id) REFERENCES flows(id) ON DELETE CASCADE; + ALTER TABLE ONLY generic_mappers ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; @@ -1197,3 +1432,6 @@ ALTER TABLE ONLY audit_events ALTER TABLE ONLY flow_type_settings ADD CONSTRAINT fk_rails_f6af7d8edf FOREIGN KEY (flow_type_id) REFERENCES flow_types(id) ON DELETE CASCADE; + +ALTER TABLE ONLY node_functions + ADD CONSTRAINT fk_rails_fbc91a3407 FOREIGN KEY (next_node_id) REFERENCES node_functions(id) ON DELETE CASCADE; diff --git a/spec/factories/flow_setting_definitions.rb b/spec/factories/flow_setting_definitions.rb new file mode 100644 index 00000000..c67033bb --- /dev/null +++ b/spec/factories/flow_setting_definitions.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :flow_setting_definition do + identifier { 'example_setting' } + key { 'example_key' } + end +end diff --git a/spec/factories/flow_settings.rb b/spec/factories/flow_settings.rb new file mode 100644 index 00000000..df810336 --- /dev/null +++ b/spec/factories/flow_settings.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :flow_setting do + flow + definition factory: %i[flow_setting_definition] + object { { enabled: true } } + end +end diff --git a/spec/factories/flows.rb b/spec/factories/flows.rb new file mode 100644 index 00000000..6649a3bf --- /dev/null +++ b/spec/factories/flows.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :flow do + project factory: %i[namespace_project] + flow_type + starting_node factory: %i[node_function] + end +end diff --git a/spec/factories/node_functions.rb b/spec/factories/node_functions.rb new file mode 100644 index 00000000..5dd5bfa2 --- /dev/null +++ b/spec/factories/node_functions.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :node_function do + runtime_function factory: %i[runtime_function_definition] + next_node { nil } + node_parameters { [] } + end +end diff --git a/spec/factories/node_parameters.rb b/spec/factories/node_parameters.rb new file mode 100644 index 00000000..5cbf0a59 --- /dev/null +++ b/spec/factories/node_parameters.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :node_parameter do + runtime_parameter factory: %i[runtime_parameter_definition] + literal_value { 'value' } + reference_value { nil } + function_value { nil } + end +end diff --git a/spec/factories/reference_paths.rb b/spec/factories/reference_paths.rb new file mode 100644 index 00000000..b9c4c114 --- /dev/null +++ b/spec/factories/reference_paths.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :reference_path do + path { nil } + array_index { nil } + reference_value + end +end diff --git a/spec/factories/reference_values.rb b/spec/factories/reference_values.rb new file mode 100644 index 00000000..fb50a4ff --- /dev/null +++ b/spec/factories/reference_values.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :reference_value do + data_type_identifier + primary_level { 1 } + secondary_level { 1 } + tertiary_level { nil } + end +end diff --git a/spec/factories/runtime_parameter_definitions.rb b/spec/factories/runtime_parameter_definitions.rb index e571ecf4..499eca4f 100644 --- a/spec/factories/runtime_parameter_definitions.rb +++ b/spec/factories/runtime_parameter_definitions.rb @@ -5,7 +5,7 @@ factory :runtime_parameter_definition do runtime_function_definition - data_type { nil } + data_type factory: %i[data_type_identifier] runtime_name { generate(:runtime_parameter_definition_name) } end end diff --git a/spec/models/flow_setting_definition_spec.rb b/spec/models/flow_setting_definition_spec.rb new file mode 100644 index 00000000..687f48c4 --- /dev/null +++ b/spec/models/flow_setting_definition_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe FlowSettingDefinition do + subject { create(:flow_setting_definition) } + + describe 'associations' do + it { is_expected.to have_many(:flow_settings).inverse_of(:definition) } + end +end diff --git a/spec/models/flow_setting_spec.rb b/spec/models/flow_setting_spec.rb new file mode 100644 index 00000000..0f0512c0 --- /dev/null +++ b/spec/models/flow_setting_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe FlowSetting do + subject { create(:flow_setting) } + + describe 'associations' do + it { is_expected.to belong_to(:flow).optional } + it { is_expected.to belong_to(:definition).class_name('FlowSettingDefinition') } + end +end diff --git a/spec/models/flow_spec.rb b/spec/models/flow_spec.rb new file mode 100644 index 00000000..0942e79b --- /dev/null +++ b/spec/models/flow_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Flow do + subject { create(:flow) } + + describe 'associations' do + it { is_expected.to belong_to(:project).class_name('NamespaceProject') } + it { is_expected.to belong_to(:flow_type) } + it { is_expected.to belong_to(:starting_node).class_name('NodeFunction') } + end +end diff --git a/spec/models/node_function_spec.rb b/spec/models/node_function_spec.rb new file mode 100644 index 00000000..fc349531 --- /dev/null +++ b/spec/models/node_function_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe NodeFunction do + subject { create(:node_function) } + + describe 'associations' do + it { is_expected.to belong_to(:runtime_function).class_name('RuntimeFunctionDefinition') } + it { is_expected.to belong_to(:next_node).class_name('NodeFunction').optional } + + it { is_expected.to have_many(:node_parameters).inverse_of(:function_value) } + end +end diff --git a/spec/models/node_parameter_spec.rb b/spec/models/node_parameter_spec.rb new file mode 100644 index 00000000..000ead41 --- /dev/null +++ b/spec/models/node_parameter_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe NodeParameter do + subject do + create(:node_parameter, + runtime_parameter: create(:runtime_parameter_definition, + data_type: create(:data_type_identifier, data_type: create(:data_type)))) + end + + describe 'associations' do + it { is_expected.to belong_to(:runtime_parameter).class_name('RuntimeParameterDefinition') } + it { is_expected.to belong_to(:reference_value).optional } + it { is_expected.to belong_to(:function_value).class_name('NodeFunction').optional } + end + + describe 'validations' do + it 'validates only one of the value fields is present' do + param = build(:node_parameter, literal_value: nil, reference_value: nil, function_value: nil, + runtime_parameter: create(:runtime_parameter_definition, + data_type: create(:data_type_identifier, + data_type: create(:data_type)))) + expect(param).not_to be_valid + expect(param.errors[:base]) + .to include('Exactly one of literal_value, reference_value, or function_value must be present') + end + end +end diff --git a/spec/models/reference_path_spec.rb b/spec/models/reference_path_spec.rb new file mode 100644 index 00000000..87e52658 --- /dev/null +++ b/spec/models/reference_path_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ReferencePath do + subject do + create(:reference_path, + reference_value: create(:reference_value, + data_type_identifier: create(:data_type_identifier, data_type: create(:data_type)))) + end + + describe 'associations' do + it { is_expected.to belong_to(:reference_value) } + end +end diff --git a/spec/models/reference_value_spec.rb b/spec/models/reference_value_spec.rb new file mode 100644 index 00000000..944dc820 --- /dev/null +++ b/spec/models/reference_value_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ReferenceValue do + subject do + create(:reference_value, data_type_identifier: create(:data_type_identifier, data_type: create(:data_type))) + end + + describe 'associations' do + it { is_expected.to belong_to(:data_type_identifier) } + it { is_expected.to have_many(:reference_paths) } + end +end From df1ca1d4bc8149d5b83f16a1dbfbca07c49588f9 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 19:20:29 +0200 Subject: [PATCH 17/54] Add flows association to NamespaceProject and update schema --- app/models/namespace_project.rb | 1 + db/structure.sql | 2 ++ spec/models/namespace_project_spec.rb | 1 + 3 files changed, 4 insertions(+) diff --git a/app/models/namespace_project.rb b/app/models/namespace_project.rb index e0fce59e..f94e2436 100644 --- a/app/models/namespace_project.rb +++ b/app/models/namespace_project.rb @@ -12,6 +12,7 @@ class NamespaceProject < ApplicationRecord has_many :assigned_roles, class_name: 'NamespaceRole', through: :role_assignments, inverse_of: :assigned_projects, source: :project + has_many :flows, class_name: 'Flow', inverse_of: :project validates :name, presence: true, length: { minimum: 3, maximum: 50 }, diff --git a/db/structure.sql b/db/structure.sql index 01102245..41a2211f 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -595,6 +595,8 @@ CREATE TABLE node_parameters ( literal_value jsonb, reference_value_id bigint, function_value_id bigint, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, CONSTRAINT check_fdac0ea550 CHECK ((num_nonnulls(literal_value, reference_value_id, function_value_id) = 1)) ); diff --git a/spec/models/namespace_project_spec.rb b/spec/models/namespace_project_spec.rb index 9ced5d81..1e5210e7 100644 --- a/spec/models/namespace_project_spec.rb +++ b/spec/models/namespace_project_spec.rb @@ -14,6 +14,7 @@ .through(:role_assignments) .source(:project) .inverse_of(:assigned_projects) + is_expected.to have_many(:flows).class_name('Flow').inverse_of(:project) end end From 89cdb7e2285fd061316f8f9a044254890ef79eb5 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 20:17:51 +0200 Subject: [PATCH 18/54] Create create/update/delete services for flows --- app/models/audit_event.rb | 1 + app/policies/namespace_project_policy.rb | 1 + .../projects/flows/create_service.rb | 56 ++++++++++++++++++ .../projects/flows/delete_service.rb | 46 +++++++++++++++ .../projects/flows/update_service.rb | 57 +++++++++++++++++++ .../projects/flows/validation_service.rb | 22 +++++++ db/migrate/20250526124346_create_flows.rb | 8 +-- 7 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 app/services/namespaces/projects/flows/create_service.rb create mode 100644 app/services/namespaces/projects/flows/delete_service.rb create mode 100644 app/services/namespaces/projects/flows/update_service.rb create mode 100644 app/services/namespaces/projects/flows/validation_service.rb diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb index bd16822b..20554456 100644 --- a/app/models/audit_event.rb +++ b/app/models/audit_event.rb @@ -32,6 +32,7 @@ class AuditEvent < ApplicationRecord user_identity_unlinked: 28, attachment_updated: 29, project_runtimes_assigned: 30, + flow_created: 31, }.with_indifferent_access # rubocop:disable Lint/StructNewOverride diff --git a/app/policies/namespace_project_policy.rb b/app/policies/namespace_project_policy.rb index 58640d9a..c6a6bc20 100644 --- a/app/policies/namespace_project_policy.rb +++ b/app/policies/namespace_project_policy.rb @@ -13,4 +13,5 @@ class NamespaceProjectPolicy < BasePolicy customizable_permission :read_namespace_project customizable_permission :update_namespace_project customizable_permission :delete_namespace_project + customizable_permission :create_flows end diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb new file mode 100644 index 00000000..de778b8d --- /dev/null +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + class CreateService + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :namespace_project, :params + + def initialize(current_authentication, namespace_project:, **params) + @current_authentication = current_authentication + @namespace_project = namespace_project + @params = params + end + + def execute + unless Ability.allowed?(current_authentication, :create_flows, namespace_project) + return ServiceResponse.error(message: 'Missing permission', payload: :missing_permission) + end + + transactional do |t| + flow = Flow.create(project: namespace_project, **params) + unless flow.persisted? + t.rollback_and_return! ServiceResponse.error( + message: 'Failed to create flow', + payload: flow.errors + ) + end + + res = ValidationService.new(current_authentication, flow).execute + + if res.error? + t.rollback_and_return! ServiceResponse.error( + message: 'Flow validation failed', + payload: res.payload + ) + end + + AuditService.audit( + :flow_created, + author_id: current_authentication.user.id, + entity: namespace_project, + target: flow, + details: { + **params, + } + ) + + ServiceResponse.success(message: 'Created new project', payload: flow) + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/delete_service.rb b/app/services/namespaces/projects/flows/delete_service.rb new file mode 100644 index 00000000..adfbfd9b --- /dev/null +++ b/app/services/namespaces/projects/flows/delete_service.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + class CreateService + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow + + def initialize(current_authentication, flow:) + @current_authentication = current_authentication + @flow = flow + end + + def execute + unless Ability.allowed?(current_authentication, :delete_flows, namespace_project) + return ServiceResponse.error(message: 'Missing permission', payload: :missing_permission) + end + + transactional do |t| + flow = flow.delete + if flow.persisted? + t.rollback_and_return! ServiceResponse.error( + message: 'Failed to delete flow', + payload: flow.errors + ) + end + + AuditService.audit( + :flow_deleted, + author_id: current_authentication.user.id, + entity: namespace_project, + target: flow, + details: { + **flow.attributes + } + ) + + ServiceResponse.success(message: 'Created new project', payload: flow) + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/update_service.rb b/app/services/namespaces/projects/flows/update_service.rb new file mode 100644 index 00000000..3edfaa7e --- /dev/null +++ b/app/services/namespaces/projects/flows/update_service.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + class CreateService + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :old_flow, :new_flow + + def initialize(current_authentication, old_flow:, new_flow:) + @current_authentication = current_authentication + @old_flow = old_flow + @new_flow = new_flow + end + + def execute + unless Ability.allowed?(current_authentication, :delete_flows, namespace_project) + return ServiceResponse.error(message: 'Missing permission', payload: :missing_permission) + end + + transactional do |t| + flow.update(new_flow.attributes.except('id', 'created_at', 'updated_at')) + if flow.persisted? + t.rollback_and_return! ServiceResponse.error( + message: 'Failed to delete flow', + payload: flow.errors + ) + end + + res = ValidationService.new(current_authentication, flow).execute + + if res.error? + t.rollback_and_return! ServiceResponse.error( + message: 'Flow validation failed', + payload: res.payload + ) + end + + AuditService.audit( + :flow_updated, + author_id: current_authentication.user.id, + entity: namespace_project, + target: flow, + details: { + old_flow: old_flow.attributes, + new_flow: new_flow.attributes + } + ) + + ServiceResponse.success(message: 'Created new project', payload: flow) + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation_service.rb b/app/services/namespaces/projects/flows/validation_service.rb new file mode 100644 index 00000000..53f40693 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation_service.rb @@ -0,0 +1,22 @@ +module Namespaces + module Projects + module Flows + class ValidationService + + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow + + def initialize(current_authentication, flow) + @current_authentication = current_authentication + @flow = flow + end + + def execute + # TODO: Implement validation logic for the flow + ServiceResponse.success(message: 'Validation service executed successfully', payload: flow) + end + end + end + end +end diff --git a/db/migrate/20250526124346_create_flows.rb b/db/migrate/20250526124346_create_flows.rb index 7bbae6b0..d1749a94 100644 --- a/db/migrate/20250526124346_create_flows.rb +++ b/db/migrate/20250526124346_create_flows.rb @@ -17,15 +17,15 @@ def change t.integer :array_index, null: true t.references :reference_value, null: false, foreign_key: { to_table: :reference_values, - on_delete: :cascade } + on_delete: :restrict } t.timestamps_with_timezone end create_table :node_functions do |t| t.references :runtime_function, null: false, foreign_key: { to_table: :runtime_function_definitions, - on_delete: :cascade } - t.references :next_node, null: true, foreign_key: { to_table: :node_functions, on_delete: :cascade } + on_delete: :restrict } + t.references :next_node, null: true, foreign_key: { to_table: :node_functions, on_delete: :restrict } t.timestamps_with_timezone end @@ -38,7 +38,7 @@ def change t.references :reference_value, null: true, foreign_key: { to_table: :reference_values, on_delete: :restrict } t.references :function_value, null: true, foreign_key: { to_table: :node_functions, - on_delete: :cascade } + on_delete: :restrict } t.check_constraint '(num_nonnulls(literal_value, reference_value_id, function_value_id) = 1)', name: check_constraint_name(:node_parameters, :value, :one_of) From aeeeca61af64410573376c3a7f8ec17294e13c5b Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 20:19:40 +0200 Subject: [PATCH 19/54] Recompile structure.sql --- db/structure.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index 41a2211f..2cddc276 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1355,7 +1355,7 @@ ALTER TABLE ONLY runtime_function_definitions ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY node_parameters - ADD CONSTRAINT fk_rails_74b7800b37 FOREIGN KEY (function_value_id) REFERENCES node_functions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_74b7800b37 FOREIGN KEY (function_value_id) REFERENCES node_functions(id) ON DELETE RESTRICT; ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; @@ -1364,7 +1364,7 @@ ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_7de9ce6578 FOREIGN KEY (starting_node_id) REFERENCES node_functions(id) ON DELETE RESTRICT; ALTER TABLE ONLY node_functions - ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY flow_settings ADD CONSTRAINT fk_rails_8c9f4f986e FOREIGN KEY (definition_id) REFERENCES flow_setting_definitions(id) ON DELETE CASCADE; @@ -1373,7 +1373,7 @@ ALTER TABLE ONLY data_type_identifiers ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY reference_paths - ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); @@ -1436,4 +1436,4 @@ ALTER TABLE ONLY flow_type_settings ADD CONSTRAINT fk_rails_f6af7d8edf FOREIGN KEY (flow_type_id) REFERENCES flow_types(id) ON DELETE CASCADE; ALTER TABLE ONLY node_functions - ADD CONSTRAINT fk_rails_fbc91a3407 FOREIGN KEY (next_node_id) REFERENCES node_functions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_fbc91a3407 FOREIGN KEY (next_node_id) REFERENCES node_functions(id) ON DELETE RESTRICT; From ab23a96a614204500e50df9de947a9a89e04c11d Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 20:33:13 +0200 Subject: [PATCH 20/54] Fix rubocop vulnerabilities --- app/services/namespaces/projects/flows/delete_service.rb | 2 +- app/services/namespaces/projects/flows/update_service.rb | 2 +- app/services/namespaces/projects/flows/validation_service.rb | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/services/namespaces/projects/flows/delete_service.rb b/app/services/namespaces/projects/flows/delete_service.rb index adfbfd9b..aa268693 100644 --- a/app/services/namespaces/projects/flows/delete_service.rb +++ b/app/services/namespaces/projects/flows/delete_service.rb @@ -33,7 +33,7 @@ def execute entity: namespace_project, target: flow, details: { - **flow.attributes + **flow.attributes, } ) diff --git a/app/services/namespaces/projects/flows/update_service.rb b/app/services/namespaces/projects/flows/update_service.rb index 3edfaa7e..7e4bd516 100644 --- a/app/services/namespaces/projects/flows/update_service.rb +++ b/app/services/namespaces/projects/flows/update_service.rb @@ -44,7 +44,7 @@ def execute target: flow, details: { old_flow: old_flow.attributes, - new_flow: new_flow.attributes + new_flow: new_flow.attributes, } ) diff --git a/app/services/namespaces/projects/flows/validation_service.rb b/app/services/namespaces/projects/flows/validation_service.rb index 53f40693..98205347 100644 --- a/app/services/namespaces/projects/flows/validation_service.rb +++ b/app/services/namespaces/projects/flows/validation_service.rb @@ -1,8 +1,9 @@ +# frozen_string_literal: true + module Namespaces module Projects module Flows class ValidationService - include Sagittarius::Database::Transactional attr_reader :current_authentication, :flow From 2f904c9dbc7e57cb828b512e6722d03026d01155 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Tue, 27 May 2025 21:27:38 +0200 Subject: [PATCH 21/54] Add flow update and delete services specs --- app/models/audit_event.rb | 2 + app/models/namespace_role_ability.rb | 3 + app/policies/namespace_project_policy.rb | 2 + .../projects/flows/create_service.rb | 6 +- .../projects/flows/delete_service.rb | 13 ++-- .../projects/flows/update_service.rb | 29 +++---- db/structure.sql | 21 ++--- .../projects/flows/create_service_spec.rb | 64 +++++++++++++++ .../projects/flows/delete_service_spec.rb | 62 +++++++++++++++ .../projects/flows/update_service_spec.rb | 78 +++++++++++++++++++ .../projects/flows/validation_service_spec.rb | 22 ++++++ 11 files changed, 270 insertions(+), 32 deletions(-) create mode 100644 spec/services/namespaces/projects/flows/create_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/delete_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/update_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation_service_spec.rb diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb index 20554456..865c9d62 100644 --- a/app/models/audit_event.rb +++ b/app/models/audit_event.rb @@ -33,6 +33,8 @@ class AuditEvent < ApplicationRecord attachment_updated: 29, project_runtimes_assigned: 30, flow_created: 31, + flow_updated: 32, + flow_deleted: 33, }.with_indifferent_access # rubocop:disable Lint/StructNewOverride diff --git a/app/models/namespace_role_ability.rb b/app/models/namespace_role_ability.rb index 80c920e8..650d9dd4 100644 --- a/app/models/namespace_role_ability.rb +++ b/app/models/namespace_role_ability.rb @@ -25,6 +25,9 @@ class NamespaceRoleAbility < ApplicationRecord rotate_runtime_token: { db: 21, description: 'Allows to regenerate a runtime token' }, assign_role_projects: { db: 22, description: 'Allows to change the assigned projects of a namespace role' }, assign_project_runtimes: { db: 23, description: 'Allows to assign runtimes to a project in the namespace' }, + create_flows: { db: 24, description: 'Allows to create flows in the namespace' }, + update_flows: { db: 25, description: 'Allows to update flows in the namespace' }, + delete_flows: { db: 26, description: 'Allows to delete flows in the namespace' }, }.with_indifferent_access enum :ability, ABILITIES.transform_values { |v| v[:db] }, prefix: :can diff --git a/app/policies/namespace_project_policy.rb b/app/policies/namespace_project_policy.rb index c6a6bc20..dea09a86 100644 --- a/app/policies/namespace_project_policy.rb +++ b/app/policies/namespace_project_policy.rb @@ -14,4 +14,6 @@ class NamespaceProjectPolicy < BasePolicy customizable_permission :update_namespace_project customizable_permission :delete_namespace_project customizable_permission :create_flows + customizable_permission :update_flows + customizable_permission :delete_flows end diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb index de778b8d..cfe75d5e 100644 --- a/app/services/namespaces/projects/flows/create_service.rb +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -40,10 +40,10 @@ def execute AuditService.audit( :flow_created, author_id: current_authentication.user.id, - entity: namespace_project, - target: flow, + entity: flow, + target: namespace_project, details: { - **params, + **flow.attributes.except('created_at', 'updated_at'), } ) diff --git a/app/services/namespaces/projects/flows/delete_service.rb b/app/services/namespaces/projects/flows/delete_service.rb index aa268693..1a5c36a2 100644 --- a/app/services/namespaces/projects/flows/delete_service.rb +++ b/app/services/namespaces/projects/flows/delete_service.rb @@ -3,7 +3,7 @@ module Namespaces module Projects module Flows - class CreateService + class DeleteService include Sagittarius::Database::Transactional attr_reader :current_authentication, :flow @@ -14,12 +14,13 @@ def initialize(current_authentication, flow:) end def execute - unless Ability.allowed?(current_authentication, :delete_flows, namespace_project) + unless Ability.allowed?(current_authentication, :delete_flows, flow.project) return ServiceResponse.error(message: 'Missing permission', payload: :missing_permission) end transactional do |t| - flow = flow.delete + flow.delete + if flow.persisted? t.rollback_and_return! ServiceResponse.error( message: 'Failed to delete flow', @@ -30,10 +31,10 @@ def execute AuditService.audit( :flow_deleted, author_id: current_authentication.user.id, - entity: namespace_project, - target: flow, + entity: flow, + target: flow.project, details: { - **flow.attributes, + **flow.attributes.except('created_at', 'updated_at'), } ) diff --git a/app/services/namespaces/projects/flows/update_service.rb b/app/services/namespaces/projects/flows/update_service.rb index 7e4bd516..2f35e77b 100644 --- a/app/services/namespaces/projects/flows/update_service.rb +++ b/app/services/namespaces/projects/flows/update_service.rb @@ -3,27 +3,30 @@ module Namespaces module Projects module Flows - class CreateService + class UpdateService include Sagittarius::Database::Transactional - attr_reader :current_authentication, :old_flow, :new_flow + attr_reader :current_authentication, :flow, :params - def initialize(current_authentication, old_flow:, new_flow:) + def initialize(current_authentication, flow:, **params) @current_authentication = current_authentication - @old_flow = old_flow - @new_flow = new_flow + @flow = flow + @params = params end def execute - unless Ability.allowed?(current_authentication, :delete_flows, namespace_project) + unless Ability.allowed?(current_authentication, :update_flows, flow.project) return ServiceResponse.error(message: 'Missing permission', payload: :missing_permission) end transactional do |t| - flow.update(new_flow.attributes.except('id', 'created_at', 'updated_at')) - if flow.persisted? + old_flow_attributes = flow.attributes.except('created_at', 'updated_at') + + success = flow.update(params) + + unless success t.rollback_and_return! ServiceResponse.error( - message: 'Failed to delete flow', + message: 'Failed to update flow', payload: flow.errors ) end @@ -40,11 +43,11 @@ def execute AuditService.audit( :flow_updated, author_id: current_authentication.user.id, - entity: namespace_project, - target: flow, + entity: flow, + target: flow.project, details: { - old_flow: old_flow.attributes, - new_flow: new_flow.attributes, + new_flow: flow.attributes.except('created_at', 'updated_at'), + old_flow: old_flow_attributes, } ) diff --git a/db/structure.sql b/db/structure.sql index 2cddc276..64eac259 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -748,6 +748,7 @@ CREATE TABLE runtimes ( namespace_id bigint, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, + status integer DEFAULT 0 NOT NULL, CONSTRAINT check_090cd49d30 CHECK ((char_length(name) <= 50)), CONSTRAINT check_f3c2ba8db3 CHECK ((char_length(description) <= 500)) ); @@ -1274,19 +1275,19 @@ ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_362b88d836 FOREIGN KEY (input_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1307,7 +1308,7 @@ ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1370,7 +1371,7 @@ ALTER TABLE ONLY flow_settings ADD CONSTRAINT fk_rails_8c9f4f986e FOREIGN KEY (definition_id) REFERENCES flow_setting_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY reference_paths ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; @@ -1379,7 +1380,7 @@ ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY user_sessions ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -1403,7 +1404,7 @@ ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1418,7 +1419,7 @@ ALTER TABLE ONLY flow_settings ADD CONSTRAINT fk_rails_da3b2fb3c5 FOREIGN KEY (flow_id) REFERENCES flows(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1427,7 +1428,7 @@ ALTER TABLE ONLY runtimes ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY audit_events ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; diff --git a/spec/services/namespaces/projects/flows/create_service_spec.rb b/spec/services/namespaces/projects/flows/create_service_spec.rb new file mode 100644 index 00000000..2caa9f22 --- /dev/null +++ b/spec/services/namespaces/projects/flows/create_service_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::CreateService do + subject(:service_response) do + described_class.new(create_authentication(current_user), namespace_project: namespace_project, **params).execute + end + + let(:namespace_project) { create(:namespace_project) } + let(:starting_node) { create(:node_function) } + let(:params) { { project: namespace_project, flow_type: create(:flow_type), starting_node: starting_node } } + + shared_examples 'does not create' do + it { is_expected.to be_error } + + it 'does not create flow' do + expect { service_response }.not_to change { Flow.count } + end + + it { expect { service_response }.not_to create_audit_event } + end + + context 'when user does not exist' do + let(:current_user) { nil } + + it_behaves_like 'does not create' + end + + context 'when params are invalid' do + let(:current_user) { create(:user) } + + context 'when starting node is nil' do + let(:params) { { project: namespace_project, flow_type: create(:flow_type), starting_node: nil } } + + it_behaves_like 'does not create' + end + end + + context 'when user and params are valid' do + let(:current_user) { create(:user) } + + before do + stub_allowed_ability(NamespaceProjectPolicy, :create_flows, user: current_user, subject: namespace_project) + end + + it { is_expected.to be_success } + it { expect(service_response.payload.reload).to be_valid } + + it do + is_expected.to create_audit_event( + :flow_created, + author_id: current_user.id, + entity_type: 'Flow', + entity_id: service_response.payload.id, + details: { + **service_response.payload.attributes.except('created_at', 'updated_at'), + }, + target_id: namespace_project.id, + target_type: 'NamespaceProject' + ) + end + end +end diff --git a/spec/services/namespaces/projects/flows/delete_service_spec.rb b/spec/services/namespaces/projects/flows/delete_service_spec.rb new file mode 100644 index 00000000..a8ba4d16 --- /dev/null +++ b/spec/services/namespaces/projects/flows/delete_service_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::DeleteService do + subject(:service_response) { described_class.new(create_authentication(current_user), flow: flow).execute } + + let(:namespace_project) { create(:namespace_project) } + let(:starting_node) { create(:node_function) } + let(:flow_type) { create(:flow_type) } + let!(:flow) { create(:flow, project: namespace_project, flow_type: flow_type, starting_node: starting_node) } + + shared_examples 'does not delete' do + it { is_expected.to be_error } + + it 'does not delete flow' do + expect { service_response }.not_to change { Flow.count } + end + + it { expect { service_response }.not_to create_audit_event } + end + + context 'when user does not exist' do + let(:current_user) { nil } + + it_behaves_like 'does not delete' + end + + context 'when user does not have permission' do + let(:current_user) { create(:user) } + + it_behaves_like 'does not delete' + end + + context 'when user has permission' do + let(:current_user) { create(:user) } + + before do + stub_allowed_ability(NamespaceProjectPolicy, :delete_flows, user: current_user, subject: namespace_project) + end + + it { is_expected.to be_success } + + it 'deletes the flow' do + expect { service_response }.to change { Flow.count }.by(-1) + end + + it do + is_expected.to create_audit_event( + :flow_deleted, + author_id: current_user.id, + entity_type: 'Flow', + entity_id: flow.id, + details: { + **flow.attributes.except('created_at', 'updated_at'), + }, + target_id: flow.project.id, + target_type: 'NamespaceProject' + ) + end + end +end diff --git a/spec/services/namespaces/projects/flows/update_service_spec.rb b/spec/services/namespaces/projects/flows/update_service_spec.rb new file mode 100644 index 00000000..03a4a3ff --- /dev/null +++ b/spec/services/namespaces/projects/flows/update_service_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::UpdateService do + subject(:service_response) { described_class.new(create_authentication(current_user), flow: flow, **params).execute } + + let(:namespace_project) { create(:namespace_project) } + let(:starting_node) { create(:node_function) } + let(:flow_type) { create(:flow_type) } + let(:flow) { create(:flow, project: namespace_project, flow_type: flow_type, starting_node: starting_node) } + let(:new_starting_node) { create(:node_function) } + let(:params) { { starting_node: new_starting_node } } + + shared_examples 'does not update' do + it { is_expected.to be_error } + + it 'does not update flow' do + expect { service_response }.not_to change { flow.reload.starting_node_id } + end + + it { expect { service_response }.not_to create_audit_event } + end + + context 'when user does not exist' do + let(:current_user) { nil } + + it_behaves_like 'does not update' + end + + context 'when user does not have permission' do + let(:current_user) { create(:user) } + + it_behaves_like 'does not update' + end + + context 'when params are invalid' do + let(:current_user) { create(:user) } + let(:params) { { starting_node: nil } } # Invalid params + + before do + stub_allowed_ability(NamespaceProjectPolicy, :update_flows, user: current_user, subject: namespace_project) + end + + it_behaves_like 'does not update' + end + + context 'when user has permission and params are valid' do + let(:current_user) { create(:user) } + + before do + stub_allowed_ability(NamespaceProjectPolicy, :update_flows, user: current_user, subject: namespace_project) + end + + it { is_expected.to be_success } + + it 'updates the flow' do + expect { service_response }.to change { flow.reload.starting_node_id }.to(new_starting_node.id) + end + + it do + old_attributes = flow.attributes.except('created_at', 'updated_at') + + is_expected.to create_audit_event( + :flow_updated, + author_id: current_user.id, + entity_type: 'Flow', + entity_id: flow.id, + details: { + old_flow: old_attributes, + new_flow: flow.reload.attributes.except('created_at', 'updated_at'), + }, + target_id: flow.project.id, + target_type: 'NamespaceProject' + ) + end + end +end diff --git a/spec/services/namespaces/projects/flows/validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation_service_spec.rb new file mode 100644 index 00000000..7d54047d --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation_service_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::ValidationService do + subject(:service_response) { described_class.new(create_authentication(current_user), flow).execute } + + let(:namespace_project) { create(:namespace_project) } + let(:starting_node) { create(:node_function) } + let(:flow_type) { create(:flow_type) } + let(:flow) { create(:flow, project: namespace_project, flow_type: flow_type, starting_node: starting_node) } + + context 'when validation succeeds' do + let(:current_user) { create(:user) } + + it { is_expected.to be_success } + it { expect(service_response.payload).to eq flow } + it { expect(service_response.message).to eq 'Validation service executed successfully' } + end + + # Add more test cases when validation logic is implemented in ValidationService +end From b2d9b4b249fe453a1e3adf0b9f1578818fb831e9 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Tue, 27 May 2025 23:33:59 +0200 Subject: [PATCH 22/54] Refactor generic type and mapper associations (tucana 0.0.28); update to_grpc methods --- Gemfile | 2 +- Gemfile.lock | 4 +- app/grpc/flow_handler.rb | 12 +++++ app/models/data_type.rb | 5 +- app/models/data_type_identifier.rb | 15 ++++-- app/models/flow.rb | 15 +++++- app/models/flow_setting.rb | 7 +++ app/models/flow_setting_definition.rb | 7 +++ app/models/function_generic_mapper.rb | 12 +---- app/models/generic_mapper.rb | 17 +++---- app/models/generic_type.rb | 10 +++- app/models/node_function.rb | 9 ++++ app/models/node_parameter.rb | 17 +++++++ app/models/reference_path.rb | 7 +++ app/models/reference_value.rb | 10 ++++ .../update_service.rb | 22 ++++---- .../20250525192143_implement_generics.rb | 51 ++++++++----------- db/structure.sql | 34 ++++++------- docs/graphql/enum/namespaceroleability.md | 3 ++ spec/factories/function_generic_mappers.rb | 3 +- spec/factories/generic_mappers.rb | 3 +- spec/factories/generic_types.rb | 2 +- spec/models/data_type_identifier_spec.rb | 9 ++-- spec/models/function_generic_mapper_spec.rb | 29 +---------- spec/models/generic_mapper_spec.rb | 39 +------------- spec/models/generic_type_spec.rb | 13 +---- ...untime_function_definition_service_spec.rb | 29 ++++------- 27 files changed, 185 insertions(+), 201 deletions(-) diff --git a/Gemfile b/Gemfile index fa653e3a..713ce561 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.27' +gem 'tucana', '0.0.28' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 729121d8..c08fc171 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -356,7 +356,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.27) + tucana (0.0.28) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -409,7 +409,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.27) + tucana (= 0.0.28) tzinfo-data RUBY VERSION diff --git a/app/grpc/flow_handler.rb b/app/grpc/flow_handler.rb index 86a58029..aa40708a 100644 --- a/app/grpc/flow_handler.rb +++ b/app/grpc/flow_handler.rb @@ -10,6 +10,18 @@ def self.update_started(runtime_id) runtime = Runtime.find(runtime_id) runtime.connected! runtime.save + + flows = NamespaceProject.where(id: runtime.projects.ids).flat_map do |project| + project.flows.map(&:to_grpc) + end + + send_update( + Tucana::Sagittarius::FlowResponse.new( + flows: Tucana::Shared::Flows.new( + flows: flows + ) + ) + ) end def self.update_died(runtime_id) diff --git a/app/models/data_type.rb b/app/models/data_type.rb index e162af9f..8cc41553 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -7,8 +7,8 @@ class DataType < ApplicationRecord object: 3, datatype: 4, array: 5, - generic: 6, - function: 7, + error: 6, + node: 7, }.with_indifferent_access enum :variant, VARIANTS, prefix: :variant @@ -20,6 +20,7 @@ class DataType < ApplicationRecord has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :rules, class_name: 'DataTypeRule', inverse_of: :data_type has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :data_type + has_many :generic_types, class_name: 'GenericType', inverse_of: :data_type validates :variant, presence: true, inclusion: { diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 8b28aaad..4daa8ac9 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -2,15 +2,22 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers - belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier + belongs_to :generic_type, optional: true, inverse_of: :data_type_identifiers belongs_to :runtime, inverse_of: :data_type_identifiers - has_many :generic_types, inverse_of: :data_type_identifier - has_many :generic_mappers, inverse_of: :data_type_identifier - has_many :function_generic_mappers, class_name: 'GenericMapper', inverse_of: :data_type_identifier + has_many :generic_mappers, inverse_of: :source + has_many :function_generic_mappers, class_name: 'FunctionGenericMapper', inverse_of: :source validate :exactly_one_of_generic_key_data_type_id_generic_type_id + def to_grpc + Tucana::Shared::DataTypeIdentifier.new( + data_type_identifier: data_type.identifier, + generic_type: generic_type&.to_grpc, + generic_key: generic_key + ) + end + private def exactly_one_of_generic_key_data_type_id_generic_type_id diff --git a/app/models/flow.rb b/app/models/flow.rb index 969d5e57..505bbbe7 100644 --- a/app/models/flow.rb +++ b/app/models/flow.rb @@ -7,5 +7,18 @@ class Flow < ApplicationRecord belongs_to :return_type_identifier, class_name: 'DataTypeIdentifier', optional: true belongs_to :starting_node, class_name: 'NodeFunction' - has_many :flow_settings, dependent: :destroy + has_many :flow_settings + + def to_grpc + Tucana::Shared::Flow.new( + id: id, + project_id: project.id, + flow_type_id: flow_type.identifier, + data_types: [], # TODO + input_type_id: input_type_identifier&.identifier, + return_type_id: return_type_identifier&.identifier, + settings: flow_settings.map(&:to_grpc), + starting_node: starting_node.to_grpc + ) + end end diff --git a/app/models/flow_setting.rb b/app/models/flow_setting.rb index 0b3311c0..58142564 100644 --- a/app/models/flow_setting.rb +++ b/app/models/flow_setting.rb @@ -3,4 +3,11 @@ class FlowSetting < ApplicationRecord belongs_to :flow, optional: true belongs_to :definition, class_name: 'FlowSettingDefinition' + + def to_grpc + Tucana::Shared::FlowSetting.new( + definition: definition.to_grpc, + object: Tucana::Shared::Struct.from_ruby(object) + ) + end end diff --git a/app/models/flow_setting_definition.rb b/app/models/flow_setting_definition.rb index e907599a..fbeb8c58 100644 --- a/app/models/flow_setting_definition.rb +++ b/app/models/flow_setting_definition.rb @@ -2,4 +2,11 @@ class FlowSettingDefinition < ApplicationRecord has_many :flow_settings, inverse_of: :definition + + def to_grpc + Tucana::Shared::FlowSettingDefinition.new( + id: identifier, + key: key + ) + end end diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 0612a21a..10d8b015 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -1,21 +1,11 @@ # frozen_string_literal: true class FunctionGenericMapper < ApplicationRecord - belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers + belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, inverse_of: :function_generic_mappers validates :target, presence: true - validate :exactly_one_of_generic_key_or_data_type_identifier_id - - private - - def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier.present?] - return if values.count(true) == 1 - - errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') - end end diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb index 117b44dc..e81f9902 100644 --- a/app/models/generic_mapper.rb +++ b/app/models/generic_mapper.rb @@ -2,20 +2,17 @@ class GenericMapper < ApplicationRecord belongs_to :generic_type, inverse_of: :generic_mappers, optional: true - belongs_to :data_type_identifier, optional: true, inverse_of: :generic_mappers + belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :generic_mappers belongs_to :runtime, inverse_of: :generic_mappers belongs_to :runtime_parameter_definition, optional: true, inverse_of: :generic_mappers validates :target, presence: true - validate :exactly_one_of_generic_key_or_data_type_identifier_id, :generic_key_changed? - validate :exactly_one_of_generic_key_or_data_type_identifier_id, :data_type_identifier_changed? - private - - def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier.present?] - return if values.count(true) == 1 - - errors.add(:base, 'Exactly one of generic_key or data_type_identifier must be present') + def to_grpc + Tucana::Shared::GenericMapper.new( + data_type_identifier_id: data_type_identifier&.to_grpc, + generic_key: generic_key, + target: target + ) end end diff --git a/app/models/generic_type.rb b/app/models/generic_type.rb index bb7cba2f..b67edf49 100644 --- a/app/models/generic_type.rb +++ b/app/models/generic_type.rb @@ -1,8 +1,16 @@ # frozen_string_literal: true class GenericType < ApplicationRecord - belongs_to :data_type_identifier, inverse_of: :generic_type + belongs_to :data_type, class_name: 'DataType', inverse_of: :generic_types belongs_to :runtime, class_name: 'Runtime', inverse_of: :generic_types has_many :generic_mappers, inverse_of: :generic_type + has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :generic_type + + def to_grcp + Tucana::Sagittarius::GenericType.new( + data_type_identifier: data_type_identifier&.data_type&.identifier, + generic_mappers: generic_mappers.map(&:to_grcp) + ) + end end diff --git a/app/models/node_function.rb b/app/models/node_function.rb index e639bd0b..18d604d8 100644 --- a/app/models/node_function.rb +++ b/app/models/node_function.rb @@ -5,4 +5,13 @@ class NodeFunction < ApplicationRecord belongs_to :next_node, class_name: 'NodeFunction', optional: true has_many :node_parameters, inverse_of: :function_value + + def to_grpc + Tucana::NodeFunction.new( + data_base_id: id, + runtime_function: runtime_function.to_grpc, + parameters: node_parameters.map(&:to_grpc), + next_node: next_node&.to_grpc + ) + end end diff --git a/app/models/node_parameter.rb b/app/models/node_parameter.rb index ea4690c6..1f6ca1c7 100644 --- a/app/models/node_parameter.rb +++ b/app/models/node_parameter.rb @@ -7,6 +7,23 @@ class NodeParameter < ApplicationRecord validate :only_one_value_present + def to_grpc + param = Tucana::Shared::NodeParameter.new( + database_id: id, + runtime_parameter_id: runtime_parameter&.identifier + ) + + if literal_value.present? + param.literal_value = Tucana::Shared::Value.from_ruby(literal_value) + elsif reference_value.present? + param.reference_value = reference_value.to_grpc + elsif function_value.present? + param.function_value = function_value.to_grpc + end + + param + end + private def only_one_value_present diff --git a/app/models/reference_path.rb b/app/models/reference_path.rb index 5cbff11f..06ff32a6 100644 --- a/app/models/reference_path.rb +++ b/app/models/reference_path.rb @@ -2,4 +2,11 @@ class ReferencePath < ApplicationRecord belongs_to :reference_value + + def to_grpc + Tucana::Shared::ReferencePath.new( + path: path, + array_index: array_index + ) + end end diff --git a/app/models/reference_value.rb b/app/models/reference_value.rb index e8d77a4d..ca12c4eb 100644 --- a/app/models/reference_value.rb +++ b/app/models/reference_value.rb @@ -4,4 +4,14 @@ class ReferenceValue < ApplicationRecord belongs_to :data_type_identifier has_many :reference_paths, inverse_of: :reference_value has_many :node_parameters, inverse_of: :reference_value + + def to_grpc + Tucana::Shared::ReferenceValue.new( + data_type_identifier: data_type_identifier.to_grpc, + primary_level: primary_level, + secondary_level: secondary_level, + tertiary_level: tertiary_level, + path: reference_paths.map(&:to_grpc) + ) + end end diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index e61b1c88..537d28fd 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -51,7 +51,7 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.deprecation_messages) db_object.error_types = update_error_types(runtime_function_definition.error_type_identifiers, db_object, t) - db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object) + db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object, t) if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -69,23 +69,20 @@ def update_runtime_function_definition(runtime_function_definition, t) end # These mappers can be either generic mappers or generic function mappers. - def update_mappers(generic_mappers, runtime_function_definition = nil) + def update_mappers(generic_mappers, runtime_function_definition, t) generic_mappers.to_a.map do |generic_mapper| if generic_mapper.is_a? Tucana::Shared::GenericMapper mapper = GenericMapper.create_or_find_by(runtime: current_runtime, target: generic_mapper.target, - generic_key: generic_mapper.generic_key, - data_type_identifier: - (generic_mapper.generic_key.nil? ? data_type_identifier : nil)) - + source: find_data_type_identifier(generic_mapper.source, + generic_mappers, t)) end if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper mapper = FunctionGenericMapper.create_or_find_by( runtime_id: current_runtime.id, runtime_function_definition: runtime_function_definition, - data_type_identifier: (generic_mapper.generic_key.nil? ? data_type_identifier : nil), + source: find_data_type_identifier(generic_mapper.source, generic_mappers, t), target: generic_mapper.target, - generic_key: generic_mapper.generic_key, parameter_id: generic_mapper.parameter_id ) end @@ -110,16 +107,16 @@ def find_data_type_identifier(identifier, generic_mappers, t) identifier.generic_type.generic_mappers.each do |generic_mapper| arr << generic_mapper end - data_type_identifier = find_data_type_identifier(identifier.generic_type.data_type_identifier, arr, t) + data_type = find_data_type(identifier.generic_type.data_type_identifier, t) generic_type = GenericType.find_by( runtime_id: current_runtime.id, - data_type_identifier_id: data_type_identifier.id + data_type: data_type ) if generic_type.nil? generic_type = GenericType.create( runtime_id: current_runtime.id, - data_type_identifier_id: data_type_identifier.id + data_type: data_type ) end @@ -130,7 +127,8 @@ def find_data_type_identifier(identifier, generic_mappers, t) ) end - generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers)) + generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers, nil, + t)) return create_data_type_identifier(t, generic_type_id: generic_type.id) end diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 4151d076..747303a3 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -8,37 +8,28 @@ def change add_column :data_types, :generic_keys, 'text[]', null: false, default: [] create_table :data_type_identifiers do |t| - # One of them needs to be set + # One of them needs to be set will be enforced later t.text :generic_key, null: true t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end create_table :generic_types do |t| - t.references :data_type_identifier, null: false, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + t.references :data_type, null: false, foreign_key: { to_table: :data_types, on_delete: :cascade } t.timestamps_with_timezone end create_table :generic_mappers do |t| - t.text :target, null: false - # One of them needs to be set - t.text :generic_key, null: true - t.references :data_type_identifier, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:generic_mappers, :source, :one_of) - - t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :cascade } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + t.text :target, null: false + t.references :source, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } + t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :restrict } t.timestamps_with_timezone end @@ -50,44 +41,42 @@ def change name: check_constraint_name(:data_type_identifiers, :type, :one_of) create_table :function_generic_mappers do |t| - t.references :data_type_identifier, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } - t.text :generic_key, null: true - - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.references :source, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } t.text :target, null: false t.text :parameter_id, null: true t.references :runtime_parameter_definition, null: true, foreign_key: { to_table: :runtime_parameter_definitions, - on_delete: :cascade } + on_delete: :restrict } t.references :runtime_function_definition, null: true, foreign_key: { to_table: :runtime_function_definitions, - on_delete: :cascade } + on_delete: :restrict } # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end - remove_column :runtime_function_definitions, :return_type_id + remove_reference :runtime_function_definitions, :return_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] - remove_column :runtime_parameter_definitions, :data_type_id + remove_reference :runtime_parameter_definitions, :data_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_column :parameter_definitions, :data_type_id + remove_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_column :function_definitions, :return_type_id + remove_reference :function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true end diff --git a/db/structure.sql b/db/structure.sql index 64eac259..56c9b443 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -297,16 +297,14 @@ ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; CREATE TABLE function_generic_mappers ( id bigint NOT NULL, - data_type_identifier_id bigint, - generic_key text, + source_id bigint, target text NOT NULL, parameter_id text, runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) + updated_at timestamp with time zone NOT NULL ); CREATE SEQUENCE function_generic_mappers_id_seq @@ -320,14 +318,12 @@ ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers CREATE TABLE generic_mappers ( id bigint NOT NULL, + runtime_id bigint NOT NULL, target text NOT NULL, - generic_key text, - data_type_identifier_id bigint, + source_id bigint NOT NULL, generic_type_id bigint, - runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) + updated_at timestamp with time zone NOT NULL ); CREATE SEQUENCE generic_mappers_id_seq @@ -341,8 +337,8 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, - data_type_identifier_id bigint NOT NULL, runtime_id bigint NOT NULL, + data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); @@ -1139,17 +1135,17 @@ CREATE INDEX index_function_definitions_on_return_type_id ON function_definition CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); -CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); - CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); -CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); +CREATE INDEX index_function_generic_mappers_on_source_id ON function_generic_mappers USING btree (source_id); CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); -CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); +CREATE INDEX index_generic_mappers_on_source_id ON generic_mappers USING btree (source_id); + +CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); @@ -1284,10 +1280,10 @@ ALTER TABLE ONLY function_generic_mappers ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_2adace81b8 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_362b88d836 FOREIGN KEY (input_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1397,6 +1393,9 @@ ALTER TABLE ONLY flows ALTER TABLE ONLY reference_values ADD CONSTRAINT fk_rails_bb34a5d62c FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_be1833ba72 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; @@ -1427,9 +1426,6 @@ ALTER TABLE ONLY runtime_parameter_definitions ALTER TABLE ONLY runtimes ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; - ALTER TABLE ONLY audit_events ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; diff --git a/docs/graphql/enum/namespaceroleability.md b/docs/graphql/enum/namespaceroleability.md index b54b3468..810c90a6 100644 --- a/docs/graphql/enum/namespaceroleability.md +++ b/docs/graphql/enum/namespaceroleability.md @@ -10,10 +10,12 @@ Represents abilities that can be granted to roles in namespaces. | `ASSIGN_PROJECT_RUNTIMES` | Allows to assign runtimes to a project in the namespace | | `ASSIGN_ROLE_ABILITIES` | Allows to change the abilities of a namespace role | | `ASSIGN_ROLE_PROJECTS` | Allows to change the assigned projects of a namespace role | +| `CREATE_FLOWS` | Allows to create flows in the namespace | | `CREATE_NAMESPACE_LICENSE` | Allows to create a license for the namespace | | `CREATE_NAMESPACE_PROJECT` | Allows to create a project in the namespace | | `CREATE_NAMESPACE_ROLE` | Allows the creation of roles in a namespace | | `CREATE_RUNTIME` | Allows to create a runtime globally or for the namespace | +| `DELETE_FLOWS` | Allows to delete flows in the namespace | | `DELETE_MEMBER` | Allows to remove members of a namespace | | `DELETE_NAMESPACE_LICENSE` | Allows to delete the license of the namespace | | `DELETE_NAMESPACE_PROJECT` | Allows to delete the project of the namespace | @@ -25,6 +27,7 @@ Represents abilities that can be granted to roles in namespaces. | `READ_NAMESPACE_LICENSE` | Allows to read the license of the namespace | | `READ_NAMESPACE_PROJECT` | Allows to read the project of the namespace | | `ROTATE_RUNTIME_TOKEN` | Allows to regenerate a runtime token | +| `UPDATE_FLOWS` | Allows to update flows in the namespace | | `UPDATE_NAMESPACE_PROJECT` | Allows to update the project of the namespace | | `UPDATE_NAMESPACE_ROLE` | Allows to update the namespace role | | `UPDATE_ORGANIZATION` | Allows to update the organization | diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb index 96e28ab6..e448ce1d 100644 --- a/spec/factories/function_generic_mappers.rb +++ b/spec/factories/function_generic_mappers.rb @@ -4,7 +4,6 @@ factory :function_generic_mapper do target { nil } runtime_parameter_definition { nil } - generic_key { nil } - data_type_identifier { nil } + source { nil } end end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index 33a5cd58..36a7fdc9 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -4,7 +4,6 @@ factory :generic_mapper do runtime target { nil } - generic_key { nil } - data_type_identifier { nil } + source { nil } end end diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index a4eef104..a7601bec 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -4,6 +4,6 @@ factory :generic_type do runtime generic_mappers { [] } - data_type_identifier { nil } + data_type end end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index 11d422d7..a2270dcd 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -8,18 +8,17 @@ it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to have_many(:generic_types) } - it { is_expected.to have_many(:generic_mappers) } + it { is_expected.to have_many(:generic_mappers).inverse_of(:source) } + it { is_expected.to have_many(:function_generic_mappers).inverse_of(:source) } end describe 'validations' do it 'is valid with exactly one of generic_key, data_type_id, or generic_type_id' do expect(build(:data_type_identifier, generic_key: 'key')).to be_valid expect(build(:data_type_identifier, data_type: create(:data_type))).to be_valid + generic_type = create(:generic_type, data_type: create(:data_type)) expect(build(:data_type_identifier, - generic_type: create(:generic_type, - data_type_identifier: create(:data_type_identifier, - generic_key: 'x')))).to be_valid + generic_type: generic_type)).to be_valid end it 'is invalid when none of generic_key, data_type_id, or generic_type_id are set' do diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index c83b8546..6dd7b9b6 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -4,7 +4,7 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do - it { is_expected.to belong_to(:data_type_identifier).optional } + it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier').inverse_of(:function_generic_mappers) } it { is_expected.to belong_to(:runtime_parameter_definition).optional } it { @@ -12,31 +12,4 @@ .optional.inverse_of(:generic_mappers) } end - - describe 'validations' do - it 'is valid with target and one of generic_key or data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'x') - expect(build(:function_generic_mapper, target: 'do_something', generic_key: 'param')).to be_valid - expect(build(:function_generic_mapper, target: 'do_something', data_type_identifier: dti)).to be_valid - end - - it 'is invalid with both generic_key and data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'x') - mapper = build(:function_generic_mapper, target: 'x', generic_key: 'param', data_type_identifier: dti) - expect(mapper).not_to be_valid - expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') - end - - it 'is invalid with neither generic_key nor data_type_identifier' do - mapper = build(:function_generic_mapper, target: 'x', generic_key: nil, data_type_identifier: nil) - expect(mapper).not_to be_valid - expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') - end - - it 'is invalid without a target' do - mapper = build(:function_generic_mapper, target: nil, generic_key: 'something') - expect(mapper).not_to be_valid - expect(mapper.errors[:target]).to include("can't be blank") - end - end end diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index bdc7873f..843a3649 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -7,43 +7,6 @@ describe 'associations' do it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to belong_to(:data_type_identifier).optional } - end - - describe 'validations' do - it 'is valid with target and exactly one of generic_key or data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - - expect(build(:generic_mapper, target: 'target', generic_key: 'key1', generic_type: generic_type)).to be_valid - expect(build(:generic_mapper, target: 'target', data_type_identifier: dti, - generic_type: generic_type)).to be_valid - end - - it 'is invalid without a target' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: nil, generic_key: 'key1', generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:target]).to include("can't be blank") - end - - it 'is invalid when neither generic_key nor data_type_identifier is set' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, - generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') - end - - it 'is invalid when both generic_key and data_type_identifier are set' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, - generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') - end + it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier') } end end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index b97b9ca7..86ff0fec 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -5,19 +5,8 @@ RSpec.describe GenericType do describe 'associations' do - it { is_expected.to belong_to(:data_type_identifier) } + it { is_expected.to belong_to(:data_type) } it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_mappers) } end - - describe 'validations' do - it 'is valid with a data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'key') - expect(build(:generic_type, data_type_identifier: dti)).to be_valid - end - - it 'is invalid without a data_type_identifier' do - expect(build(:generic_type, data_type_identifier: nil)).not_to be_valid - end - end end diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 5473a97a..8aada144 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -15,13 +15,7 @@ end let!(:generic_type) do - create(:generic_type, - runtime: runtime, - data_type_identifier: - create(:data_type_identifier, - runtime: runtime, - data_type: create(:data_type, - runtime: runtime).reload).reload).reload + create(:generic_type, runtime: runtime, data_type: create(:data_type, runtime: runtime)) end let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload } let(:error_type) { create(:data_type, runtime: runtime) } @@ -44,16 +38,13 @@ ], return_type_identifier: { generic_type: { - data_type_identifier: { # Without reloads it just fails - data_type_identifier: return_type.reload.generic_type - .reload.data_type_identifier.reload.data_type.reload.identifier, - }, - generic_mappers: [{ generic_key: 'T', target: 'V' }], + data_type_identifier: return_type.generic_type.data_type.identifier, + generic_mappers: [{ source: { generic_key: 'T' }, target: 'V' }], }, }, generic_mappers: [ { - generic_key: 'X', + source: { generic_key: 'X' }, target: 'Y', parameter_id: 'some_id', } @@ -89,15 +80,15 @@ expect(stub.update(message, authorization(runtime)).success).to be(true) expect(GenericMapper.count).to eq(1) - expect(GenericMapper.last.generic_key).to eq('T') + expect(GenericMapper.last.source.generic_key).to eq('T') expect(GenericMapper.last.target).to eq('V') expect(GenericType.count).to eq(1) function = RuntimeFunctionDefinition.last expect(function.runtime_name).to eq('runtime_function_id') - expect(function.return_type.generic_type.reload.data_type_identifier.data_type.identifier) - .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) + expect(function.return_type.generic_type.reload.data_type.identifier) + .to eq(return_type.generic_type.data_type.identifier) expect(function.names.first.content).to eq('Eine Funktion') expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation') @@ -115,8 +106,8 @@ expect(function_definition.names.first.content).to eq('Eine Funktion') expect(function_definition.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function_definition.documentations.first.content).to eq('Eine Funktionsdokumentation') - expect(function_definition.return_type.generic_type.reload.data_type_identifier.data_type.identifier) - .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) + expect(function_definition.return_type.generic_type.reload.data_type.identifier) + .to eq(return_type.generic_type.data_type.identifier) parameter_definition = ParameterDefinition.first expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter_definition.names.first.content).to eq('Ein Parameter') @@ -125,7 +116,7 @@ expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) expect(FunctionGenericMapper.count).to eq(1) - expect(FunctionGenericMapper.last.generic_key).to eq('X') + expect(FunctionGenericMapper.last.source.generic_key).to eq('X') expect(FunctionGenericMapper.last.target).to eq('Y') expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end From dad9ba69d31bc515300d2f8b39101ad3fec37983 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 15:41:23 +0200 Subject: [PATCH 23/54] Refactor flow associations to use input_type and return_type instead of input_type_identifier and return_type_identifier to align with grpc implementation of the flow --- app/models/flow.rb | 8 ++++---- db/migrate/20250526124346_create_flows.rb | 4 ++-- db/structure.sql | 20 ++++++++++---------- spec/models/flow_spec.rb | 2 ++ 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/models/flow.rb b/app/models/flow.rb index 505bbbe7..b50d11a5 100644 --- a/app/models/flow.rb +++ b/app/models/flow.rb @@ -3,8 +3,8 @@ class Flow < ApplicationRecord belongs_to :project, class_name: 'NamespaceProject' belongs_to :flow_type - belongs_to :input_type_identifier, class_name: 'DataTypeIdentifier', optional: true - belongs_to :return_type_identifier, class_name: 'DataTypeIdentifier', optional: true + belongs_to :input_type, class_name: 'DataType', optional: true + belongs_to :return_type, class_name: 'DataType', optional: true belongs_to :starting_node, class_name: 'NodeFunction' has_many :flow_settings @@ -15,8 +15,8 @@ def to_grpc project_id: project.id, flow_type_id: flow_type.identifier, data_types: [], # TODO - input_type_id: input_type_identifier&.identifier, - return_type_id: return_type_identifier&.identifier, + input_type_id: input_type&.identifier, + return_type_id: return_type&.identifier, settings: flow_settings.map(&:to_grpc), starting_node: starting_node.to_grpc ) diff --git a/db/migrate/20250526124346_create_flows.rb b/db/migrate/20250526124346_create_flows.rb index d1749a94..f0cef993 100644 --- a/db/migrate/20250526124346_create_flows.rb +++ b/db/migrate/20250526124346_create_flows.rb @@ -51,9 +51,9 @@ def change on_delete: :cascade } t.references :flow_type, null: false, foreign_key: { to_table: :flow_types, on_delete: :cascade } - t.references :input_type_identifier, null: true, foreign_key: { to_table: :data_type_identifiers, + t.references :input_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } - t.references :return_type_identifier, null: true, foreign_key: { to_table: :data_type_identifiers, + t.references :return_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } t.references :starting_node, null: false, foreign_key: { to_table: :node_functions, on_delete: :restrict } diff --git a/db/structure.sql b/db/structure.sql index 56c9b443..535c6f68 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -262,8 +262,8 @@ CREATE TABLE flows ( id bigint NOT NULL, project_id bigint NOT NULL, flow_type_id bigint NOT NULL, - input_type_identifier_id bigint, - return_type_identifier_id bigint, + input_type_id bigint, + return_type_id bigint, starting_node_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL @@ -1123,11 +1123,11 @@ CREATE UNIQUE INDEX index_flow_types_on_runtime_id_and_identifier ON flow_types CREATE INDEX index_flows_on_flow_type_id ON flows USING btree (flow_type_id); -CREATE INDEX index_flows_on_input_type_identifier_id ON flows USING btree (input_type_identifier_id); +CREATE INDEX index_flows_on_input_type_id ON flows USING btree (input_type_id); CREATE INDEX index_flows_on_project_id ON flows USING btree (project_id); -CREATE INDEX index_flows_on_return_type_identifier_id ON flows USING btree (return_type_identifier_id); +CREATE INDEX index_flows_on_return_type_id ON flows USING btree (return_type_id); CREATE INDEX index_flows_on_starting_node_id ON flows USING btree (starting_node_id); @@ -1261,9 +1261,6 @@ ALTER TABLE ONLY function_definitions ALTER TABLE ONLY node_parameters ADD CONSTRAINT fk_rails_0ff4fd0049 FOREIGN KEY (runtime_parameter_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; -ALTER TABLE ONLY flows - ADD CONSTRAINT fk_rails_10bea7d7dc FOREIGN KEY (return_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; - ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_118c914ed0 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; @@ -1285,9 +1282,6 @@ ALTER TABLE ONLY generic_types ALTER TABLE ONLY generic_mappers ADD CONSTRAINT fk_rails_2adace81b8 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY flows - ADD CONSTRAINT fk_rails_362b88d836 FOREIGN KEY (input_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; - ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -1369,6 +1363,9 @@ ALTER TABLE ONLY flow_settings ALTER TABLE ONLY data_type_identifiers ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_8f97500cd4 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + ALTER TABLE ONLY reference_paths ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; @@ -1393,6 +1390,9 @@ ALTER TABLE ONLY flows ALTER TABLE ONLY reference_values ADD CONSTRAINT fk_rails_bb34a5d62c FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_bb587eff6a FOREIGN KEY (input_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + ALTER TABLE ONLY function_generic_mappers ADD CONSTRAINT fk_rails_be1833ba72 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; diff --git a/spec/models/flow_spec.rb b/spec/models/flow_spec.rb index 0942e79b..9eee50bd 100644 --- a/spec/models/flow_spec.rb +++ b/spec/models/flow_spec.rb @@ -9,5 +9,7 @@ it { is_expected.to belong_to(:project).class_name('NamespaceProject') } it { is_expected.to belong_to(:flow_type) } it { is_expected.to belong_to(:starting_node).class_name('NodeFunction') } + it { is_expected.to belong_to(:input_type).class_name('DataType').optional } + it { is_expected.to belong_to(:return_type).class_name('DataType').optional } end end From d647f0b0bec5f150b71616b1fd4e8e732b97cb4c Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 15:50:52 +0200 Subject: [PATCH 24/54] Changeup flow setting to allign with https://github.com/code0-tech/tucana/pull/96 --- app/models/flow_setting.rb | 4 +-- app/models/flow_setting_definition.rb | 12 --------- db/migrate/20250526124346_create_flows.rb | 13 +++------ db/structure.sql | 29 +-------------------- spec/factories/flow_setting_definitions.rb | 8 ------ spec/factories/flow_settings.rb | 2 +- spec/models/flow_setting_definition_spec.rb | 11 -------- spec/models/flow_setting_spec.rb | 1 - 8 files changed, 7 insertions(+), 73 deletions(-) delete mode 100644 app/models/flow_setting_definition.rb delete mode 100644 spec/factories/flow_setting_definitions.rb delete mode 100644 spec/models/flow_setting_definition_spec.rb diff --git a/app/models/flow_setting.rb b/app/models/flow_setting.rb index 58142564..49396be0 100644 --- a/app/models/flow_setting.rb +++ b/app/models/flow_setting.rb @@ -2,11 +2,11 @@ class FlowSetting < ApplicationRecord belongs_to :flow, optional: true - belongs_to :definition, class_name: 'FlowSettingDefinition' def to_grpc Tucana::Shared::FlowSetting.new( - definition: definition.to_grpc, + database_id: id, + flow_setting_id: flow_setting_id, object: Tucana::Shared::Struct.from_ruby(object) ) end diff --git a/app/models/flow_setting_definition.rb b/app/models/flow_setting_definition.rb deleted file mode 100644 index fbeb8c58..00000000 --- a/app/models/flow_setting_definition.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -class FlowSettingDefinition < ApplicationRecord - has_many :flow_settings, inverse_of: :definition - - def to_grpc - Tucana::Shared::FlowSettingDefinition.new( - id: identifier, - key: key - ) - end -end diff --git a/db/migrate/20250526124346_create_flows.rb b/db/migrate/20250526124346_create_flows.rb index f0cef993..9a7f3948 100644 --- a/db/migrate/20250526124346_create_flows.rb +++ b/db/migrate/20250526124346_create_flows.rb @@ -52,9 +52,9 @@ def change t.references :flow_type, null: false, foreign_key: { to_table: :flow_types, on_delete: :cascade } t.references :input_type, null: true, foreign_key: { to_table: :data_types, - on_delete: :restrict } + on_delete: :restrict } t.references :return_type, null: true, foreign_key: { to_table: :data_types, - on_delete: :restrict } + on_delete: :restrict } t.references :starting_node, null: false, foreign_key: { to_table: :node_functions, on_delete: :restrict } @@ -63,17 +63,10 @@ def change add_reference :data_types, :flows, null: true, foreign_key: { to_table: :flows, on_delete: :restrict } - create_table :flow_setting_definitions do |t| - t.text :identifier, null: false - t.text :key, null: false - - t.timestamps_with_timezone - end - create_table :flow_settings do |t| t.references :flow, null: true, foreign_key: { to_table: :flows, on_delete: :cascade } - t.references :definition, null: false, foreign_key: { to_table: :flow_setting_definitions, on_delete: :cascade } + t.text :flow_setting_id, null: false t.jsonb :object, null: false t.timestamps_with_timezone diff --git a/db/structure.sql b/db/structure.sql index 535c6f68..e7ec01b1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -182,27 +182,10 @@ CREATE SEQUENCE data_types_id_seq ALTER SEQUENCE data_types_id_seq OWNED BY data_types.id; -CREATE TABLE flow_setting_definitions ( - id bigint NOT NULL, - identifier text NOT NULL, - key text NOT NULL, - created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL -); - -CREATE SEQUENCE flow_setting_definitions_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -ALTER SEQUENCE flow_setting_definitions_id_seq OWNED BY flow_setting_definitions.id; - CREATE TABLE flow_settings ( id bigint NOT NULL, flow_id bigint, - definition_id bigint NOT NULL, + flow_setting_id text NOT NULL, object jsonb NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL @@ -862,8 +845,6 @@ ALTER TABLE ONLY data_type_rules ALTER COLUMN id SET DEFAULT nextval('data_type_ ALTER TABLE ONLY data_types ALTER COLUMN id SET DEFAULT nextval('data_types_id_seq'::regclass); -ALTER TABLE ONLY flow_setting_definitions ALTER COLUMN id SET DEFAULT nextval('flow_setting_definitions_id_seq'::regclass); - ALTER TABLE ONLY flow_settings ALTER COLUMN id SET DEFAULT nextval('flow_settings_id_seq'::regclass); ALTER TABLE ONLY flow_type_settings ALTER COLUMN id SET DEFAULT nextval('flow_type_settings_id_seq'::regclass); @@ -954,9 +935,6 @@ ALTER TABLE ONLY data_type_rules ALTER TABLE ONLY data_types ADD CONSTRAINT data_types_pkey PRIMARY KEY (id); -ALTER TABLE ONLY flow_setting_definitions - ADD CONSTRAINT flow_setting_definitions_pkey PRIMARY KEY (id); - ALTER TABLE ONLY flow_settings ADD CONSTRAINT flow_settings_pkey PRIMARY KEY (id); @@ -1107,8 +1085,6 @@ CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (paren CREATE UNIQUE INDEX index_data_types_on_runtime_id_and_identifier ON data_types USING btree (runtime_id, identifier); -CREATE INDEX index_flow_settings_on_definition_id ON flow_settings USING btree (definition_id); - CREATE INDEX index_flow_settings_on_flow_id ON flow_settings USING btree (flow_id); CREATE INDEX index_flow_type_settings_on_data_type_id ON flow_type_settings USING btree (data_type_id); @@ -1357,9 +1333,6 @@ ALTER TABLE ONLY flows ALTER TABLE ONLY node_functions ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; -ALTER TABLE ONLY flow_settings - ADD CONSTRAINT fk_rails_8c9f4f986e FOREIGN KEY (definition_id) REFERENCES flow_setting_definitions(id) ON DELETE CASCADE; - ALTER TABLE ONLY data_type_identifiers ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; diff --git a/spec/factories/flow_setting_definitions.rb b/spec/factories/flow_setting_definitions.rb deleted file mode 100644 index c67033bb..00000000 --- a/spec/factories/flow_setting_definitions.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :flow_setting_definition do - identifier { 'example_setting' } - key { 'example_key' } - end -end diff --git a/spec/factories/flow_settings.rb b/spec/factories/flow_settings.rb index df810336..becef0c7 100644 --- a/spec/factories/flow_settings.rb +++ b/spec/factories/flow_settings.rb @@ -3,7 +3,7 @@ FactoryBot.define do factory :flow_setting do flow - definition factory: %i[flow_setting_definition] + flow_setting_id { 'default' } object { { enabled: true } } end end diff --git a/spec/models/flow_setting_definition_spec.rb b/spec/models/flow_setting_definition_spec.rb deleted file mode 100644 index 687f48c4..00000000 --- a/spec/models/flow_setting_definition_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe FlowSettingDefinition do - subject { create(:flow_setting_definition) } - - describe 'associations' do - it { is_expected.to have_many(:flow_settings).inverse_of(:definition) } - end -end diff --git a/spec/models/flow_setting_spec.rb b/spec/models/flow_setting_spec.rb index 0f0512c0..edf0a315 100644 --- a/spec/models/flow_setting_spec.rb +++ b/spec/models/flow_setting_spec.rb @@ -7,6 +7,5 @@ describe 'associations' do it { is_expected.to belong_to(:flow).optional } - it { is_expected.to belong_to(:definition).class_name('FlowSettingDefinition') } end end From 85b8f5c0727440ccb036cb7b0bc62154283b7f5e Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Thu, 29 May 2025 02:39:04 +0200 Subject: [PATCH 25/54] Recompile structure.sql --- db/structure.sql | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/db/structure.sql b/db/structure.sql index e7ec01b1..e2a4fb01 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -463,6 +463,23 @@ CREATE SEQUENCE namespace_members_id_seq ALTER SEQUENCE namespace_members_id_seq OWNED BY namespace_members.id; +CREATE TABLE namespace_project_runtime_assignments ( + id bigint NOT NULL, + runtime_id bigint NOT NULL, + namespace_project_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE namespace_project_runtime_assignments_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE namespace_project_runtime_assignments_id_seq OWNED BY namespace_project_runtime_assignments.id; + CREATE TABLE namespace_projects ( id bigint NOT NULL, name text NOT NULL, @@ -470,6 +487,7 @@ CREATE TABLE namespace_projects ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, namespace_id bigint NOT NULL, + primary_runtime_id bigint, CONSTRAINT check_09e881e641 CHECK ((char_length(name) <= 50)), CONSTRAINT check_a77bf7c685 CHECK ((char_length(description) <= 500)) ); @@ -867,6 +885,8 @@ ALTER TABLE ONLY namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('nam ALTER TABLE ONLY namespace_members ALTER COLUMN id SET DEFAULT nextval('namespace_members_id_seq'::regclass); +ALTER TABLE ONLY namespace_project_runtime_assignments ALTER COLUMN id SET DEFAULT nextval('namespace_project_runtime_assignments_id_seq'::regclass); + ALTER TABLE ONLY namespace_projects ALTER COLUMN id SET DEFAULT nextval('namespace_projects_id_seq'::regclass); ALTER TABLE ONLY namespace_role_abilities ALTER COLUMN id SET DEFAULT nextval('namespace_role_abilities_id_seq'::regclass); @@ -983,6 +1003,9 @@ ALTER TABLE ONLY namespace_member_roles ALTER TABLE ONLY namespace_members ADD CONSTRAINT namespace_members_pkey PRIMARY KEY (id); +ALTER TABLE ONLY namespace_project_runtime_assignments + ADD CONSTRAINT namespace_project_runtime_assignments_pkey PRIMARY KEY (id); + ALTER TABLE ONLY namespace_projects ADD CONSTRAINT namespace_projects_pkey PRIMARY KEY (id); @@ -1053,6 +1076,8 @@ CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON function_generi CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); +CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); + CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON runtime_function_definitions USING btree (runtime_id, runtime_name); CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON function_generic_mappers USING btree (runtime_parameter_definition_id); @@ -1173,6 +1198,8 @@ CREATE INDEX index_namespace_members_on_user_id ON namespace_members USING btree CREATE INDEX index_namespace_projects_on_namespace_id ON namespace_projects USING btree (namespace_id); +CREATE INDEX index_namespace_projects_on_primary_runtime_id ON namespace_projects USING btree (primary_runtime_id); + CREATE INDEX index_namespace_role_project_assignments_on_project_id ON namespace_role_project_assignments USING btree (project_id); CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON namespace_roles USING btree (namespace_id, lower(name)); @@ -1327,6 +1354,9 @@ ALTER TABLE ONLY node_parameters ALTER TABLE ONLY data_type_rules ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY namespace_projects + ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_7de9ce6578 FOREIGN KEY (starting_node_id) REFERENCES node_functions(id) ON DELETE RESTRICT; @@ -1372,9 +1402,15 @@ ALTER TABLE ONLY function_generic_mappers ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY namespace_project_runtime_assignments + ADD CONSTRAINT fk_rails_c019e5b233 FOREIGN KEY (namespace_project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; + ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); +ALTER TABLE ONLY namespace_project_runtime_assignments + ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ALTER TABLE ONLY generic_mappers ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; From 77c7747ba0e5b909998f08ea2df9c84dbc1c0449 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 00:29:57 +0200 Subject: [PATCH 26/54] Update datatype model and runtime function (definition) models --- Gemfile | 2 +- Gemfile.lock | 4 +- app/models/data_type.rb | 5 +- app/models/data_type_identifier.rb | 10 +-- app/models/function_generic_mapper.rb | 14 ++- .../update_service.rb | 86 +++---------------- .../20250525192143_implement_generics.rb | 49 ++++++----- spec/factories/data_type_identifiers.rb | 1 - spec/factories/function_generic_mappers.rb | 5 +- spec/factories/generic_mappers.rb | 4 +- spec/factories/generic_types.rb | 3 +- spec/models/data_type_identifier_spec.rb | 10 +-- spec/models/function_generic_mapper_spec.rb | 30 ++++++- spec/models/generic_mapper_spec.rb | 42 ++++++++- spec/models/generic_type_spec.rb | 14 ++- ...untime_function_definition_service_spec.rb | 47 ++-------- 16 files changed, 157 insertions(+), 169 deletions(-) diff --git a/Gemfile b/Gemfile index 713ce561..5ceadfd1 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.28' +gem 'tucana', '0.0.26' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index c08fc171..5dec9ce4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -356,7 +356,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.28) + tucana (0.0.26) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -409,7 +409,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.28) + tucana (= 0.0.26) tzinfo-data RUBY VERSION diff --git a/app/models/data_type.rb b/app/models/data_type.rb index 8cc41553..e162af9f 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -7,8 +7,8 @@ class DataType < ApplicationRecord object: 3, datatype: 4, array: 5, - error: 6, - node: 7, + generic: 6, + function: 7, }.with_indifferent_access enum :variant, VARIANTS, prefix: :variant @@ -20,7 +20,6 @@ class DataType < ApplicationRecord has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :rules, class_name: 'DataTypeRule', inverse_of: :data_type has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :data_type - has_many :generic_types, class_name: 'GenericType', inverse_of: :data_type validates :variant, presence: true, inclusion: { diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 4daa8ac9..0451dad5 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -2,11 +2,11 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers - belongs_to :generic_type, optional: true, inverse_of: :data_type_identifiers - belongs_to :runtime, inverse_of: :data_type_identifiers + belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier - has_many :generic_mappers, inverse_of: :source - has_many :function_generic_mappers, class_name: 'FunctionGenericMapper', inverse_of: :source + has_many :generic_types, inverse_of: :data_type_identifier + has_many :generic_mappers, inverse_of: :data_type_identifier + has_many :function_generic_mappers, class_name: 'GenericMapper', inverse_of: :data_type_identifier validate :exactly_one_of_generic_key_data_type_id_generic_type_id @@ -21,7 +21,7 @@ def to_grpc private def exactly_one_of_generic_key_data_type_id_generic_type_id - values = [generic_key.present?, data_type.present?, generic_type.present?] + values = [generic_key.present?, data_type_id.present?, generic_type_id.present?] return if values.count(true) == 1 errors.add(:base, 'Exactly one of generic_key, data_type_id, or generic_type_id must be present') diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 10d8b015..32489de2 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -1,11 +1,19 @@ # frozen_string_literal: true class FunctionGenericMapper < ApplicationRecord - belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mappers + belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers - belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, - inverse_of: :function_generic_mappers validates :target, presence: true + validate :exactly_one_of_generic_key_or_data_type_identifier_id + + private + + def exactly_one_of_generic_key_or_data_type_identifier_id + values = [generic_key.present?, data_type_identifier_id.present?] + return if values.count(true) == 1 + + errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') + end end diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 537d28fd..89603888 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -51,7 +51,6 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.deprecation_messages) db_object.error_types = update_error_types(runtime_function_definition.error_type_identifiers, db_object, t) - db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object, t) if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -69,88 +68,29 @@ def update_runtime_function_definition(runtime_function_definition, t) end # These mappers can be either generic mappers or generic function mappers. - def update_mappers(generic_mappers, runtime_function_definition, t) - generic_mappers.to_a.map do |generic_mapper| - if generic_mapper.is_a? Tucana::Shared::GenericMapper - mapper = GenericMapper.create_or_find_by(runtime: current_runtime, - target: generic_mapper.target, - source: find_data_type_identifier(generic_mapper.source, - generic_mappers, t)) - end - if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper - mapper = FunctionGenericMapper.create_or_find_by( - runtime_id: current_runtime.id, - runtime_function_definition: runtime_function_definition, - source: find_data_type_identifier(generic_mapper.source, generic_mappers, t), - target: generic_mapper.target, - parameter_id: generic_mapper.parameter_id - ) - end - - if mapper.nil? || !mapper.save - t.rollback_and_return! ServiceResponse.error( - message: "Could not find or create generic mapper (#{generic_mapper})", - payload: :error_creating_generic_mapper - ) - end - mapper - end - end - - def find_data_type_identifier(identifier, generic_mappers, t) + def find_data_type_identifier(identifier, _generic_mappers, t) if identifier.data_type_identifier.present? - return create_data_type_identifier(t, data_type_id: find_data_type(identifier.data_type_identifier, t).id) - end - - if identifier.generic_type.present? - arr = generic_mappers.to_a - identifier.generic_type.generic_mappers.each do |generic_mapper| - arr << generic_mapper - end - data_type = find_data_type(identifier.generic_type.data_type_identifier, t) - - generic_type = GenericType.find_by( - runtime_id: current_runtime.id, - data_type: data_type - ) - if generic_type.nil? - generic_type = GenericType.create( - runtime_id: current_runtime.id, - data_type: data_type - ) - end + data_type_identifier = DataTypeIdentifier.find_by(data_type: find_data_type(identifier.data_type_identifier, + t)) - if generic_type.nil? + if data_type_identifier.nil? t.rollback_and_return! ServiceResponse.error( - message: "Could not find generic type with identifier #{identifier.generic_type.data_type_identifier}", - payload: :no_generic_type_for_identifier + message: "Could not find datatype identifier with identifier #{identifier}", + payload: :no_datatype_identifier_for_identifier ) end - generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers, nil, - t)) - - return create_data_type_identifier(t, generic_type_id: generic_type.id) + return data_type_identifier end - return create_data_type_identifier(t, generic_key: identifier.generic_key) if identifier.generic_key.present? - - raise ArgumentError, "Invalid identifier: #{identifier.inspect}" - end - - def create_data_type_identifier(t, **kwargs) - data_type_identifier = DataTypeIdentifier.find_by(runtime_id: current_runtime.id, **kwargs) - if data_type_identifier.nil? - data_type_identifier = DataTypeIdentifier.create_or_find_by(runtime_id: current_runtime.id, **kwargs) + if identifier.generic_type.present? + return find_data_type_identifier(identifier.generic_type.identifier, identifier.generic_type.generic_mappers, + t) end - - if data_type_identifier.nil? - t.rollback_and_return! ServiceResponse.error( - message: "Could not find datatype identifier with #{kwargs}", - payload: :no_datatype_identifier_for_generic_key - ) + if identifier.generic_key.present? + return DataTypeIdentifier.find_or_create_by(runtime: current_runtime, generic_key: identifier.generic_key) end - data_type_identifier + raise ArgumentError, "Invalid identifier: #{identifier.inspect}" end def find_data_type(identifier, t) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 747303a3..416af4a0 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -8,28 +8,31 @@ def change add_column :data_types, :generic_keys, 'text[]', null: false, default: [] create_table :data_type_identifiers do |t| - # One of them needs to be set will be enforced later + # One of them needs to be set t.text :generic_key, null: true t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } - t.timestamps_with_timezone end create_table :generic_types do |t| - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } - t.references :data_type, null: false, foreign_key: { to_table: :data_types, on_delete: :cascade } + t.references :data_type_identifier, null: false, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } t.timestamps_with_timezone end create_table :generic_mappers do |t| - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } - t.text :target, null: false - t.references :source, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } - t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :restrict } + # One of them needs to be set + t.text :generic_key, null: true + t.references :data_type_identifier, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:generic_mappers, :source, :one_of) + + t.references :generic_type, null: false, foreign_key: { to_table: :generic_types, on_delete: :cascade } t.timestamps_with_timezone end @@ -41,42 +44,42 @@ def change name: check_constraint_name(:data_type_identifiers, :type, :one_of) create_table :function_generic_mappers do |t| - t.references :source, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } + t.references :data_type_identifier, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + t.text :generic_key, null: true t.text :target, null: false t.text :parameter_id, null: true - t.references :runtime_parameter_definition, null: true, - foreign_key: { to_table: :runtime_parameter_definitions, - on_delete: :restrict } + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:function_generic_mappers, :source, :one_of) t.references :runtime_function_definition, null: true, foreign_key: { to_table: :runtime_function_definitions, - on_delete: :restrict } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + on_delete: :cascade } t.timestamps_with_timezone end - remove_reference :runtime_function_definitions, :return_type, - foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_column :runtime_function_definitions, :return_type_id add_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] - remove_reference :runtime_parameter_definitions, :data_type, - foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_column :runtime_parameter_definitions, :data_type_id add_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_column :parameter_definitions, :data_type_id add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_reference :function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } + # remove_column :runtime_function_definition_error_types, :data_type_id + # add_reference :runtime_function_definition_error_types, :data_type, + # foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: false + + remove_column :function_definitions, :return_type_id add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true end diff --git a/spec/factories/data_type_identifiers.rb b/spec/factories/data_type_identifiers.rb index f3103216..7ef0303c 100644 --- a/spec/factories/data_type_identifiers.rb +++ b/spec/factories/data_type_identifiers.rb @@ -5,6 +5,5 @@ generic_key { nil } data_type { nil } generic_type { nil } - runtime end end diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb index e448ce1d..e5579f87 100644 --- a/spec/factories/function_generic_mappers.rb +++ b/spec/factories/function_generic_mappers.rb @@ -3,7 +3,8 @@ FactoryBot.define do factory :function_generic_mapper do target { nil } - runtime_parameter_definition { nil } - source { nil } + parameter_id { nil } + generic_key { nil } + data_type_identifier { nil } end end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index 36a7fdc9..b601b3c5 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -2,8 +2,8 @@ FactoryBot.define do factory :generic_mapper do - runtime target { nil } - source { nil } + generic_key { nil } + data_type_identifier { nil } end end diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index a7601bec..f26bc778 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -2,8 +2,7 @@ FactoryBot.define do factory :generic_type do - runtime generic_mappers { [] } - data_type + data_type_identifier { nil } end end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index a2270dcd..e27ff00e 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -7,18 +7,18 @@ describe 'associations' do it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } - it { is_expected.to belong_to(:runtime) } - it { is_expected.to have_many(:generic_mappers).inverse_of(:source) } - it { is_expected.to have_many(:function_generic_mappers).inverse_of(:source) } + it { is_expected.to have_many(:generic_types) } + it { is_expected.to have_many(:generic_mappers) } end describe 'validations' do it 'is valid with exactly one of generic_key, data_type_id, or generic_type_id' do expect(build(:data_type_identifier, generic_key: 'key')).to be_valid expect(build(:data_type_identifier, data_type: create(:data_type))).to be_valid - generic_type = create(:generic_type, data_type: create(:data_type)) expect(build(:data_type_identifier, - generic_type: generic_type)).to be_valid + generic_type: create(:generic_type, + data_type_identifier: create(:data_type_identifier, + generic_key: 'x')))).to be_valid end it 'is invalid when none of generic_key, data_type_id, or generic_type_id are set' do diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index 6dd7b9b6..f22a01fa 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -4,12 +4,38 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do - it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier').inverse_of(:function_generic_mappers) } - it { is_expected.to belong_to(:runtime_parameter_definition).optional } + it { is_expected.to belong_to(:data_type_identifier).optional } it { is_expected.to belong_to(:runtime_function_definition).class_name('RuntimeFunctionDefinition') .optional.inverse_of(:generic_mappers) } end + + describe 'validations' do + it 'is valid with target and one of generic_key or data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'x') + expect(build(:function_generic_mapper, target: 'do_something', generic_key: 'param')).to be_valid + expect(build(:function_generic_mapper, target: 'do_something', data_type_identifier: dti)).to be_valid + end + + it 'is invalid with both generic_key and data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'x') + mapper = build(:function_generic_mapper, target: 'x', generic_key: 'param', data_type_identifier: dti) + expect(mapper).not_to be_valid + expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid with neither generic_key nor data_type_identifier' do + mapper = build(:function_generic_mapper, target: 'x', generic_key: nil, data_type_identifier: nil) + expect(mapper).not_to be_valid + expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid without a target' do + mapper = build(:function_generic_mapper, target: nil, generic_key: 'something') + expect(mapper).not_to be_valid + expect(mapper.errors[:target]).to include("can't be blank") + end + end end diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index 843a3649..419407c7 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -5,8 +5,44 @@ RSpec.describe GenericMapper do describe 'associations' do - it { is_expected.to belong_to(:generic_type).optional } - it { is_expected.to belong_to(:runtime) } - it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier') } + it { is_expected.to belong_to(:generic_type) } + it { is_expected.to belong_to(:data_type_identifier).optional } + end + + describe 'validations' do + it 'is valid with target and exactly one of generic_key or data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + + expect(build(:generic_mapper, target: 'target', generic_key: 'key1', generic_type: generic_type)).to be_valid + expect(build(:generic_mapper, target: 'target', data_type_identifier: dti, + generic_type: generic_type)).to be_valid + end + + it 'is invalid without a target' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: nil, generic_key: 'key1', generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:target]).to include("can't be blank") + end + + it 'is invalid when neither generic_key nor data_type_identifier is set' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, + generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end + + it 'is invalid when both generic_key and data_type_identifier are set' do + dti = create(:data_type_identifier, generic_key: 'key') + generic_type = create(:generic_type, data_type_identifier: dti) + gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, + generic_type: generic_type) + expect(gm).not_to be_valid + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + end end end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index 86ff0fec..9a2aae5c 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -5,8 +5,18 @@ RSpec.describe GenericType do describe 'associations' do - it { is_expected.to belong_to(:data_type) } - it { is_expected.to belong_to(:runtime) } + it { is_expected.to belong_to(:data_type_identifier) } it { is_expected.to have_many(:generic_mappers) } end + + describe 'validations' do + it 'is valid with a data_type_identifier' do + dti = create(:data_type_identifier, generic_key: 'key') + expect(build(:generic_type, data_type_identifier: dti)).to be_valid + end + + it 'is invalid without a data_type_identifier' do + expect(build(:generic_type, data_type_identifier: nil)).not_to be_valid + end + end end diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 8aada144..2e70e488 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -10,14 +10,8 @@ describe 'Update' do context 'when create' do let(:runtime) { create(:runtime) } - let!(:parameter_type) do - create(:data_type_identifier, runtime: runtime, data_type: create(:data_type, runtime: runtime)) - end - - let!(:generic_type) do - create(:generic_type, runtime: runtime, data_type: create(:data_type, runtime: runtime)) - end - let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload } + let(:parameter_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } + let(:return_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } let(:error_type) { create(:data_type, runtime: runtime) } let(:runtime_functions) do @@ -37,18 +31,8 @@ { code: 'de_DE', content: 'Eine Deprecationsmeldung' } ], return_type_identifier: { - generic_type: { - data_type_identifier: return_type.generic_type.data_type.identifier, - generic_mappers: [{ source: { generic_key: 'T' }, target: 'V' }], - }, + data_type_identifier: return_type.data_type.identifier, }, - generic_mappers: [ - { - source: { generic_key: 'X' }, - target: 'Y', - parameter_id: 'some_id', - } - ], error_type_identifiers: [error_type.identifier], runtime_parameter_definitions: [ { @@ -79,16 +63,9 @@ it 'creates a correct functions' do expect(stub.update(message, authorization(runtime)).success).to be(true) - expect(GenericMapper.count).to eq(1) - expect(GenericMapper.last.source.generic_key).to eq('T') - expect(GenericMapper.last.target).to eq('V') - - expect(GenericType.count).to eq(1) - function = RuntimeFunctionDefinition.last expect(function.runtime_name).to eq('runtime_function_id') - expect(function.return_type.generic_type.reload.data_type.identifier) - .to eq(return_type.generic_type.data_type.identifier) + expect(function.return_type.data_type.identifier).to eq(return_type.data_type.identifier) expect(function.names.first.content).to eq('Eine Funktion') expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation') @@ -106,27 +83,19 @@ expect(function_definition.names.first.content).to eq('Eine Funktion') expect(function_definition.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function_definition.documentations.first.content).to eq('Eine Funktionsdokumentation') - expect(function_definition.return_type.generic_type.reload.data_type.identifier) - .to eq(return_type.generic_type.data_type.identifier) + expect(function_definition.return_type.data_type.identifier).to eq(return_type.data_type.identifier) parameter_definition = ParameterDefinition.first expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter_definition.names.first.content).to eq('Ein Parameter') expect(parameter_definition.descriptions.first.content).to eq('Eine Parameterbeschreibung') expect(parameter_definition.documentations.first.content).to eq('Eine Parameterdokumentation') expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) - - expect(FunctionGenericMapper.count).to eq(1) - expect(FunctionGenericMapper.last.source.generic_key).to eq('X') - expect(FunctionGenericMapper.last.target).to eq('Y') - expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end end context 'when update' do let(:runtime) { create(:runtime) } - let(:data_type) do - create(:data_type_identifier, runtime: runtime, data_type: create(:data_type, runtime: runtime)) - end + let(:data_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } let(:existing_runtime_function_definition) do create(:runtime_function_definition, @@ -188,9 +157,7 @@ end let!(:existing_runtime_parameter_definition) do - create(:runtime_parameter_definition, data_type: create(:data_type_identifier, - runtime: runtime, - data_type: create(:data_type, runtime: runtime)), + create(:runtime_parameter_definition, data_type: create(:data_type_identifier, data_type: create(:data_type)), runtime_function_definition: existing_runtime_function_definition) end From 330d3e2a6a652c20665864e507708cecc782ef19 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Mon, 26 May 2025 13:37:18 +0200 Subject: [PATCH 27/54] Adjust models and tests --- Gemfile | 2 +- Gemfile.lock | 4 +- app/models/data_type_identifier.rb | 3 +- app/models/function_generic_mapper.rb | 4 +- .../update_service.rb | 88 ++++++++++++++++--- .../20250525192143_implement_generics.rb | 22 +++-- spec/factories/data_type_identifiers.rb | 1 + spec/factories/function_generic_mappers.rb | 2 +- spec/factories/generic_mappers.rb | 1 + spec/factories/generic_types.rb | 1 + spec/models/data_type_identifier_spec.rb | 1 + spec/models/function_generic_mapper_spec.rb | 1 + spec/models/generic_mapper_spec.rb | 7 +- spec/models/generic_type_spec.rb | 1 + ...untime_function_definition_service_spec.rb | 56 ++++++++++-- 15 files changed, 158 insertions(+), 36 deletions(-) diff --git a/Gemfile b/Gemfile index 5ceadfd1..fa653e3a 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.26' +gem 'tucana', '0.0.27' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 5dec9ce4..729121d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -356,7 +356,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.26) + tucana (0.0.27) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -409,7 +409,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.26) + tucana (= 0.0.27) tzinfo-data RUBY VERSION diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 0451dad5..69503d06 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -3,6 +3,7 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier + belongs_to :runtime, inverse_of: :data_type_identifiers has_many :generic_types, inverse_of: :data_type_identifier has_many :generic_mappers, inverse_of: :data_type_identifier @@ -21,7 +22,7 @@ def to_grpc private def exactly_one_of_generic_key_data_type_id_generic_type_id - values = [generic_key.present?, data_type_id.present?, generic_type_id.present?] + values = [generic_key.present?, data_type.present?, generic_type.present?] return if values.count(true) == 1 errors.add(:base, 'Exactly one of generic_key, data_type_id, or generic_type_id must be present') diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 32489de2..0612a21a 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -4,6 +4,8 @@ class FunctionGenericMapper < ApplicationRecord belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers + belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, + inverse_of: :function_generic_mappers validates :target, presence: true validate :exactly_one_of_generic_key_or_data_type_identifier_id @@ -11,7 +13,7 @@ class FunctionGenericMapper < ApplicationRecord private def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier_id.present?] + values = [generic_key.present?, data_type_identifier.present?] return if values.count(true) == 1 errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 89603888..e61b1c88 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -51,6 +51,7 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.deprecation_messages) db_object.error_types = update_error_types(runtime_function_definition.error_type_identifiers, db_object, t) + db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object) if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -68,31 +69,92 @@ def update_runtime_function_definition(runtime_function_definition, t) end # These mappers can be either generic mappers or generic function mappers. - def find_data_type_identifier(identifier, _generic_mappers, t) - if identifier.data_type_identifier.present? - data_type_identifier = DataTypeIdentifier.find_by(data_type: find_data_type(identifier.data_type_identifier, - t)) + def update_mappers(generic_mappers, runtime_function_definition = nil) + generic_mappers.to_a.map do |generic_mapper| + if generic_mapper.is_a? Tucana::Shared::GenericMapper + mapper = GenericMapper.create_or_find_by(runtime: current_runtime, + target: generic_mapper.target, + generic_key: generic_mapper.generic_key, + data_type_identifier: + (generic_mapper.generic_key.nil? ? data_type_identifier : nil)) - if data_type_identifier.nil? + end + if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper + mapper = FunctionGenericMapper.create_or_find_by( + runtime_id: current_runtime.id, + runtime_function_definition: runtime_function_definition, + data_type_identifier: (generic_mapper.generic_key.nil? ? data_type_identifier : nil), + target: generic_mapper.target, + generic_key: generic_mapper.generic_key, + parameter_id: generic_mapper.parameter_id + ) + end + + if mapper.nil? || !mapper.save t.rollback_and_return! ServiceResponse.error( - message: "Could not find datatype identifier with identifier #{identifier}", - payload: :no_datatype_identifier_for_identifier + message: "Could not find or create generic mapper (#{generic_mapper})", + payload: :error_creating_generic_mapper ) end + mapper + end + end - return data_type_identifier + def find_data_type_identifier(identifier, generic_mappers, t) + if identifier.data_type_identifier.present? + return create_data_type_identifier(t, data_type_id: find_data_type(identifier.data_type_identifier, t).id) end + if identifier.generic_type.present? - return find_data_type_identifier(identifier.generic_type.identifier, identifier.generic_type.generic_mappers, - t) - end - if identifier.generic_key.present? - return DataTypeIdentifier.find_or_create_by(runtime: current_runtime, generic_key: identifier.generic_key) + arr = generic_mappers.to_a + identifier.generic_type.generic_mappers.each do |generic_mapper| + arr << generic_mapper + end + data_type_identifier = find_data_type_identifier(identifier.generic_type.data_type_identifier, arr, t) + + generic_type = GenericType.find_by( + runtime_id: current_runtime.id, + data_type_identifier_id: data_type_identifier.id + ) + if generic_type.nil? + generic_type = GenericType.create( + runtime_id: current_runtime.id, + data_type_identifier_id: data_type_identifier.id + ) + end + + if generic_type.nil? + t.rollback_and_return! ServiceResponse.error( + message: "Could not find generic type with identifier #{identifier.generic_type.data_type_identifier}", + payload: :no_generic_type_for_identifier + ) + end + + generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers)) + + return create_data_type_identifier(t, generic_type_id: generic_type.id) end + return create_data_type_identifier(t, generic_key: identifier.generic_key) if identifier.generic_key.present? raise ArgumentError, "Invalid identifier: #{identifier.inspect}" end + def create_data_type_identifier(t, **kwargs) + data_type_identifier = DataTypeIdentifier.find_by(runtime_id: current_runtime.id, **kwargs) + if data_type_identifier.nil? + data_type_identifier = DataTypeIdentifier.create_or_find_by(runtime_id: current_runtime.id, **kwargs) + end + + if data_type_identifier.nil? + t.rollback_and_return! ServiceResponse.error( + message: "Could not find datatype identifier with #{kwargs}", + payload: :no_datatype_identifier_for_generic_key + ) + end + + data_type_identifier + end + def find_data_type(identifier, t) data_type = DataType.find_by(runtime: current_runtime, identifier: identifier) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 416af4a0..4151d076 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -11,6 +11,8 @@ def change # One of them needs to be set t.text :generic_key, null: true t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -18,6 +20,8 @@ def change create_table :generic_types do |t| t.references :data_type_identifier, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -32,7 +36,9 @@ def change t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', name: check_constraint_name(:generic_mappers, :source, :one_of) - t.references :generic_type, null: false, foreign_key: { to_table: :generic_types, on_delete: :cascade } + t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -48,15 +54,21 @@ def change foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } t.text :generic_key, null: true + t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', + name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.text :target, null: false t.text :parameter_id, null: true - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.references :runtime_parameter_definition, null: true, + foreign_key: { to_table: :runtime_parameter_definitions, + on_delete: :cascade } t.references :runtime_function_definition, null: true, foreign_key: { to_table: :runtime_function_definitions, on_delete: :cascade } + # Unsure if restrict is correct here + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } t.timestamps_with_timezone end @@ -75,10 +87,6 @@ def change add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - # remove_column :runtime_function_definition_error_types, :data_type_id - # add_reference :runtime_function_definition_error_types, :data_type, - # foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: false - remove_column :function_definitions, :return_type_id add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true diff --git a/spec/factories/data_type_identifiers.rb b/spec/factories/data_type_identifiers.rb index 7ef0303c..f3103216 100644 --- a/spec/factories/data_type_identifiers.rb +++ b/spec/factories/data_type_identifiers.rb @@ -5,5 +5,6 @@ generic_key { nil } data_type { nil } generic_type { nil } + runtime end end diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb index e5579f87..96e28ab6 100644 --- a/spec/factories/function_generic_mappers.rb +++ b/spec/factories/function_generic_mappers.rb @@ -3,7 +3,7 @@ FactoryBot.define do factory :function_generic_mapper do target { nil } - parameter_id { nil } + runtime_parameter_definition { nil } generic_key { nil } data_type_identifier { nil } end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index b601b3c5..33a5cd58 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :generic_mapper do + runtime target { nil } generic_key { nil } data_type_identifier { nil } diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index f26bc778..a4eef104 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -2,6 +2,7 @@ FactoryBot.define do factory :generic_type do + runtime generic_mappers { [] } data_type_identifier { nil } end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index e27ff00e..11d422d7 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -7,6 +7,7 @@ describe 'associations' do it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } + it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_types) } it { is_expected.to have_many(:generic_mappers) } end diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index f22a01fa..c83b8546 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -5,6 +5,7 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do it { is_expected.to belong_to(:data_type_identifier).optional } + it { is_expected.to belong_to(:runtime_parameter_definition).optional } it { is_expected.to belong_to(:runtime_function_definition).class_name('RuntimeFunctionDefinition') diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index 419407c7..bdc7873f 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -5,7 +5,8 @@ RSpec.describe GenericMapper do describe 'associations' do - it { is_expected.to belong_to(:generic_type) } + it { is_expected.to belong_to(:generic_type).optional } + it { is_expected.to belong_to(:runtime) } it { is_expected.to belong_to(:data_type_identifier).optional } end @@ -33,7 +34,7 @@ gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, generic_type: generic_type) expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') end it 'is invalid when both generic_key and data_type_identifier are set' do @@ -42,7 +43,7 @@ gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, generic_type: generic_type) expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') + expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') end end end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index 9a2aae5c..b97b9ca7 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -6,6 +6,7 @@ RSpec.describe GenericType do describe 'associations' do it { is_expected.to belong_to(:data_type_identifier) } + it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_mappers) } end diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 2e70e488..5473a97a 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -10,8 +10,20 @@ describe 'Update' do context 'when create' do let(:runtime) { create(:runtime) } - let(:parameter_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } - let(:return_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } + let!(:parameter_type) do + create(:data_type_identifier, runtime: runtime, data_type: create(:data_type, runtime: runtime)) + end + + let!(:generic_type) do + create(:generic_type, + runtime: runtime, + data_type_identifier: + create(:data_type_identifier, + runtime: runtime, + data_type: create(:data_type, + runtime: runtime).reload).reload).reload + end + let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload } let(:error_type) { create(:data_type, runtime: runtime) } let(:runtime_functions) do @@ -31,8 +43,21 @@ { code: 'de_DE', content: 'Eine Deprecationsmeldung' } ], return_type_identifier: { - data_type_identifier: return_type.data_type.identifier, + generic_type: { + data_type_identifier: { # Without reloads it just fails + data_type_identifier: return_type.reload.generic_type + .reload.data_type_identifier.reload.data_type.reload.identifier, + }, + generic_mappers: [{ generic_key: 'T', target: 'V' }], + }, }, + generic_mappers: [ + { + generic_key: 'X', + target: 'Y', + parameter_id: 'some_id', + } + ], error_type_identifiers: [error_type.identifier], runtime_parameter_definitions: [ { @@ -63,9 +88,16 @@ it 'creates a correct functions' do expect(stub.update(message, authorization(runtime)).success).to be(true) + expect(GenericMapper.count).to eq(1) + expect(GenericMapper.last.generic_key).to eq('T') + expect(GenericMapper.last.target).to eq('V') + + expect(GenericType.count).to eq(1) + function = RuntimeFunctionDefinition.last expect(function.runtime_name).to eq('runtime_function_id') - expect(function.return_type.data_type.identifier).to eq(return_type.data_type.identifier) + expect(function.return_type.generic_type.reload.data_type_identifier.data_type.identifier) + .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) expect(function.names.first.content).to eq('Eine Funktion') expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation') @@ -83,19 +115,27 @@ expect(function_definition.names.first.content).to eq('Eine Funktion') expect(function_definition.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function_definition.documentations.first.content).to eq('Eine Funktionsdokumentation') - expect(function_definition.return_type.data_type.identifier).to eq(return_type.data_type.identifier) + expect(function_definition.return_type.generic_type.reload.data_type_identifier.data_type.identifier) + .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) parameter_definition = ParameterDefinition.first expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter_definition.names.first.content).to eq('Ein Parameter') expect(parameter_definition.descriptions.first.content).to eq('Eine Parameterbeschreibung') expect(parameter_definition.documentations.first.content).to eq('Eine Parameterdokumentation') expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) + + expect(FunctionGenericMapper.count).to eq(1) + expect(FunctionGenericMapper.last.generic_key).to eq('X') + expect(FunctionGenericMapper.last.target).to eq('Y') + expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end end context 'when update' do let(:runtime) { create(:runtime) } - let(:data_type) { create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)) } + let(:data_type) do + create(:data_type_identifier, runtime: runtime, data_type: create(:data_type, runtime: runtime)) + end let(:existing_runtime_function_definition) do create(:runtime_function_definition, @@ -157,7 +197,9 @@ end let!(:existing_runtime_parameter_definition) do - create(:runtime_parameter_definition, data_type: create(:data_type_identifier, data_type: create(:data_type)), + create(:runtime_parameter_definition, data_type: create(:data_type_identifier, + runtime: runtime, + data_type: create(:data_type, runtime: runtime)), runtime_function_definition: existing_runtime_function_definition) end From 469305747a6baef989b4279327d2cca90e27bc4e Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 17:32:46 +0200 Subject: [PATCH 28/54] Fix singleton methods and runtime assignments --- app/grpc/concerns/grpc_stream_handler.rb | 10 +++++----- app/grpc/flow_handler.rb | 12 +++++++++--- app/models/runtime.rb | 3 ++- spec/models/namespace_project_spec.rb | 2 ++ spec/models/runtime_spec.rb | 2 ++ 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/grpc/concerns/grpc_stream_handler.rb b/app/grpc/concerns/grpc_stream_handler.rb index 3f82334c..86441fae 100644 --- a/app/grpc/concerns/grpc_stream_handler.rb +++ b/app/grpc/concerns/grpc_stream_handler.rb @@ -13,15 +13,15 @@ def grpc_stream(method) end define_singleton_method("send_#{method}") do |grpc_object, runtime_id| - logger.info(message: 'Sending data', runtime_id: runtime_id, method: method) + GrpcStreamHandler.logger.info(message: 'Sending data', runtime_id: runtime_id, method: method, grpc_object: grpc_object) - encoded_data = self.class.encoders[method].call(grpc_object) + encoded_data = send('encoders')[method].call(grpc_object) encoded_data64 = Base64.encode64(encoded_data) - logger.info(message: 'Encoded data', runtime_id: runtime_id, method: method, encoded_data: encoded_data64) + GrpcStreamHandler.logger.info(message: 'Encoded data', runtime_id: runtime_id, method: method, encoded_data: encoded_data64) ActiveRecord::Base.connection.raw_connection - .exec("NOTIFY grpc_streams, '#{self.class},#{method},#{runtime_id},#{encoded_data64}'") + .exec("NOTIFY grpc_streams, '#{self},#{method},#{runtime_id},#{encoded_data64}'") end define_singleton_method("end_#{method}") do |runtime_id| ActiveRecord::Base.connection.raw_connection @@ -55,7 +55,7 @@ def self.listen! decoded_data = :end else data = Base64.decode64(encoded_data64) - decoded_data = clazz.decoders[method_name].call(data) + decoded_data = clazz.send('decoders')[method_name].call(data) end queues = GrpcStreamHandler.yielders.dig(clazz, method_name, runtime_id.to_i) diff --git a/app/grpc/flow_handler.rb b/app/grpc/flow_handler.rb index aa40708a..8345b7e0 100644 --- a/app/grpc/flow_handler.rb +++ b/app/grpc/flow_handler.rb @@ -11,8 +11,13 @@ def self.update_started(runtime_id) runtime.connected! runtime.save - flows = NamespaceProject.where(id: runtime.projects.ids).flat_map do |project| - project.flows.map(&:to_grpc) + logger.info(message: 'Runtime connected', runtime_id: runtime.id) + + flows = [] + runtime.projects.each do |project| + project.flows.each do |flow| + flows << flow.to_grpc + end end send_update( @@ -20,7 +25,8 @@ def self.update_started(runtime_id) flows: Tucana::Shared::Flows.new( flows: flows ) - ) + ), + runtime.id ) end diff --git a/app/models/runtime.rb b/app/models/runtime.rb index 13df93e1..d1099787 100644 --- a/app/models/runtime.rb +++ b/app/models/runtime.rb @@ -10,7 +10,8 @@ class Runtime < ApplicationRecord enum :status, { disconnected: 0, connected: 1 }, default: :disconnected has_many :project_assignments, class_name: 'NamespaceProjectRuntimeAssignment', inverse_of: :runtime - has_many :projects, class_name: 'NamespaceProject', through: :project_assignments, inverse_of: :runtimes + has_many :projects, class_name: 'NamespaceProject', through: :project_assignments, source: :namespace_project, + inverse_of: :runtimes has_many :data_types, inverse_of: :runtime has_many :data_type_identifiers, inverse_of: :runtime diff --git a/spec/models/namespace_project_spec.rb b/spec/models/namespace_project_spec.rb index 1e5210e7..fb5f887a 100644 --- a/spec/models/namespace_project_spec.rb +++ b/spec/models/namespace_project_spec.rb @@ -8,6 +8,8 @@ describe 'associations' do it { is_expected.to belong_to(:namespace).required } it { is_expected.to have_many(:role_assignments).class_name('NamespaceRoleProjectAssignment').inverse_of(:project) } + it { is_expected.to have_many(:runtime_assignments).class_name('NamespaceProjectRuntimeAssignment').inverse_of(:namespace_project) } + it { is_expected.to have_many(:runtimes).through(:runtime_assignments).inverse_of(:projects) } it do is_expected.to have_many(:assigned_roles).class_name('NamespaceRole') diff --git a/spec/models/runtime_spec.rb b/spec/models/runtime_spec.rb index d2fd63cb..c767c6b5 100644 --- a/spec/models/runtime_spec.rb +++ b/spec/models/runtime_spec.rb @@ -12,6 +12,8 @@ it { is_expected.to have_many(:generic_types).inverse_of(:runtime) } it { is_expected.to have_many(:generic_mappers).inverse_of(:runtime) } it { is_expected.to have_many(:flow_types).inverse_of(:runtime) } + it { is_expected.to have_many(:project_assignments).class_name('NamespaceProjectRuntimeAssignment').inverse_of(:runtime) } + it { is_expected.to have_many(:projects).class_name('NamespaceProject').through(:project_assignments).inverse_of(:runtimes) } end describe 'validations' do From 418567ecc26e8820edec409a1530813c5be7db14 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 18:06:30 +0200 Subject: [PATCH 29/54] Add logging capabilities to FlowHandler by including Loggable module --- app/grpc/flow_handler.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/grpc/flow_handler.rb b/app/grpc/flow_handler.rb index 8345b7e0..7690715f 100644 --- a/app/grpc/flow_handler.rb +++ b/app/grpc/flow_handler.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class FlowHandler < Tucana::Sagittarius::FlowService::Service + include Code0::ZeroTrack::Loggable include GrpcHandler include GrpcStreamHandler From b4893a9fe0adf1cae922686e21c0e83c19131198 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 18:07:24 +0200 Subject: [PATCH 30/54] Add logging for data type updates and improve datatype retrieval method --- app/grpc/data_type_handler.rb | 3 +++ app/services/runtimes/data_types/update_service.rb | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/grpc/data_type_handler.rb b/app/grpc/data_type_handler.rb index 2b2e7e77..93270991 100644 --- a/app/grpc/data_type_handler.rb +++ b/app/grpc/data_type_handler.rb @@ -2,12 +2,15 @@ class DataTypeHandler < Tucana::Sagittarius::DataTypeService::Service include GrpcHandler + include Code0::ZeroTrack::Loggable def update(request, _call) current_runtime = Runtime.find(Code0::ZeroTrack::Context.current[:runtime][:id]) response = Runtimes::DataTypes::UpdateService.new(current_runtime, request.data_types).execute + logger.info(message: 'Data types updated', runtime_id: current_runtime.id, response: response) + Tucana::Sagittarius::DataTypeUpdateResponse.new(success: response.success?) end end diff --git a/app/services/runtimes/data_types/update_service.rb b/app/services/runtimes/data_types/update_service.rb index 70473f20..8069b2e5 100644 --- a/app/services/runtimes/data_types/update_service.rb +++ b/app/services/runtimes/data_types/update_service.rb @@ -63,7 +63,7 @@ def update_datatype(data_type, t) end def find_datatype(identifier, t) - data_type = DataType.find_by(runtime: current_runtime, identifier: identifier) + data_type = DataType.find_or_initialize_by(runtime: current_runtime, identifier: identifier) if data_type.nil? t.rollback_and_return! ServiceResponse.error(message: "Could not find datatype with identifier #{identifier}", From b7c19f6e183bb6f9357050449f8e9652b6af49f9 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 18:23:11 +0200 Subject: [PATCH 31/54] Fix formatting --- app/grpc/concerns/grpc_stream_handler.rb | 6 ++++-- app/models/runtime.rb | 2 +- spec/models/namespace_project_spec.rb | 7 ++++++- spec/models/runtime_spec.rb | 12 ++++++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/app/grpc/concerns/grpc_stream_handler.rb b/app/grpc/concerns/grpc_stream_handler.rb index 86441fae..10316a3a 100644 --- a/app/grpc/concerns/grpc_stream_handler.rb +++ b/app/grpc/concerns/grpc_stream_handler.rb @@ -13,12 +13,14 @@ def grpc_stream(method) end define_singleton_method("send_#{method}") do |grpc_object, runtime_id| - GrpcStreamHandler.logger.info(message: 'Sending data', runtime_id: runtime_id, method: method, grpc_object: grpc_object) + GrpcStreamHandler.logger.info(message: 'Sending data', runtime_id: runtime_id, method: method, + grpc_object: grpc_object) encoded_data = send('encoders')[method].call(grpc_object) encoded_data64 = Base64.encode64(encoded_data) - GrpcStreamHandler.logger.info(message: 'Encoded data', runtime_id: runtime_id, method: method, encoded_data: encoded_data64) + GrpcStreamHandler.logger.info(message: 'Encoded data', runtime_id: runtime_id, method: method, + encoded_data: encoded_data64) ActiveRecord::Base.connection.raw_connection .exec("NOTIFY grpc_streams, '#{self},#{method},#{runtime_id},#{encoded_data64}'") diff --git a/app/models/runtime.rb b/app/models/runtime.rb index d1099787..eee6ffa8 100644 --- a/app/models/runtime.rb +++ b/app/models/runtime.rb @@ -11,7 +11,7 @@ class Runtime < ApplicationRecord has_many :project_assignments, class_name: 'NamespaceProjectRuntimeAssignment', inverse_of: :runtime has_many :projects, class_name: 'NamespaceProject', through: :project_assignments, source: :namespace_project, - inverse_of: :runtimes + inverse_of: :runtimes has_many :data_types, inverse_of: :runtime has_many :data_type_identifiers, inverse_of: :runtime diff --git a/spec/models/namespace_project_spec.rb b/spec/models/namespace_project_spec.rb index fb5f887a..b7ff3cd7 100644 --- a/spec/models/namespace_project_spec.rb +++ b/spec/models/namespace_project_spec.rb @@ -8,7 +8,12 @@ describe 'associations' do it { is_expected.to belong_to(:namespace).required } it { is_expected.to have_many(:role_assignments).class_name('NamespaceRoleProjectAssignment').inverse_of(:project) } - it { is_expected.to have_many(:runtime_assignments).class_name('NamespaceProjectRuntimeAssignment').inverse_of(:namespace_project) } + + it { + is_expected.to have_many(:runtime_assignments).class_name('NamespaceProjectRuntimeAssignment') + .inverse_of(:namespace_project) + } + it { is_expected.to have_many(:runtimes).through(:runtime_assignments).inverse_of(:projects) } it do diff --git a/spec/models/runtime_spec.rb b/spec/models/runtime_spec.rb index c767c6b5..395b5e21 100644 --- a/spec/models/runtime_spec.rb +++ b/spec/models/runtime_spec.rb @@ -12,8 +12,16 @@ it { is_expected.to have_many(:generic_types).inverse_of(:runtime) } it { is_expected.to have_many(:generic_mappers).inverse_of(:runtime) } it { is_expected.to have_many(:flow_types).inverse_of(:runtime) } - it { is_expected.to have_many(:project_assignments).class_name('NamespaceProjectRuntimeAssignment').inverse_of(:runtime) } - it { is_expected.to have_many(:projects).class_name('NamespaceProject').through(:project_assignments).inverse_of(:runtimes) } + + it { + is_expected.to have_many(:project_assignments).class_name('NamespaceProjectRuntimeAssignment') + .inverse_of(:runtime) + } + + it { + is_expected.to have_many(:projects).class_name('NamespaceProject').through(:project_assignments) + .inverse_of(:runtimes) + } end describe 'validations' do From 0764b7ded1981bc56f311a83981e5b28ccb74c5c Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Wed, 28 May 2025 20:44:25 +0200 Subject: [PATCH 32/54] Create graphql input/types --- .../namespaces/projects/flows/create.rb | 21 ++++++++++++ .../types/data_type_identifier_type.rb | 23 +++++++++++++ app/graphql/types/flow_setting_type.rb | 20 ++++++++++++ app/graphql/types/flow_type.rb | 29 +++++++++++++++++ app/graphql/types/generic_key_type.rb | 13 ++++++++ app/graphql/types/generic_mapper_type.rb | 14 ++++++++ app/graphql/types/generic_type_type.rb | 15 +++++++++ .../input/data_type_identifier_input_type.rb | 17 ++++++++++ .../types/input/data_type_type_input.rb | 22 +++++++++++++ app/graphql/types/input/flow_input_type.rb | 20 ++++++++++++ .../types/input/flow_setting_input_type.rb | 12 +++++++ .../types/input/generic_mapper_input_type.rb | 15 +++++++++ .../types/input/generic_type_input_type.rb | 15 +++++++++ .../node_function_definition_input_type.rb | 14 ++++++++ .../types/input/node_function_input_type.rb | 16 ++++++++++ .../node_parameter_definition_input_type.rb | 14 ++++++++ .../types/input/node_parameter_input_type.rb | 14 ++++++++ .../input/node_parameter_value_input_type.rb | 16 ++++++++++ .../types/input/reference_path_input_type.rb | 14 ++++++++ .../types/input/reference_value_input_type.rb | 20 ++++++++++++ ...ype_rule_contains_key_config_input_type.rb | 16 ++++++++++ ...pe_rule_contains_type_config_input_type.rb | 15 +++++++++ .../input/rules/data_type_rule_input_type.rb | 18 +++++++++++ app/graphql/types/literal_value_type.rb | 13 ++++++++ app/graphql/types/mutation_type.rb | 1 + .../types/node_function_definition_type.rb | 14 ++++++++ app/graphql/types/node_function_type.rb | 24 ++++++++++++++ .../types/node_parameter_definition_type.rb | 14 ++++++++ app/graphql/types/node_parameter_type.rb | 32 +++++++++++++++++++ .../types/node_parameter_value_type.rb | 23 +++++++++++++ app/graphql/types/reference_path_type.rb | 15 +++++++++ app/graphql/types/reference_value_type.rb | 22 +++++++++++++ .../input_object/datatypeidentifierinput.md | 13 ++++++++ .../datatyperulecontainskeyconfiginput.md | 12 +++++++ .../datatyperulecontainstypeconfiginput.md | 11 +++++++ .../graphql/input_object/datatyperuleinput.md | 12 +++++++ .../graphql/input_object/datatypetypeinput.md | 16 ++++++++++ docs/graphql/input_object/flowinput.md | 15 +++++++++ docs/graphql/input_object/flowsettinginput.md | 11 +++++++ .../input_object/genericmapperinput.md | 12 +++++++ docs/graphql/input_object/generictypeinput.md | 12 +++++++ .../nodefunctiondefinitioninput.md | 12 +++++++ .../graphql/input_object/nodefunctioninput.md | 13 ++++++++ .../nodeparameterdefinitioninput.md | 12 +++++++ .../input_object/nodeparameterinput.md | 12 +++++++ .../input_object/nodeparametervalueinput.md | 13 ++++++++ .../input_object/referencepathinput.md | 12 +++++++ .../input_object/referencevalueinput.md | 15 +++++++++ .../mutation/namespacesprojectsflowscreate.md | 20 ++++++++++++ docs/graphql/object/flow.md | 20 ++++++++++++ docs/graphql/object/flowsetting.md | 16 ++++++++++ docs/graphql/object/generickey.md | 14 ++++++++ docs/graphql/object/genericmapper.md | 15 +++++++++ docs/graphql/object/generictype.md | 15 +++++++++ docs/graphql/object/literalvalue.md | 14 ++++++++ docs/graphql/object/nodefunction.md | 17 ++++++++++ docs/graphql/object/nodefunctiondefinition.md | 15 +++++++++ docs/graphql/object/nodeparameter.md | 16 ++++++++++ .../graphql/object/nodeparameterconnection.md | 15 +++++++++ .../graphql/object/nodeparameterdefinition.md | 15 +++++++++ docs/graphql/object/nodeparameteredge.md | 13 ++++++++ docs/graphql/object/referencepath.md | 16 ++++++++++ docs/graphql/object/referencevalue.md | 19 +++++++++++ docs/graphql/scalar/flowid.md | 5 +++ docs/graphql/scalar/flowsettingid.md | 5 +++ docs/graphql/scalar/json.md | 5 +++ docs/graphql/scalar/nodefunctionid.md | 5 +++ docs/graphql/scalar/nodeparameterid.md | 5 +++ docs/graphql/scalar/referencepathid.md | 5 +++ docs/graphql/scalar/referencevalueid.md | 5 +++ docs/graphql/union/datatypeidentifier.md | 11 +++++++ docs/graphql/union/nodeparametervalue.md | 11 +++++++ 72 files changed, 1051 insertions(+) create mode 100644 app/graphql/mutations/namespaces/projects/flows/create.rb create mode 100644 app/graphql/types/data_type_identifier_type.rb create mode 100644 app/graphql/types/flow_setting_type.rb create mode 100644 app/graphql/types/flow_type.rb create mode 100644 app/graphql/types/generic_key_type.rb create mode 100644 app/graphql/types/generic_mapper_type.rb create mode 100644 app/graphql/types/generic_type_type.rb create mode 100644 app/graphql/types/input/data_type_identifier_input_type.rb create mode 100644 app/graphql/types/input/data_type_type_input.rb create mode 100644 app/graphql/types/input/flow_input_type.rb create mode 100644 app/graphql/types/input/flow_setting_input_type.rb create mode 100644 app/graphql/types/input/generic_mapper_input_type.rb create mode 100644 app/graphql/types/input/generic_type_input_type.rb create mode 100644 app/graphql/types/input/node_function_definition_input_type.rb create mode 100644 app/graphql/types/input/node_function_input_type.rb create mode 100644 app/graphql/types/input/node_parameter_definition_input_type.rb create mode 100644 app/graphql/types/input/node_parameter_input_type.rb create mode 100644 app/graphql/types/input/node_parameter_value_input_type.rb create mode 100644 app/graphql/types/input/reference_path_input_type.rb create mode 100644 app/graphql/types/input/reference_value_input_type.rb create mode 100644 app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb create mode 100644 app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb create mode 100644 app/graphql/types/input/rules/data_type_rule_input_type.rb create mode 100644 app/graphql/types/literal_value_type.rb create mode 100644 app/graphql/types/node_function_definition_type.rb create mode 100644 app/graphql/types/node_function_type.rb create mode 100644 app/graphql/types/node_parameter_definition_type.rb create mode 100644 app/graphql/types/node_parameter_type.rb create mode 100644 app/graphql/types/node_parameter_value_type.rb create mode 100644 app/graphql/types/reference_path_type.rb create mode 100644 app/graphql/types/reference_value_type.rb create mode 100644 docs/graphql/input_object/datatypeidentifierinput.md create mode 100644 docs/graphql/input_object/datatyperulecontainskeyconfiginput.md create mode 100644 docs/graphql/input_object/datatyperulecontainstypeconfiginput.md create mode 100644 docs/graphql/input_object/datatyperuleinput.md create mode 100644 docs/graphql/input_object/datatypetypeinput.md create mode 100644 docs/graphql/input_object/flowinput.md create mode 100644 docs/graphql/input_object/flowsettinginput.md create mode 100644 docs/graphql/input_object/genericmapperinput.md create mode 100644 docs/graphql/input_object/generictypeinput.md create mode 100644 docs/graphql/input_object/nodefunctiondefinitioninput.md create mode 100644 docs/graphql/input_object/nodefunctioninput.md create mode 100644 docs/graphql/input_object/nodeparameterdefinitioninput.md create mode 100644 docs/graphql/input_object/nodeparameterinput.md create mode 100644 docs/graphql/input_object/nodeparametervalueinput.md create mode 100644 docs/graphql/input_object/referencepathinput.md create mode 100644 docs/graphql/input_object/referencevalueinput.md create mode 100644 docs/graphql/mutation/namespacesprojectsflowscreate.md create mode 100644 docs/graphql/object/flow.md create mode 100644 docs/graphql/object/flowsetting.md create mode 100644 docs/graphql/object/generickey.md create mode 100644 docs/graphql/object/genericmapper.md create mode 100644 docs/graphql/object/generictype.md create mode 100644 docs/graphql/object/literalvalue.md create mode 100644 docs/graphql/object/nodefunction.md create mode 100644 docs/graphql/object/nodefunctiondefinition.md create mode 100644 docs/graphql/object/nodeparameter.md create mode 100644 docs/graphql/object/nodeparameterconnection.md create mode 100644 docs/graphql/object/nodeparameterdefinition.md create mode 100644 docs/graphql/object/nodeparameteredge.md create mode 100644 docs/graphql/object/referencepath.md create mode 100644 docs/graphql/object/referencevalue.md create mode 100644 docs/graphql/scalar/flowid.md create mode 100644 docs/graphql/scalar/flowsettingid.md create mode 100644 docs/graphql/scalar/json.md create mode 100644 docs/graphql/scalar/nodefunctionid.md create mode 100644 docs/graphql/scalar/nodeparameterid.md create mode 100644 docs/graphql/scalar/referencepathid.md create mode 100644 docs/graphql/scalar/referencevalueid.md create mode 100644 docs/graphql/union/datatypeidentifier.md create mode 100644 docs/graphql/union/nodeparametervalue.md diff --git a/app/graphql/mutations/namespaces/projects/flows/create.rb b/app/graphql/mutations/namespaces/projects/flows/create.rb new file mode 100644 index 00000000..96202386 --- /dev/null +++ b/app/graphql/mutations/namespaces/projects/flows/create.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Mutations + module Namespaces + module Projects + module Flows + class Create < BaseMutation + description 'Creates a new flow.' + + field :flow, Types::FlowType, null: true, description: 'The newly created flow.' + + argument :flow, Types::Input::FlowInputType + + def resolve(namespace_id:, **params) + # TODO + end + end + end + end + end +end diff --git a/app/graphql/types/data_type_identifier_type.rb b/app/graphql/types/data_type_identifier_type.rb new file mode 100644 index 00000000..8f397986 --- /dev/null +++ b/app/graphql/types/data_type_identifier_type.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Types + class DataTypeIdentifierType < Types::BaseUnion + description 'Represents a data type identifier.' + + possible_types Types::GenericTypeType, Types::DataTypeType, Types::GenericKeyType, + description: 'The identifier can be a generic type, a data type, or a generic key.' + + def self.resolve_type(object, _context) + case object + when GenericType + Types::GenericTypeType + when DataType + Types::DataTypeType + when GenericKey + Types::GenericKeyType + else + raise "Unexpected value type: #{object.class}" + end + end + end +end diff --git a/app/graphql/types/flow_setting_type.rb b/app/graphql/types/flow_setting_type.rb new file mode 100644 index 00000000..30f12cc3 --- /dev/null +++ b/app/graphql/types/flow_setting_type.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Types + class FlowSettingType < Types::BaseObject + description 'Represents a flow setting' + + authorize :read_flow + + field :database_id, Types::GlobalIdType[::FlowSetting], null: false, + description: 'The global ID of the flow setting' + field :value, GraphQL::Types::JSON, null: false, method: :object, description: 'The value of the flow setting' + + def database_id + object.id.to_global_id.to_s + end + + id_field FlowSetting + timestamps + end +end diff --git a/app/graphql/types/flow_type.rb b/app/graphql/types/flow_type.rb new file mode 100644 index 00000000..4fd05c2f --- /dev/null +++ b/app/graphql/types/flow_type.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Types + class FlowType < Types::BaseObject + description 'Represents a flow' + + authorize :read_flow + + field :flow_id, Types::GlobalIdType[::Flow], null: false, description: 'The global ID of the flow' + # field :name, String, null: false does exist in pictor but not in grpc + field :input_type, Types::DataTypeType, null: true, description: 'The input data type of the flow' + field :return_type, Types::DataTypeType, null: true, description: 'The return data type of the flow' + field :settings, [Types::FlowSettingType], null: true, method: :flow_settings, + description: 'The settings of the flow' + field :starting_node, Types::NodeFunctionType, null: false, description: 'The starting node of the flow' + field :type, String, null: false, description: 'The identifier of the flow type' # identifier of the flow_type + + def flow_id + object.id.to_global_id.to_s + end + + def type + object.flow_type.identifier + end + + id_field Flow + timestamps + end +end diff --git a/app/graphql/types/generic_key_type.rb b/app/graphql/types/generic_key_type.rb new file mode 100644 index 00000000..331f4ab0 --- /dev/null +++ b/app/graphql/types/generic_key_type.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Types + class GenericKeyType < Types::BaseObject + description 'Represents a key for a generic value.' + + authorize :read_flow + + field :generic_key, String, null: false, description: 'The key of the generic value.' + + timestamps + end +end diff --git a/app/graphql/types/generic_mapper_type.rb b/app/graphql/types/generic_mapper_type.rb new file mode 100644 index 00000000..c346790a --- /dev/null +++ b/app/graphql/types/generic_mapper_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + class GenericMapperType < Types::BaseObject + description 'Represents a mapping between a source data type and a target key for generic values.' + + authorize :read_flow + + field :source, Types::DataTypeIdentifierType, null: false, description: 'The source data type identifier.' + field :target, String, null: false, description: 'The target key for the generic value.' + + timestamps + end +end diff --git a/app/graphql/types/generic_type_type.rb b/app/graphql/types/generic_type_type.rb new file mode 100644 index 00000000..fa4ee06c --- /dev/null +++ b/app/graphql/types/generic_type_type.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + class GenericTypeType < Types::BaseObject + description 'Represents a generic type that can be used in various contexts.' + + authorize :read_flow + + field :data_type, Types::DataTypeType, null: false, description: 'The data type associated with this generic type.' + field :generic_mappers, [Types::GenericMapperType], null: false, + description: 'The mappers associated with this generic type.' + + timestamps + end +end diff --git a/app/graphql/types/input/data_type_identifier_input_type.rb b/app/graphql/types/input/data_type_identifier_input_type.rb new file mode 100644 index 00000000..c8e5be82 --- /dev/null +++ b/app/graphql/types/input/data_type_identifier_input_type.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Types + module Input + class DataTypeIdentifierInputType < Types::BaseInputObject + description 'Input type for data type identifier' + + argument :data_type_identifier, String, required: false, + description: 'Data type ID' + argument :generic_key, String, required: false, + description: 'Generic key value' + argument :generic_type, Types::Input::GenericTypeInputType, required: false, + description: 'Generic type information' + + end + end +end diff --git a/app/graphql/types/input/data_type_type_input.rb b/app/graphql/types/input/data_type_type_input.rb new file mode 100644 index 00000000..b2fce072 --- /dev/null +++ b/app/graphql/types/input/data_type_type_input.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Types + module Input + class DataTypeTypeInput < Types::BaseInputObject + description 'Represents a DataType' + + argument :identifier, String, required: true, description: 'The identifier scoped to the namespace' + argument :namespace_id, Types::GlobalIdType[::Namespace], required: true, + description: 'The namespace where this datatype belongs to' + argument :variant, Types::DataTypeVariantEnum, required: true, description: 'The type of the datatype' + + argument :generic_keys, [String], required: false, description: 'The generic keys for the datatype' + + argument :rules, [Rules::DataTypeRuleInputType], required: false, description: 'The rules for the datatype' + + argument :parent_type_identifier, String, required: false, + description: 'The identifier of the parent data type, if any' + + end + end +end diff --git a/app/graphql/types/input/flow_input_type.rb b/app/graphql/types/input/flow_input_type.rb new file mode 100644 index 00000000..6ee2c830 --- /dev/null +++ b/app/graphql/types/input/flow_input_type.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Types + module Input + class FlowInputType < Types::BaseInputObject + description 'Input type for creating or updating a flow' + + argument :input_type_id, ID, required: false, + description: 'The ID of the input data type' + argument :return_type_id, ID, required: false, + description: 'The ID of the return data type' + argument :settings, [Types::Input::FlowSettingInputType], required: false, + description: 'The settings of the flow' + argument :starting_node, Types::Input::NodeFunctionInputType, required: true, + description: 'The starting node of the flow' + argument :type, String, required: true, + description: 'The identifier of the flow type' + end + end +end diff --git a/app/graphql/types/input/flow_setting_input_type.rb b/app/graphql/types/input/flow_setting_input_type.rb new file mode 100644 index 00000000..259fc0d0 --- /dev/null +++ b/app/graphql/types/input/flow_setting_input_type.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Types + module Input + class FlowSettingInputType < Types::BaseInputObject + description 'Input type for flow settings' + + argument :value, GraphQL::Types::JSON, required: true, + description: 'The value of the flow setting' + end + end +end diff --git a/app/graphql/types/input/generic_mapper_input_type.rb b/app/graphql/types/input/generic_mapper_input_type.rb new file mode 100644 index 00000000..3ab6f4fa --- /dev/null +++ b/app/graphql/types/input/generic_mapper_input_type.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Input + class GenericMapperInputType < Types::BaseInputObject + description 'Input type for generic mappers' + + argument :source, Types::Input::DataTypeIdentifierInputType, required: true, + description: 'The source data type identifier for the mapper' + + argument :target, Types::Input::DataTypeIdentifierInputType, required: true, + description: 'The target data type identifier for the mapper' + end + end +end diff --git a/app/graphql/types/input/generic_type_input_type.rb b/app/graphql/types/input/generic_type_input_type.rb new file mode 100644 index 00000000..eda9c1e2 --- /dev/null +++ b/app/graphql/types/input/generic_type_input_type.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Input + class GenericTypeInputType < Types::BaseInputObject + description 'Input type for generic type operations.' + + argument :data_type, Types::Input::DataTypeTypeInput, required: true, description: 'The data type associated with this generic type.' + argument :generic_mappers, [Types::Input::GenericMapperInputType], required: true, + description: 'The mappers associated with this generic type.' + + + end + end +end diff --git a/app/graphql/types/input/node_function_definition_input_type.rb b/app/graphql/types/input/node_function_definition_input_type.rb new file mode 100644 index 00000000..eab09188 --- /dev/null +++ b/app/graphql/types/input/node_function_definition_input_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module Input + class NodeFunctionDefinitionInputType < Types::BaseInputObject + description 'Input type for Node Function definition' + + argument :function_id, String, required: true, + description: 'The function ID of the Node Function' + argument :runtime_function_id, String, required: true, + description: 'The runtime function ID of the Node Function' + end + end +end diff --git a/app/graphql/types/input/node_function_input_type.rb b/app/graphql/types/input/node_function_input_type.rb new file mode 100644 index 00000000..2b033c1a --- /dev/null +++ b/app/graphql/types/input/node_function_input_type.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + module Input + class NodeFunctionInputType < Types::BaseInputObject + description 'Input type for a Node Function' + + argument :function, Types::Input::NodeFunctionDefinitionInputType, required: true, + description: 'The definition of the Node Function' + argument :next_node, Types::Input::NodeFunctionInputType, required: false, + description: 'The next Node Function in the flow' + argument :parameters, [Types::Input::NodeParameterInputType], required: true, + description: 'The parameters of the Node Function' + end + end +end diff --git a/app/graphql/types/input/node_parameter_definition_input_type.rb b/app/graphql/types/input/node_parameter_definition_input_type.rb new file mode 100644 index 00000000..ffdac983 --- /dev/null +++ b/app/graphql/types/input/node_parameter_definition_input_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module Input + class NodeParameterDefinitionInputType < Types::BaseInputObject + description 'Input type for Node parameter definition' + + argument :parameter_id, String, required: true, + description: 'The ID of the parameter' + argument :runtime_parameter_id, String, required: true, + description: 'The runtime ID of the parameter' + end + end +end diff --git a/app/graphql/types/input/node_parameter_input_type.rb b/app/graphql/types/input/node_parameter_input_type.rb new file mode 100644 index 00000000..f877fcb2 --- /dev/null +++ b/app/graphql/types/input/node_parameter_input_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module Input + class NodeParameterInputType < Types::BaseInputObject + description 'Input type for Node parameter' + + argument :definition, Types::Input::NodeParameterDefinitionInputType, required: true, + description: 'The definition of the parameter' + argument :value, Types::Input::NodeParameterValueInputType, required: false, + description: 'The value of the parameter' + end + end +end diff --git a/app/graphql/types/input/node_parameter_value_input_type.rb b/app/graphql/types/input/node_parameter_value_input_type.rb new file mode 100644 index 00000000..11b2d310 --- /dev/null +++ b/app/graphql/types/input/node_parameter_value_input_type.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + module Input + class NodeParameterValueInputType < Types::BaseInputObject + description 'Input type for parameter value' + + argument :function_value, Types::Input::NodeFunctionInputType, required: false, + description: 'The function value of the parameter' + argument :literal_value, GraphQL::Types::JSON, required: false, + description: 'The literal value of the parameter' + argument :reference_value, Types::Input::ReferenceValueInputType, required: false, + description: 'The reference value of the parameter' + end + end +end diff --git a/app/graphql/types/input/reference_path_input_type.rb b/app/graphql/types/input/reference_path_input_type.rb new file mode 100644 index 00000000..bd090d04 --- /dev/null +++ b/app/graphql/types/input/reference_path_input_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module Input + class ReferencePathInputType < Types::BaseInputObject + description 'Input type for reference path' + + argument :array_index, Integer, required: false, + description: 'Array index if applicable' + argument :path, String, required: false, + description: 'The path to the reference in the flow' + end + end +end diff --git a/app/graphql/types/input/reference_value_input_type.rb b/app/graphql/types/input/reference_value_input_type.rb new file mode 100644 index 00000000..d9e59f18 --- /dev/null +++ b/app/graphql/types/input/reference_value_input_type.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Types + module Input + class ReferenceValueInputType < Types::BaseInputObject + description 'Input type for reference value' + + argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, + required: true, description: 'The identifier of the data type this reference value belongs to' + argument :primary_level, Int, required: true, + description: 'The primary level of the reference value' + argument :reference_path, [Types::Input::ReferencePathInputType], + required: true, description: 'The paths associated with this reference value' + argument :secondary_level, Int, required: true, + description: 'The secondary level of the reference value' + argument :tertiary_level, Int, required: false, + description: 'The tertiary level of the reference value' + end + end +end diff --git a/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb b/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb new file mode 100644 index 00000000..dbf92408 --- /dev/null +++ b/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + module Input + module Rules + class DataTypeRuleContainsKeyConfigInputType < Types::BaseInputObject + description 'Input type for Data Type Rule Contains A Key configuration' + + argument :key, String, required: true, description: 'The key to check for in the data type rule' + argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, required: false, + description: 'The identifier of the data type this rule applies to' + + end + end + end +end diff --git a/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb b/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb new file mode 100644 index 00000000..8dc65113 --- /dev/null +++ b/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Input + module Rules + class DataTypeRuleContainsTypeConfigInputType < Types::BaseInputObject + description 'Input type for Data Type Rule Contains Type configuration' + + argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, required: false, + description: 'The identifier of the data type this rule applies to' + + end + end + end +end diff --git a/app/graphql/types/input/rules/data_type_rule_input_type.rb b/app/graphql/types/input/rules/data_type_rule_input_type.rb new file mode 100644 index 00000000..c104ac23 --- /dev/null +++ b/app/graphql/types/input/rules/data_type_rule_input_type.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Types + module Input + module Rules + class DataTypeRuleInputType < Types::BaseInputObject + description 'Input type for Data Type Rule' + + argument :contains_key, DataTypeRuleContainsKeyConfigInputType, required: false, + description: 'Configuration for contains key rule' + + argument :contains_value, DataTypeRuleContainsTypeConfigInputType, required: false, + description: 'Configuration for contains type rule' + + end + end + end +end diff --git a/app/graphql/types/literal_value_type.rb b/app/graphql/types/literal_value_type.rb new file mode 100644 index 00000000..5aee8671 --- /dev/null +++ b/app/graphql/types/literal_value_type.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Types + class LiteralValueType < Types::BaseObject + description 'Represents a literal value, such as a string or number.' + + authorize :read_flow + + field :value, GraphQL::Types::JSON, null: false, description: 'The literal value itself as JSON.' + + timestamps + end +end diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index 32a1dafb..2e2e63ea 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -14,6 +14,7 @@ class MutationType < Types::BaseObject mount_mutation Mutations::Namespaces::Projects::Create mount_mutation Mutations::Namespaces::Projects::Update mount_mutation Mutations::Namespaces::Projects::Delete + mount_mutation Mutations::Namespaces::Projects::Flows::Create mount_mutation Mutations::Namespaces::Roles::AssignAbilities mount_mutation Mutations::Namespaces::Roles::AssignProjects mount_mutation Mutations::Namespaces::Roles::Create diff --git a/app/graphql/types/node_function_definition_type.rb b/app/graphql/types/node_function_definition_type.rb new file mode 100644 index 00000000..c466ea63 --- /dev/null +++ b/app/graphql/types/node_function_definition_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + class NodeFunctionDefinitionType < Types::BaseObject + description 'Represents a Node Function definition' + + authorize :read_flow + + field :function_id, String, null: false, description: 'The function ID of the Node Function' + field :runtime_function_id, String, null: false, description: 'The runtime function ID of the Node Function' + + timestamps + end +end diff --git a/app/graphql/types/node_function_type.rb b/app/graphql/types/node_function_type.rb new file mode 100644 index 00000000..51cdb270 --- /dev/null +++ b/app/graphql/types/node_function_type.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Types + class NodeFunctionType < Types::BaseObject + description 'Represents a Node Function' + + authorize :read_flow + + field :function, Types::NodeFunctionDefinitionType, null: false, description: 'The definition of the Node Function' + field :next_node, Types::NodeFunctionType, null: true, description: 'The next Node Function in the flow' + field :parameters, Types::NodeParameterType.connection_type, null: false, method: :node_parameters, + description: 'The parameters of the Node Function' + + def function + { + function_id: '', + runtime_function_id: object.runtime_function.runtime_name, + } + end + + id_field NodeFunction + timestamps + end +end diff --git a/app/graphql/types/node_parameter_definition_type.rb b/app/graphql/types/node_parameter_definition_type.rb new file mode 100644 index 00000000..b1c92193 --- /dev/null +++ b/app/graphql/types/node_parameter_definition_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + class NodeParameterDefinitionType < Types::BaseObject + description 'Represents a Node parameter definition' + + authorize :read_flow + + field :parameter_id, String, null: false, description: 'The ID of the parameter' + field :runtime_parameter_id, String, null: false, description: 'The runtime ID of the parameter' + + timestamps + end +end diff --git a/app/graphql/types/node_parameter_type.rb b/app/graphql/types/node_parameter_type.rb new file mode 100644 index 00000000..29dee2df --- /dev/null +++ b/app/graphql/types/node_parameter_type.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Types + class NodeParameterType < Types::BaseObject + description 'Represents a Node parameter' + + authorize :read_flow + + field :definition, Types::NodeParameterDefinitionType, null: false, description: 'The definition of the parameter' + field :value, Types::NodeParameterValueType, null: true, description: 'The value of the parameter' + + def definition + { + parameter_id: '', + runtime_parameter_id: object.runtime_function.runtime_name, + } + end + + def value + if object.literal_value.present? + object.literal_value + elsif object.reference_value.present? + object.reference_value + elsif object.function_value_id.present? + object.function_value + end + end + + id_field NodeParameter + timestamps + end +end diff --git a/app/graphql/types/node_parameter_value_type.rb b/app/graphql/types/node_parameter_value_type.rb new file mode 100644 index 00000000..7d48a870 --- /dev/null +++ b/app/graphql/types/node_parameter_value_type.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Types + class NodeParameterValueType < Types::BaseUnion + description 'Represents a parameter value for a node.' + + possible_types Types::LiteralValueType, Types::ReferenceValueType, Types::NodeFunctionType, + description: 'The value can be a literal, a reference, or a node function.' + + def self.resolve_type(object, _context) + case object + when LiteralValue + Types::LiteralValueType + when ReferenceValue + Types::ReferenceValueType + when NodeFunction + Types::NodeFunctionType + else + raise "Unexpected value type: #{object.class}" + end + end + end +end diff --git a/app/graphql/types/reference_path_type.rb b/app/graphql/types/reference_path_type.rb new file mode 100644 index 00000000..a68bc931 --- /dev/null +++ b/app/graphql/types/reference_path_type.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + class ReferencePathType < Types::BaseObject + description 'Represents a reference path in a flow' + + authorize :read_flow + + field :array_index, Integer, null: true, description: 'TODO' + field :path, String, null: true, description: 'The path to the reference in the flow' + + id_field ReferencePath + timestamps + end +end diff --git a/app/graphql/types/reference_value_type.rb b/app/graphql/types/reference_value_type.rb new file mode 100644 index 00000000..8dc8d9f4 --- /dev/null +++ b/app/graphql/types/reference_value_type.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Types + class ReferenceValueType < Types::BaseObject + description 'Represents a reference value in the system.' + + authorize :read_flow + + field :data_type_identifier, Types::DataTypeIdentifierType, + null: false, description: 'The identifier of the data type this reference value belongs to.' + + field :primary_level, Int, null: false, description: 'The primary level of the reference value.' + field :secondary_level, Int, null: false, description: 'The secondary level of the reference value.' + field :tertiary_level, Int, null: true, description: 'The tertiary level of the reference value, if applicable.' + + field :reference_path, [Types::ReferencePathType], null: false, + description: 'The paths associated with this reference value.' + + id_field ReferenceValue + timestamps + end +end diff --git a/docs/graphql/input_object/datatypeidentifierinput.md b/docs/graphql/input_object/datatypeidentifierinput.md new file mode 100644 index 00000000..47f83fa4 --- /dev/null +++ b/docs/graphql/input_object/datatypeidentifierinput.md @@ -0,0 +1,13 @@ +--- +title: DataTypeIdentifierInput +--- + +Input type for data type identifier + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `dataTypeIdentifier` | [`String`](../scalar/string.md) | Data type ID | +| `genericKey` | [`String`](../scalar/string.md) | Generic key value | +| `genericType` | [`GenericTypeInput`](../input_object/generictypeinput.md) | Generic type information | diff --git a/docs/graphql/input_object/datatyperulecontainskeyconfiginput.md b/docs/graphql/input_object/datatyperulecontainskeyconfiginput.md new file mode 100644 index 00000000..74c25d61 --- /dev/null +++ b/docs/graphql/input_object/datatyperulecontainskeyconfiginput.md @@ -0,0 +1,12 @@ +--- +title: DataTypeRuleContainsKeyConfigInput +--- + +Input type for Data Type Rule Contains A Key configuration + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `dataTypeIdentifier` | [`DataTypeIdentifierInput`](../input_object/datatypeidentifierinput.md) | The identifier of the data type this rule applies to | +| `key` | [`String!`](../scalar/string.md) | The key to check for in the data type rule | diff --git a/docs/graphql/input_object/datatyperulecontainstypeconfiginput.md b/docs/graphql/input_object/datatyperulecontainstypeconfiginput.md new file mode 100644 index 00000000..14cb28b6 --- /dev/null +++ b/docs/graphql/input_object/datatyperulecontainstypeconfiginput.md @@ -0,0 +1,11 @@ +--- +title: DataTypeRuleContainsTypeConfigInput +--- + +Input type for Data Type Rule Contains Type configuration + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `dataTypeIdentifier` | [`DataTypeIdentifierInput`](../input_object/datatypeidentifierinput.md) | The identifier of the data type this rule applies to | diff --git a/docs/graphql/input_object/datatyperuleinput.md b/docs/graphql/input_object/datatyperuleinput.md new file mode 100644 index 00000000..0b569307 --- /dev/null +++ b/docs/graphql/input_object/datatyperuleinput.md @@ -0,0 +1,12 @@ +--- +title: DataTypeRuleInput +--- + +Input type for Data Type Rule + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `containsKey` | [`DataTypeRuleContainsKeyConfigInput`](../input_object/datatyperulecontainskeyconfiginput.md) | Configuration for contains key rule | +| `containsValue` | [`DataTypeRuleContainsTypeConfigInput`](../input_object/datatyperulecontainstypeconfiginput.md) | Configuration for contains type rule | diff --git a/docs/graphql/input_object/datatypetypeinput.md b/docs/graphql/input_object/datatypetypeinput.md new file mode 100644 index 00000000..501d38e5 --- /dev/null +++ b/docs/graphql/input_object/datatypetypeinput.md @@ -0,0 +1,16 @@ +--- +title: DataTypeTypeInput +--- + +Represents a DataType + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `genericKeys` | [`[String!]`](../scalar/string.md) | The generic keys for the datatype | +| `identifier` | [`String!`](../scalar/string.md) | The identifier scoped to the namespace | +| `namespaceId` | [`NamespaceID!`](../scalar/namespaceid.md) | The namespace where this datatype belongs to | +| `parentTypeIdentifier` | [`String`](../scalar/string.md) | The identifier of the parent data type, if any | +| `rules` | [`[DataTypeRuleInput!]`](../input_object/datatyperuleinput.md) | The rules for the datatype | +| `variant` | [`DataTypeVariant!`](../enum/datatypevariant.md) | The type of the datatype | diff --git a/docs/graphql/input_object/flowinput.md b/docs/graphql/input_object/flowinput.md new file mode 100644 index 00000000..168c0067 --- /dev/null +++ b/docs/graphql/input_object/flowinput.md @@ -0,0 +1,15 @@ +--- +title: FlowInput +--- + +Input type for creating or updating a flow + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `inputTypeId` | [`ID`](../scalar/id.md) | The ID of the input data type | +| `returnTypeId` | [`ID`](../scalar/id.md) | The ID of the return data type | +| `settings` | [`[FlowSettingInput!]`](../input_object/flowsettinginput.md) | The settings of the flow | +| `startingNode` | [`NodeFunctionInput!`](../input_object/nodefunctioninput.md) | The starting node of the flow | +| `type` | [`String!`](../scalar/string.md) | The identifier of the flow type | diff --git a/docs/graphql/input_object/flowsettinginput.md b/docs/graphql/input_object/flowsettinginput.md new file mode 100644 index 00000000..403e6ee7 --- /dev/null +++ b/docs/graphql/input_object/flowsettinginput.md @@ -0,0 +1,11 @@ +--- +title: FlowSettingInput +--- + +Input type for flow settings + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `value` | [`JSON!`](../scalar/json.md) | The value of the flow setting | diff --git a/docs/graphql/input_object/genericmapperinput.md b/docs/graphql/input_object/genericmapperinput.md new file mode 100644 index 00000000..2316955b --- /dev/null +++ b/docs/graphql/input_object/genericmapperinput.md @@ -0,0 +1,12 @@ +--- +title: GenericMapperInput +--- + +Input type for generic mappers + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `source` | [`DataTypeIdentifierInput!`](../input_object/datatypeidentifierinput.md) | The source data type identifier for the mapper | +| `target` | [`DataTypeIdentifierInput!`](../input_object/datatypeidentifierinput.md) | The target data type identifier for the mapper | diff --git a/docs/graphql/input_object/generictypeinput.md b/docs/graphql/input_object/generictypeinput.md new file mode 100644 index 00000000..446d0cfa --- /dev/null +++ b/docs/graphql/input_object/generictypeinput.md @@ -0,0 +1,12 @@ +--- +title: GenericTypeInput +--- + +Input type for generic type operations. + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `dataType` | [`DataTypeTypeInput!`](../input_object/datatypetypeinput.md) | The data type associated with this generic type. | +| `genericMappers` | [`[GenericMapperInput!]!`](../input_object/genericmapperinput.md) | The mappers associated with this generic type. | diff --git a/docs/graphql/input_object/nodefunctiondefinitioninput.md b/docs/graphql/input_object/nodefunctiondefinitioninput.md new file mode 100644 index 00000000..93ba4433 --- /dev/null +++ b/docs/graphql/input_object/nodefunctiondefinitioninput.md @@ -0,0 +1,12 @@ +--- +title: NodeFunctionDefinitionInput +--- + +Input type for Node Function definition + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `functionId` | [`String!`](../scalar/string.md) | The function ID of the Node Function | +| `runtimeFunctionId` | [`String!`](../scalar/string.md) | The runtime function ID of the Node Function | diff --git a/docs/graphql/input_object/nodefunctioninput.md b/docs/graphql/input_object/nodefunctioninput.md new file mode 100644 index 00000000..05ca758d --- /dev/null +++ b/docs/graphql/input_object/nodefunctioninput.md @@ -0,0 +1,13 @@ +--- +title: NodeFunctionInput +--- + +Input type for a Node Function + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `function` | [`NodeFunctionDefinitionInput!`](../input_object/nodefunctiondefinitioninput.md) | The definition of the Node Function | +| `nextNode` | [`NodeFunctionInput`](../input_object/nodefunctioninput.md) | The next Node Function in the flow | +| `parameters` | [`[NodeParameterInput!]!`](../input_object/nodeparameterinput.md) | The parameters of the Node Function | diff --git a/docs/graphql/input_object/nodeparameterdefinitioninput.md b/docs/graphql/input_object/nodeparameterdefinitioninput.md new file mode 100644 index 00000000..ff91d064 --- /dev/null +++ b/docs/graphql/input_object/nodeparameterdefinitioninput.md @@ -0,0 +1,12 @@ +--- +title: NodeParameterDefinitionInput +--- + +Input type for Node parameter definition + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `parameterId` | [`String!`](../scalar/string.md) | The ID of the parameter | +| `runtimeParameterId` | [`String!`](../scalar/string.md) | The runtime ID of the parameter | diff --git a/docs/graphql/input_object/nodeparameterinput.md b/docs/graphql/input_object/nodeparameterinput.md new file mode 100644 index 00000000..07eb83e7 --- /dev/null +++ b/docs/graphql/input_object/nodeparameterinput.md @@ -0,0 +1,12 @@ +--- +title: NodeParameterInput +--- + +Input type for Node parameter + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `definition` | [`NodeParameterDefinitionInput!`](../input_object/nodeparameterdefinitioninput.md) | The definition of the parameter | +| `value` | [`NodeParameterValueInput`](../input_object/nodeparametervalueinput.md) | The value of the parameter | diff --git a/docs/graphql/input_object/nodeparametervalueinput.md b/docs/graphql/input_object/nodeparametervalueinput.md new file mode 100644 index 00000000..1c98b90a --- /dev/null +++ b/docs/graphql/input_object/nodeparametervalueinput.md @@ -0,0 +1,13 @@ +--- +title: NodeParameterValueInput +--- + +Input type for parameter value + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `functionValue` | [`NodeFunctionInput`](../input_object/nodefunctioninput.md) | The function value of the parameter | +| `literalValue` | [`JSON`](../scalar/json.md) | The literal value of the parameter | +| `referenceValue` | [`ReferenceValueInput`](../input_object/referencevalueinput.md) | The reference value of the parameter | diff --git a/docs/graphql/input_object/referencepathinput.md b/docs/graphql/input_object/referencepathinput.md new file mode 100644 index 00000000..01b3e5d9 --- /dev/null +++ b/docs/graphql/input_object/referencepathinput.md @@ -0,0 +1,12 @@ +--- +title: ReferencePathInput +--- + +Input type for reference path + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `arrayIndex` | [`Int`](../scalar/int.md) | Array index if applicable | +| `path` | [`String`](../scalar/string.md) | The path to the reference in the flow | diff --git a/docs/graphql/input_object/referencevalueinput.md b/docs/graphql/input_object/referencevalueinput.md new file mode 100644 index 00000000..6a072b0b --- /dev/null +++ b/docs/graphql/input_object/referencevalueinput.md @@ -0,0 +1,15 @@ +--- +title: ReferenceValueInput +--- + +Input type for reference value + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `dataTypeIdentifier` | [`DataTypeIdentifierInput!`](../input_object/datatypeidentifierinput.md) | The identifier of the data type this reference value belongs to | +| `primaryLevel` | [`Int!`](../scalar/int.md) | The primary level of the reference value | +| `referencePath` | [`[ReferencePathInput!]!`](../input_object/referencepathinput.md) | The paths associated with this reference value | +| `secondaryLevel` | [`Int!`](../scalar/int.md) | The secondary level of the reference value | +| `tertiaryLevel` | [`Int`](../scalar/int.md) | The tertiary level of the reference value | diff --git a/docs/graphql/mutation/namespacesprojectsflowscreate.md b/docs/graphql/mutation/namespacesprojectsflowscreate.md new file mode 100644 index 00000000..d39efe16 --- /dev/null +++ b/docs/graphql/mutation/namespacesprojectsflowscreate.md @@ -0,0 +1,20 @@ +--- +title: namespacesProjectsFlowsCreate +--- + +Creates a new flow. + +## Arguments + +| Name | Type | Description | +|------|------|-------------| +| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. | +| `flow` | [`FlowInput!`](../input_object/flowinput.md) | | + +## Fields + +| Name | Type | Description | +|------|------|-------------| +| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. | +| `errors` | [`[Error!]!`](../union/error.md) | Errors encountered during execution of the mutation. | +| `flow` | [`Flow`](../object/flow.md) | The newly created flow. | diff --git a/docs/graphql/object/flow.md b/docs/graphql/object/flow.md new file mode 100644 index 00000000..54243be8 --- /dev/null +++ b/docs/graphql/object/flow.md @@ -0,0 +1,20 @@ +--- +title: Flow +--- + +Represents a flow + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this Flow was created | +| `flowId` | [`FlowID!`](../scalar/flowid.md) | The global ID of the flow | +| `id` | [`FlowID!`](../scalar/flowid.md) | Global ID of this Flow | +| `inputType` | [`DataType`](../object/datatype.md) | The input data type of the flow | +| `returnType` | [`DataType`](../object/datatype.md) | The return data type of the flow | +| `settings` | [`[FlowSetting!]`](../object/flowsetting.md) | The settings of the flow | +| `startingNode` | [`NodeFunction!`](../object/nodefunction.md) | The starting node of the flow | +| `type` | [`String!`](../scalar/string.md) | The identifier of the flow type | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this Flow was last updated | + diff --git a/docs/graphql/object/flowsetting.md b/docs/graphql/object/flowsetting.md new file mode 100644 index 00000000..b2eea8c4 --- /dev/null +++ b/docs/graphql/object/flowsetting.md @@ -0,0 +1,16 @@ +--- +title: FlowSetting +--- + +Represents a flow setting + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this FlowSetting was created | +| `databaseId` | [`FlowSettingID!`](../scalar/flowsettingid.md) | The global ID of the flow setting | +| `id` | [`FlowSettingID!`](../scalar/flowsettingid.md) | Global ID of this FlowSetting | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this FlowSetting was last updated | +| `value` | [`JSON!`](../scalar/json.md) | The value of the flow setting | + diff --git a/docs/graphql/object/generickey.md b/docs/graphql/object/generickey.md new file mode 100644 index 00000000..3bcc62fa --- /dev/null +++ b/docs/graphql/object/generickey.md @@ -0,0 +1,14 @@ +--- +title: GenericKey +--- + +Represents a key for a generic value. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this GenericKey was created | +| `genericKey` | [`String!`](../scalar/string.md) | The key of the generic value. | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this GenericKey was last updated | + diff --git a/docs/graphql/object/genericmapper.md b/docs/graphql/object/genericmapper.md new file mode 100644 index 00000000..205c4bb6 --- /dev/null +++ b/docs/graphql/object/genericmapper.md @@ -0,0 +1,15 @@ +--- +title: GenericMapper +--- + +Represents a mapping between a source data type and a target key for generic values. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this GenericMapper was created | +| `source` | [`DataTypeIdentifier!`](../union/datatypeidentifier.md) | The source data type identifier. | +| `target` | [`String!`](../scalar/string.md) | The target key for the generic value. | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this GenericMapper was last updated | + diff --git a/docs/graphql/object/generictype.md b/docs/graphql/object/generictype.md new file mode 100644 index 00000000..c88321df --- /dev/null +++ b/docs/graphql/object/generictype.md @@ -0,0 +1,15 @@ +--- +title: GenericType +--- + +Represents a generic type that can be used in various contexts. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this GenericType was created | +| `dataType` | [`DataType!`](../object/datatype.md) | The data type associated with this generic type. | +| `genericMappers` | [`[GenericMapper!]!`](../object/genericmapper.md) | The mappers associated with this generic type. | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this GenericType was last updated | + diff --git a/docs/graphql/object/literalvalue.md b/docs/graphql/object/literalvalue.md new file mode 100644 index 00000000..67eca3cc --- /dev/null +++ b/docs/graphql/object/literalvalue.md @@ -0,0 +1,14 @@ +--- +title: LiteralValue +--- + +Represents a literal value, such as a string or number. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this LiteralValue was created | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this LiteralValue was last updated | +| `value` | [`JSON!`](../scalar/json.md) | The literal value itself as JSON. | + diff --git a/docs/graphql/object/nodefunction.md b/docs/graphql/object/nodefunction.md new file mode 100644 index 00000000..22f0dd24 --- /dev/null +++ b/docs/graphql/object/nodefunction.md @@ -0,0 +1,17 @@ +--- +title: NodeFunction +--- + +Represents a Node Function + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this NodeFunction was created | +| `function` | [`NodeFunctionDefinition!`](../object/nodefunctiondefinition.md) | The definition of the Node Function | +| `id` | [`NodeFunctionID!`](../scalar/nodefunctionid.md) | Global ID of this NodeFunction | +| `nextNode` | [`NodeFunction`](../object/nodefunction.md) | The next Node Function in the flow | +| `parameters` | [`NodeParameterConnection!`](../object/nodeparameterconnection.md) | The parameters of the Node Function | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this NodeFunction was last updated | + diff --git a/docs/graphql/object/nodefunctiondefinition.md b/docs/graphql/object/nodefunctiondefinition.md new file mode 100644 index 00000000..2488a640 --- /dev/null +++ b/docs/graphql/object/nodefunctiondefinition.md @@ -0,0 +1,15 @@ +--- +title: NodeFunctionDefinition +--- + +Represents a Node Function definition + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this NodeFunctionDefinition was created | +| `functionId` | [`String!`](../scalar/string.md) | The function ID of the Node Function | +| `runtimeFunctionId` | [`String!`](../scalar/string.md) | The runtime function ID of the Node Function | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this NodeFunctionDefinition was last updated | + diff --git a/docs/graphql/object/nodeparameter.md b/docs/graphql/object/nodeparameter.md new file mode 100644 index 00000000..3697c951 --- /dev/null +++ b/docs/graphql/object/nodeparameter.md @@ -0,0 +1,16 @@ +--- +title: NodeParameter +--- + +Represents a Node parameter + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this NodeParameter was created | +| `definition` | [`NodeParameterDefinition!`](../object/nodeparameterdefinition.md) | The definition of the parameter | +| `id` | [`NodeParameterID!`](../scalar/nodeparameterid.md) | Global ID of this NodeParameter | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this NodeParameter was last updated | +| `value` | [`NodeParameterValue`](../union/nodeparametervalue.md) | The value of the parameter | + diff --git a/docs/graphql/object/nodeparameterconnection.md b/docs/graphql/object/nodeparameterconnection.md new file mode 100644 index 00000000..d90beef5 --- /dev/null +++ b/docs/graphql/object/nodeparameterconnection.md @@ -0,0 +1,15 @@ +--- +title: NodeParameterConnection +--- + +The connection type for NodeParameter. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `count` | [`Int!`](../scalar/int.md) | Total count of collection. | +| `edges` | [`[NodeParameterEdge]`](../object/nodeparameteredge.md) | A list of edges. | +| `nodes` | [`[NodeParameter]`](../object/nodeparameter.md) | A list of nodes. | +| `pageInfo` | [`PageInfo!`](../object/pageinfo.md) | Information to aid in pagination. | + diff --git a/docs/graphql/object/nodeparameterdefinition.md b/docs/graphql/object/nodeparameterdefinition.md new file mode 100644 index 00000000..64492fdc --- /dev/null +++ b/docs/graphql/object/nodeparameterdefinition.md @@ -0,0 +1,15 @@ +--- +title: NodeParameterDefinition +--- + +Represents a Node parameter definition + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this NodeParameterDefinition was created | +| `parameterId` | [`String!`](../scalar/string.md) | The ID of the parameter | +| `runtimeParameterId` | [`String!`](../scalar/string.md) | The runtime ID of the parameter | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this NodeParameterDefinition was last updated | + diff --git a/docs/graphql/object/nodeparameteredge.md b/docs/graphql/object/nodeparameteredge.md new file mode 100644 index 00000000..aeda1e19 --- /dev/null +++ b/docs/graphql/object/nodeparameteredge.md @@ -0,0 +1,13 @@ +--- +title: NodeParameterEdge +--- + +An edge in a connection. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `cursor` | [`String!`](../scalar/string.md) | A cursor for use in pagination. | +| `node` | [`NodeParameter`](../object/nodeparameter.md) | The item at the end of the edge. | + diff --git a/docs/graphql/object/referencepath.md b/docs/graphql/object/referencepath.md new file mode 100644 index 00000000..d934b762 --- /dev/null +++ b/docs/graphql/object/referencepath.md @@ -0,0 +1,16 @@ +--- +title: ReferencePath +--- + +Represents a reference path in a flow + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `arrayIndex` | [`Int`](../scalar/int.md) | TODO | +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this ReferencePath was created | +| `id` | [`ReferencePathID!`](../scalar/referencepathid.md) | Global ID of this ReferencePath | +| `path` | [`String`](../scalar/string.md) | The path to the reference in the flow | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this ReferencePath was last updated | + diff --git a/docs/graphql/object/referencevalue.md b/docs/graphql/object/referencevalue.md new file mode 100644 index 00000000..f94059d2 --- /dev/null +++ b/docs/graphql/object/referencevalue.md @@ -0,0 +1,19 @@ +--- +title: ReferenceValue +--- + +Represents a reference value in the system. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this ReferenceValue was created | +| `dataTypeIdentifier` | [`DataTypeIdentifier!`](../union/datatypeidentifier.md) | The identifier of the data type this reference value belongs to. | +| `id` | [`ReferenceValueID!`](../scalar/referencevalueid.md) | Global ID of this ReferenceValue | +| `primaryLevel` | [`Int!`](../scalar/int.md) | The primary level of the reference value. | +| `referencePath` | [`[ReferencePath!]!`](../object/referencepath.md) | The paths associated with this reference value. | +| `secondaryLevel` | [`Int!`](../scalar/int.md) | The secondary level of the reference value. | +| `tertiaryLevel` | [`Int`](../scalar/int.md) | The tertiary level of the reference value, if applicable. | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this ReferenceValue was last updated | + diff --git a/docs/graphql/scalar/flowid.md b/docs/graphql/scalar/flowid.md new file mode 100644 index 00000000..46098ade --- /dev/null +++ b/docs/graphql/scalar/flowid.md @@ -0,0 +1,5 @@ +--- +title: FlowID +--- + +A unique identifier for all Flow entities of the application diff --git a/docs/graphql/scalar/flowsettingid.md b/docs/graphql/scalar/flowsettingid.md new file mode 100644 index 00000000..2d956031 --- /dev/null +++ b/docs/graphql/scalar/flowsettingid.md @@ -0,0 +1,5 @@ +--- +title: FlowSettingID +--- + +A unique identifier for all FlowSetting entities of the application diff --git a/docs/graphql/scalar/json.md b/docs/graphql/scalar/json.md new file mode 100644 index 00000000..98c835c0 --- /dev/null +++ b/docs/graphql/scalar/json.md @@ -0,0 +1,5 @@ +--- +title: JSON +--- + +Represents untyped JSON diff --git a/docs/graphql/scalar/nodefunctionid.md b/docs/graphql/scalar/nodefunctionid.md new file mode 100644 index 00000000..341b2a00 --- /dev/null +++ b/docs/graphql/scalar/nodefunctionid.md @@ -0,0 +1,5 @@ +--- +title: NodeFunctionID +--- + +A unique identifier for all NodeFunction entities of the application diff --git a/docs/graphql/scalar/nodeparameterid.md b/docs/graphql/scalar/nodeparameterid.md new file mode 100644 index 00000000..b28d4f82 --- /dev/null +++ b/docs/graphql/scalar/nodeparameterid.md @@ -0,0 +1,5 @@ +--- +title: NodeParameterID +--- + +A unique identifier for all NodeParameter entities of the application diff --git a/docs/graphql/scalar/referencepathid.md b/docs/graphql/scalar/referencepathid.md new file mode 100644 index 00000000..aa58a22b --- /dev/null +++ b/docs/graphql/scalar/referencepathid.md @@ -0,0 +1,5 @@ +--- +title: ReferencePathID +--- + +A unique identifier for all ReferencePath entities of the application diff --git a/docs/graphql/scalar/referencevalueid.md b/docs/graphql/scalar/referencevalueid.md new file mode 100644 index 00000000..4e2e6b1a --- /dev/null +++ b/docs/graphql/scalar/referencevalueid.md @@ -0,0 +1,5 @@ +--- +title: ReferenceValueID +--- + +A unique identifier for all ReferenceValue entities of the application diff --git a/docs/graphql/union/datatypeidentifier.md b/docs/graphql/union/datatypeidentifier.md new file mode 100644 index 00000000..a9a6afbc --- /dev/null +++ b/docs/graphql/union/datatypeidentifier.md @@ -0,0 +1,11 @@ +--- +title: DataTypeIdentifier +--- + +Represents a data type identifier. + +## Possible types + +- [`DataType`](../object/datatype.md) +- [`GenericKey`](../object/generickey.md) +- [`GenericType`](../object/generictype.md) diff --git a/docs/graphql/union/nodeparametervalue.md b/docs/graphql/union/nodeparametervalue.md new file mode 100644 index 00000000..dea2d6bc --- /dev/null +++ b/docs/graphql/union/nodeparametervalue.md @@ -0,0 +1,11 @@ +--- +title: NodeParameterValue +--- + +Represents a parameter value for a node. + +## Possible types + +- [`LiteralValue`](../object/literalvalue.md) +- [`NodeFunction`](../object/nodefunction.md) +- [`ReferenceValue`](../object/referencevalue.md) From e0d0ce14b0b1225ac1f90818dc2c0939a019a25f Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Thu, 29 May 2025 01:14:56 +0200 Subject: [PATCH 33/54] Add validation services for data types and node functions, enhance input types, and update JSON schemas --- Gemfile | 3 + Gemfile.lock | 7 ++ .../namespaces/projects/flows/create.rb | 33 +++++- app/graphql/sagittarius_schema.rb | 9 ++ app/graphql/types/base_input_object.rb | 4 + app/graphql/types/input/flow_input_type.rb | 16 +-- .../types/input/flow_setting_input_type.rb | 5 +- .../node_function_definition_input_type.rb | 14 --- .../types/input/node_function_input_type.rb | 5 +- .../node_parameter_definition_input_type.rb | 14 --- .../types/input/node_parameter_input_type.rb | 5 +- .../input/node_parameter_value_input_type.rb | 4 + app/models/data_type_rule.rb | 19 ++- ...ContainsKeyRuleConfig.json:Zone.Identifier | 0 ...ontainsTypeRuleConfig.json:Zone.Identifier | 0 .../json_schemas/DataTypeIdentifier.json | 32 ++++++ .../DataTypeIdentifier.json:Zone.Identifier | 0 ...fCollectionRuleConfig.json:Zone.Identifier | 0 ...NumberRangeRuleConfig.json:Zone.Identifier | 0 ...taTypeRegexRuleConfig.json:Zone.Identifier | 0 app/models/json_schemas/GenericMapper.json | 15 +++ app/models/json_schemas/GenericType.json | 18 +++ .../DataTypeContainsKeyRuleConfig.json | 15 +++ .../DataTypeContainsTypeRuleConfig.json | 9 ++ .../DataTypeItemOfCollectionRuleConfig.json | 14 +++ .../DataTypeNumberRangeRuleConfig.json | 11 ++ .../data_types/DataTypeRegexRuleConfig.json | 13 +++ app/models/node_function.rb | 15 +++ .../data_type_rule_validation_service.rb | 43 +++++++ .../data_type/data_type_validation_service.rb | 81 +++++++++++++ ...data_type_identifier_validation_service.rb | 59 ++++++++++ ...data_type_identifier_validation_service.rb | 65 +++++++++++ .../flow_setting_validation_service.rb | 29 +++++ .../flow_type_validation_service.rb | 38 ++++++ .../generic_mapper_validation_service.rb | 54 +++++++++ .../generic_type_validation_service.rb | 45 ++++++++ ...e_function_parameter_validation_service.rb | 52 +++++++++ .../node_function_validation_service.rb | 92 +++++++++++++++ .../reference_value_validation_service.rb | 55 +++++++++ .../flows/validation/validation_service.rb | 72 ++++++++++++ .../projects/flows/validation_service.rb | 23 ---- docs/graphql/input_object/flowinput.md | 6 +- docs/graphql/input_object/flowsettinginput.md | 3 +- .../nodefunctiondefinitioninput.md | 12 -- .../graphql/input_object/nodefunctioninput.md | 2 +- .../nodeparameterdefinitioninput.md | 12 -- .../input_object/nodeparameterinput.md | 2 +- .../mutation/namespacesprojectsflowscreate.md | 1 + docs/graphql/scalar/flowtypeid.md | 5 + .../scalar/runtimefunctiondefinitionid.md | 5 + .../scalar/runtimeparameterdefinitionid.md | 5 + .../validators/json_schema_validator.rb | 75 ++++++++++++ spec/factories/data_type_rules.rb | 4 +- spec/models/data_type_rule_spec.rb | 108 ++++++++++++++++++ .../projects/flows/validation_service_spec.rb | 9 +- 55 files changed, 1131 insertions(+), 106 deletions(-) delete mode 100644 app/graphql/types/input/node_function_definition_input_type.rb delete mode 100644 app/graphql/types/input/node_parameter_definition_input_type.rb create mode 100644 app/models/json_schemas/DataTypeContainsKeyRuleConfig.json:Zone.Identifier create mode 100644 app/models/json_schemas/DataTypeContainsTypeRuleConfig.json:Zone.Identifier create mode 100644 app/models/json_schemas/DataTypeIdentifier.json create mode 100644 app/models/json_schemas/DataTypeIdentifier.json:Zone.Identifier create mode 100644 app/models/json_schemas/DataTypeItemOfCollectionRuleConfig.json:Zone.Identifier create mode 100644 app/models/json_schemas/DataTypeNumberRangeRuleConfig.json:Zone.Identifier create mode 100644 app/models/json_schemas/DataTypeRegexRuleConfig.json:Zone.Identifier create mode 100644 app/models/json_schemas/GenericMapper.json create mode 100644 app/models/json_schemas/GenericType.json create mode 100644 app/models/json_schemas/data_types/DataTypeContainsKeyRuleConfig.json create mode 100644 app/models/json_schemas/data_types/DataTypeContainsTypeRuleConfig.json create mode 100644 app/models/json_schemas/data_types/DataTypeItemOfCollectionRuleConfig.json create mode 100644 app/models/json_schemas/data_types/DataTypeNumberRangeRuleConfig.json create mode 100644 app/models/json_schemas/data_types/DataTypeRegexRuleConfig.json create mode 100644 app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb create mode 100644 app/services/namespaces/projects/flows/validation/validation_service.rb delete mode 100644 app/services/namespaces/projects/flows/validation_service.rb delete mode 100644 docs/graphql/input_object/nodefunctiondefinitioninput.md delete mode 100644 docs/graphql/input_object/nodeparameterdefinitioninput.md create mode 100644 docs/graphql/scalar/flowtypeid.md create mode 100644 docs/graphql/scalar/runtimefunctiondefinitionid.md create mode 100644 docs/graphql/scalar/runtimeparameterdefinitionid.md create mode 100644 lib/sagittarius/validators/json_schema_validator.rb diff --git a/Gemfile b/Gemfile index fa653e3a..6671cff6 100644 --- a/Gemfile +++ b/Gemfile @@ -89,3 +89,6 @@ gem 'pry-byebug', '~> 3.10' gem 'code0-zero_track', '0.0.4' gem 'image_processing', '>= 1.2' + + +gem "json-schema", "~> 5.1" diff --git a/Gemfile.lock b/Gemfile.lock index 729121d8..18325aed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -72,6 +72,8 @@ GEM securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) uri (>= 0.13.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.3) base64 (0.2.0) bcrypt (3.1.20) @@ -154,6 +156,9 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.12.0) + json-schema (5.1.1) + addressable (~> 2.8) + bigdecimal (~> 3.1) language_server-protocol (3.17.0.5) lint_roller (1.1.0) logger (1.7.0) @@ -212,6 +217,7 @@ GEM psych (5.2.6) date stringio + public_suffix (6.0.2) puma (6.6.0) nio4r (~> 2.0) raabro (1.4.0) @@ -389,6 +395,7 @@ DEPENDENCIES graphql (~> 2.1) grpc (~> 1.67) image_processing (>= 1.2) + json-schema (~> 5.1) lograge (~> 0.14.0) pg (~> 1.1) pry (~> 0.14.2) diff --git a/app/graphql/mutations/namespaces/projects/flows/create.rb b/app/graphql/mutations/namespaces/projects/flows/create.rb index 96202386..930446ad 100644 --- a/app/graphql/mutations/namespaces/projects/flows/create.rb +++ b/app/graphql/mutations/namespaces/projects/flows/create.rb @@ -9,10 +9,39 @@ class Create < BaseMutation field :flow, Types::FlowType, null: true, description: 'The newly created flow.' + argument :project_id, Types::GlobalIdType[NamespaceProject], required: true, + description: 'The ID of the project to which the flow belongs to' + argument :flow, Types::Input::FlowInputType - def resolve(namespace_id:, **params) - # TODO + def resolve(project_id:, flow:, **params) + create_params = {} + + + project = SagittariusSchema.object_from_id(project_id) + + if project.nil? + return error('Invalid project id') + end + + input_type = SagittariusSchema.object_from_id(flow.input_type) + + if input_type.nil? + return error('Invalid input type id') + end + + + + + + + end + + def error(message) + { + flow: nil, + errors: [create_message_error(message)] + } end end end diff --git a/app/graphql/sagittarius_schema.rb b/app/graphql/sagittarius_schema.rb index 72927d77..8a47972a 100644 --- a/app/graphql/sagittarius_schema.rb +++ b/app/graphql/sagittarius_schema.rb @@ -51,6 +51,15 @@ def self.object_from_id(global_id, query_ctx = nil) rescue ActiveRecord::RecordNotFound nil end + + def self.object_from_id_or_error(global_id) + obj = object_from_id(global_id) + if obj.nil? + + end + obj + end + # rubocop:enable Lint/UnusedMethodArgument end # rubocop:enable GraphQL/MaxDepthSchema diff --git a/app/graphql/types/base_input_object.rb b/app/graphql/types/base_input_object.rb index 27951132..32c51240 100644 --- a/app/graphql/types/base_input_object.rb +++ b/app/graphql/types/base_input_object.rb @@ -3,5 +3,9 @@ module Types class BaseInputObject < GraphQL::Schema::InputObject argument_class Types::BaseArgument + + def self.require_one_of(arguments) + validates required: { one_of: arguments, message: "Only one of #{arguments.inspect} should be provided" } + end end end diff --git a/app/graphql/types/input/flow_input_type.rb b/app/graphql/types/input/flow_input_type.rb index 6ee2c830..94a75ca6 100644 --- a/app/graphql/types/input/flow_input_type.rb +++ b/app/graphql/types/input/flow_input_type.rb @@ -5,16 +5,16 @@ module Input class FlowInputType < Types::BaseInputObject description 'Input type for creating or updating a flow' - argument :input_type_id, ID, required: false, - description: 'The ID of the input data type' - argument :return_type_id, ID, required: false, - description: 'The ID of the return data type' + argument :input_type, Types::GlobalIdType[::DataType], required: false, + description: 'The ID of the input data type' + argument :return_type, Types::GlobalIdType[::DataType], required: false, + description: 'The ID of the return data type' argument :settings, [Types::Input::FlowSettingInputType], required: false, - description: 'The settings of the flow' + description: 'The settings of the flow' argument :starting_node, Types::Input::NodeFunctionInputType, required: true, - description: 'The starting node of the flow' - argument :type, String, required: true, - description: 'The identifier of the flow type' + description: 'The starting node of the flow' + argument :type, Types::GlobalIdType[::FlowType], required: true, + description: 'The identifier of the flow type' end end end diff --git a/app/graphql/types/input/flow_setting_input_type.rb b/app/graphql/types/input/flow_setting_input_type.rb index 259fc0d0..d1ee6266 100644 --- a/app/graphql/types/input/flow_setting_input_type.rb +++ b/app/graphql/types/input/flow_setting_input_type.rb @@ -5,7 +5,10 @@ module Input class FlowSettingInputType < Types::BaseInputObject description 'Input type for flow settings' - argument :value, GraphQL::Types::JSON, required: true, + argument :flow_setting_id, String, required: true, + description: 'The identifier of the flow setting' + + argument :object, GraphQL::Types::JSON, required: true, description: 'The value of the flow setting' end end diff --git a/app/graphql/types/input/node_function_definition_input_type.rb b/app/graphql/types/input/node_function_definition_input_type.rb deleted file mode 100644 index eab09188..00000000 --- a/app/graphql/types/input/node_function_definition_input_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Types - module Input - class NodeFunctionDefinitionInputType < Types::BaseInputObject - description 'Input type for Node Function definition' - - argument :function_id, String, required: true, - description: 'The function ID of the Node Function' - argument :runtime_function_id, String, required: true, - description: 'The runtime function ID of the Node Function' - end - end -end diff --git a/app/graphql/types/input/node_function_input_type.rb b/app/graphql/types/input/node_function_input_type.rb index 2b033c1a..c8e1fd8e 100644 --- a/app/graphql/types/input/node_function_input_type.rb +++ b/app/graphql/types/input/node_function_input_type.rb @@ -5,8 +5,9 @@ module Input class NodeFunctionInputType < Types::BaseInputObject description 'Input type for a Node Function' - argument :function, Types::Input::NodeFunctionDefinitionInputType, required: true, - description: 'The definition of the Node Function' + argument :runtime_function_id, Types::GlobalIdType[::RuntimeFunctionDefinition], + required: true, description: 'The identifier of the Runtime Function Definition' + argument :next_node, Types::Input::NodeFunctionInputType, required: false, description: 'The next Node Function in the flow' argument :parameters, [Types::Input::NodeParameterInputType], required: true, diff --git a/app/graphql/types/input/node_parameter_definition_input_type.rb b/app/graphql/types/input/node_parameter_definition_input_type.rb deleted file mode 100644 index ffdac983..00000000 --- a/app/graphql/types/input/node_parameter_definition_input_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Types - module Input - class NodeParameterDefinitionInputType < Types::BaseInputObject - description 'Input type for Node parameter definition' - - argument :parameter_id, String, required: true, - description: 'The ID of the parameter' - argument :runtime_parameter_id, String, required: true, - description: 'The runtime ID of the parameter' - end - end -end diff --git a/app/graphql/types/input/node_parameter_input_type.rb b/app/graphql/types/input/node_parameter_input_type.rb index f877fcb2..d6001c40 100644 --- a/app/graphql/types/input/node_parameter_input_type.rb +++ b/app/graphql/types/input/node_parameter_input_type.rb @@ -5,8 +5,9 @@ module Input class NodeParameterInputType < Types::BaseInputObject description 'Input type for Node parameter' - argument :definition, Types::Input::NodeParameterDefinitionInputType, required: true, - description: 'The definition of the parameter' + argument :runtime_parameter_definition_id, Types::GlobalIdType[::RuntimeParameterDefinition], + required: true, description: 'The identifier of the Runtime Parameter Definition' + argument :value, Types::Input::NodeParameterValueInputType, required: false, description: 'The value of the parameter' end diff --git a/app/graphql/types/input/node_parameter_value_input_type.rb b/app/graphql/types/input/node_parameter_value_input_type.rb index 11b2d310..4cecf61a 100644 --- a/app/graphql/types/input/node_parameter_value_input_type.rb +++ b/app/graphql/types/input/node_parameter_value_input_type.rb @@ -11,6 +11,10 @@ class NodeParameterValueInputType < Types::BaseInputObject description: 'The literal value of the parameter' argument :reference_value, Types::Input::ReferenceValueInputType, required: false, description: 'The reference value of the parameter' + + require_one_of %i[function_value literal_value reference_value] + + end end end diff --git a/app/models/data_type_rule.rb b/app/models/data_type_rule.rb index eb30af26..49283133 100644 --- a/app/models/data_type_rule.rb +++ b/app/models/data_type_rule.rb @@ -9,12 +9,23 @@ class DataTypeRule < ApplicationRecord regex: 5, }.with_indifferent_access - enum :variant, VARIANTS, prefix: :types + enum :variant, VARIANTS, prefix: :variant belongs_to :data_type, inverse_of: :rules validates :variant, presence: true, - inclusion: { - in: VARIANTS.keys.map(&:to_s), - } + inclusion: { + in: VARIANTS.keys.map(&:to_s), + } + + validates :config, if: :variant_contains_key?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeContainsKeyRuleConfig', hash_conversion: true } + + validates :config, if: :variant_contains_type?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeContainsTypeRuleConfig', hash_conversion: true } + + validates :config, if: :variant_item_of_collection?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeItemOfCollectionRuleConfig', hash_conversion: true } + + validates :config, if: :variant_number_range?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeNumberRangeRuleConfig', hash_conversion: true } + + validates :config, if: :variant_regex?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeRegexRuleConfig', hash_conversion: true } + end diff --git a/app/models/json_schemas/DataTypeContainsKeyRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeContainsKeyRuleConfig.json:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/app/models/json_schemas/DataTypeContainsTypeRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeContainsTypeRuleConfig.json:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/app/models/json_schemas/DataTypeIdentifier.json b/app/models/json_schemas/DataTypeIdentifier.json new file mode 100644 index 00000000..bb03a759 --- /dev/null +++ b/app/models/json_schemas/DataTypeIdentifier.json @@ -0,0 +1,32 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "https://example.com/schemas/DataTypeIdentifier.json", + "title": "DataTypeIdentifier", + "type": "object", + "oneOf": [ + { + "required": ["data_type_identifier"], + "properties": { + "data_type_identifier": { + "type": "string" + } + } + }, + { + "required": ["generic_type"], + "properties": { + "generic_type": { + "$ref": "GenericType.json" + } + } + }, + { + "required": ["generic_key"], + "properties": { + "generic_key": { + "type": "string" + } + } + } + ] +} diff --git a/app/models/json_schemas/DataTypeIdentifier.json:Zone.Identifier b/app/models/json_schemas/DataTypeIdentifier.json:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/app/models/json_schemas/DataTypeItemOfCollectionRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeItemOfCollectionRuleConfig.json:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/app/models/json_schemas/DataTypeNumberRangeRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeNumberRangeRuleConfig.json:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/app/models/json_schemas/DataTypeRegexRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeRegexRuleConfig.json:Zone.Identifier new file mode 100644 index 00000000..e69de29b diff --git a/app/models/json_schemas/GenericMapper.json b/app/models/json_schemas/GenericMapper.json new file mode 100644 index 00000000..4dd8a8d4 --- /dev/null +++ b/app/models/json_schemas/GenericMapper.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "https://example.com/schemas/GenericMapper.json", + "title": "GenericMapper", + "type": "object", + "required": ["source", "target"], + "properties": { + "source": { + "$ref": "DataTypeIdentifier.json" + }, + "target": { + "type": "string" + } + } +} diff --git a/app/models/json_schemas/GenericType.json b/app/models/json_schemas/GenericType.json new file mode 100644 index 00000000..b710e3d2 --- /dev/null +++ b/app/models/json_schemas/GenericType.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "https://example.com/schemas/GenericType.json", + "title": "GenericType", + "type": "object", + "required": ["data_type_identifier", "generic_mappers"], + "properties": { + "data_type_identifier": { + "type": "string" + }, + "generic_mappers": { + "type": "array", + "items": { + "$ref": "GenericMapper.json" + } + } + } +} diff --git a/app/models/json_schemas/data_types/DataTypeContainsKeyRuleConfig.json b/app/models/json_schemas/data_types/DataTypeContainsKeyRuleConfig.json new file mode 100644 index 00000000..afa92e7f --- /dev/null +++ b/app/models/json_schemas/data_types/DataTypeContainsKeyRuleConfig.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "https://example.com/schemas/DataTypeContainsKeyRuleConfig.json", + "title": "DataTypeContainsKeyRuleConfig", + "type": "object", + "required": ["key", "data_type_identifier"], + "properties": { + "key": { + "type": "string" + }, + "data_type_identifier": { + "$ref": "../DataTypeIdentifier.json" + } + } +} diff --git a/app/models/json_schemas/data_types/DataTypeContainsTypeRuleConfig.json b/app/models/json_schemas/data_types/DataTypeContainsTypeRuleConfig.json new file mode 100644 index 00000000..fba57caf --- /dev/null +++ b/app/models/json_schemas/data_types/DataTypeContainsTypeRuleConfig.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "DataTypeContainsTypeRuleConfig", + "type": "object", + "required": ["data_type_identifier"], + "properties": { + "data_type_identifier": { "$ref": "../DataTypeIdentifier.json" } + } +} diff --git a/app/models/json_schemas/data_types/DataTypeItemOfCollectionRuleConfig.json b/app/models/json_schemas/data_types/DataTypeItemOfCollectionRuleConfig.json new file mode 100644 index 00000000..3a5ff9c3 --- /dev/null +++ b/app/models/json_schemas/data_types/DataTypeItemOfCollectionRuleConfig.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "DataTypeItemOfCollectionRuleConfig", + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "type": "array", + "items": {} + } + } +} diff --git a/app/models/json_schemas/data_types/DataTypeNumberRangeRuleConfig.json b/app/models/json_schemas/data_types/DataTypeNumberRangeRuleConfig.json new file mode 100644 index 00000000..f6136fe5 --- /dev/null +++ b/app/models/json_schemas/data_types/DataTypeNumberRangeRuleConfig.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "DataTypeNumberRangeRuleConfig", + "type": "object", + "required": ["from", "to"], + "properties": { + "from": { "type": "integer" }, + "to": { "type": "integer" }, + "steps": { "type": "integer" } + } +} diff --git a/app/models/json_schemas/data_types/DataTypeRegexRuleConfig.json b/app/models/json_schemas/data_types/DataTypeRegexRuleConfig.json new file mode 100644 index 00000000..2c8c4d0d --- /dev/null +++ b/app/models/json_schemas/data_types/DataTypeRegexRuleConfig.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "DataTypeRegexRuleConfig", + "type": "object", + "required": [ + "pattern" + ], + "properties": { + "pattern": { + "type": "string" + } + } +} diff --git a/app/models/node_function.rb b/app/models/node_function.rb index 18d604d8..5359cb1c 100644 --- a/app/models/node_function.rb +++ b/app/models/node_function.rb @@ -6,6 +6,21 @@ class NodeFunction < ApplicationRecord has_many :node_parameters, inverse_of: :function_value + + validate :validate_recursion, if: :next_node_changed? + + def validate_recursion + current_node = self + until current_node.next_node.nil? + current_node = current_node.next_node + + if current_node == self + errors.add(:next_node, :recursion) + break + end + end + end + def to_grpc Tucana::NodeFunction.new( data_base_id: id, diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb new file mode 100644 index 00000000..bb2f7034 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module DataType + class DataTypeRuleValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :data_type, :rule + + def initialize(current_authentication, flow, data_type, rule) + @current_authentication = current_authentication + @flow = flow + @data_type = data_type + @rule = rule + end + + def execute + logger.debug("Validating data type rule #{rule.id}") + + transaction do |t| + if rule.invalid? + logger.debug(message: "Data type rule validation (model) failed", + flow: flow.id, + data_type: data_type.id, + rule: rule.id, + errors: rule.errors.full_messages) + t.rollback_and_return! ServiceResponse.error( + message: 'Data type rule is invalid', + payload: rule.errors + ) + end + end + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb new file mode 100644 index 00000000..b44afc99 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module DataType + class DataTypeValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :data_type + + def initialize(current_authentication, flow, data_type) + @current_authentication = current_authentication + @flow = flow + @data_type = data_type + end + + def execute + logger.debug("Validating data type: #{data_type.name} for flow: #{flow.name}") + + transactional do |t| + if data_type.invalid? + logger.debug(message: "Data type validation failed", + flow: flow.id, + data_type: data_type.id, + errors: data_type.errors.full_messages) + t.rollback_and_return!( + ServiceResponse.error( + message: 'Data type is invalid', + payload: data_type.errors, + ) + ) + end + + primary_runtime = flow.project.primary_runtime + + if primary_runtime != data_type.runtime + logger.debug(message: "Data type runtime mismatch", + primary_runtime: primary_runtime.id, + given_runtime: data_type.runtime.id, + flow: flow.id, + data_type: data_type.id + ) + t.rollback_and_return!( + ServiceResponse.error( + message: 'Data type runtime does not match the primary runtime of the project', + payload: :runtime_mismatch + ) + ) + end + + data_type.parent_type&.tap do |parent_type| + logger.debug("Validating parent type: #{parent_type.id} for data type: #{data_type.id}") + DataTypeValidationService.new( + current_authentication, + flow, + parent_type + ).execute + end + + data_type.rules.each do |rule| + logger.debug("Validating data type rule: #{rule.id} for data type: #{data_type.id}") + ::DataTypeRuleValidationService.new( + current_authentication, + flow, + data_type, + rule + ).execute + end + + logger.debug(message: "Data type is valid", flow: flow.id, data_type: data_type.id) + end + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb new file mode 100644 index 00000000..e5cf82d5 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module DataType + class GenericDataTypeIdentifierValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :data_type_identifier + + def initialize(current_authentication, flow, data_type_identifier) + @current_authentication = current_authentication + @flow = flow + @data_type_identifier = data_type_identifier + end + + def execute + logger.debug("Validating flow_type: #{data_type_identifier.inspect} for flow: #{flow.id}") + + transactional do |t| + if data_type_identifier.invalid? + logger.debug(message: "Data type identifier validation failed", + flow: flow.id, + data_type_identifier: data_type_identifier.id, + errors: data_type_identifier.errors.full_messages) + t.rollback_and_return!( + ServiceResponse.error( + message: 'Data type identifier is invalid', + payload: data_type_identifier.errors + ) + ) + end + if data_type_identifier.runtime != flow.project.primary_runtime + logger.debug(message: "Data type identifier runtime mismatch", + primary_runtime: flow.project.primary_runtime.id, + given_runtime: data_type_identifier.runtime.id, + flow: flow.id, + data_type_identifier: data_type_identifier.id) + t.rollback_and_return!( + ServiceResponse.error( + message: 'Data type identifier runtime does not match the primary runtime of the project', + payload: :runtime_mismatch + ) + ) + end + + + + end + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb new file mode 100644 index 00000000..fc7ace12 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module DataType + class GenericMapperDataTypeIdentifierValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :parameter, :mapper, :source + + def initialize(current_authentication, flow, parameter, mapper, source) + @current_authentication = current_authentication + @flow = flow + @parameter = parameter + @mapper = mapper + @source = source + end + + def execute + logger.debug("Validating flow_type: #{data_type_identifier.inspect} for flow: #{flow.id}") + + transactional do |t| + ::GenericDataTypeIdentifierValidationService.new( + current_authentication, + flow, + source + ).execute + + if source.generic_key.present? + unless parameter.function_value.runtime_function_definition.generic_keys.has?(source.generic_key) + t.rollback_and_return!( + ServiceResponse.error( + message: "Generic type #{parameter.generic_type.data_type.id} does not have a generic key for source #{source.generic_key}", + payload: :generic_key_not_found + ) + ) + end + return + end + if source.data_type.present? + DataTypeValidationService.new( + current_authentication, + flow, + source.data_type + ).execute + return + end + if source.generic_type.present? + ::NodeFunction::GenericTypeValidationService.new( + current_authentication, + flow, + source.generic_type + ).execute + end + end + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb b/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb new file mode 100644 index 00000000..43aa8240 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + class FlowSettingValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :setting + + def initialize(current_authentication, flow, setting) + @current_authentication = current_authentication + @flow = flow + @setting = setting + end + + def execute + logger.debug("Validating setting: #{setting.inspect} for flow: #{flow.id}") + + # Maybe something in the future we will validate the setting object but currently its not typed + + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb new file mode 100644 index 00000000..3253e259 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + class FlowTypeValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :flow_type + + def initialize(current_authentication, flow, flow_type) + @current_authentication = current_authentication + @flow = flow + @flow_type = flow_type + end + + def execute + logger.debug("Validating flow_type: #{flow_type.inspect} for flow: #{flow.id}") + + transactional do |t| + if flow_type.runtime != flow.project.primary_runtime + t.rollback_and_return!( + ServiceResponse.error( + message: 'Flow type runtime definition does not match the primary runtime of the project', + payload: :runtime_mismatch + ) + ) + end + end + + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb new file mode 100644 index 00000000..413767a0 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module NodeFunction + class GenericMapperValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :parameter, :generic_mapper + + def initialize(current_authentication, flow, parameter, generic_mapper) + @current_authentication = current_authentication + @flow = flow + @parameter = parameter + @generic_mapper = generic_mapper + end + + def execute + logger.debug("Validating node function: #{parameter.inspect} for flow: #{flow.id}") + + transactional do |t| + target = generic_mapper.target + + # Validate the target + unless parameter.generic_type.data_type.generic_keys.has?(target) + t.rollback_and_return!( + ServiceResponse.error( + message: "Generic type #{parameter.generic_type.data_type.id} does not have a generic key for target #{target}", + payload: :generic_key_not_found + ) + ) + end + + ::DataType::GenericMapperDataTypeIdentifierValidationService.new( + current_authentication, + flow, + parameter, + generic_mapper, + generic_mapper.source + ).execute + + end + + ServiceResponse.success(message: 'Node function generic mapper validation passed') + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb new file mode 100644 index 00000000..77ef9ced --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module NodeFunction + class GenericTypeValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :node_function, :generic_type + + def initialize(current_authentication, flow, node_function, generic_type) + @current_authentication = current_authentication + @flow = flow + @node_function = node_function + @generic_type = generic_type + end + + def execute + transactional do |t| + ::DataType::DataTypeValidationService.new( + current_authentication, + flow, + identifier.data_type + ).execute + + identifier.data_type.generic_mappers.each do |generic_mapper| + logger.debug("Validating generic mapper: #{generic_mapper.id} for data type identifier: #{identifier.id}") + ::DataType::GenericMapperValidationService.new( + current_authentication, + flow, + parameter, + generic_mapper + ).execute + end + end + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb new file mode 100644 index 00000000..5d1b4ede --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module NodeFunction + class NodeFunctionParameterValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :node_function, :parameter + + def initialize(current_authentication, flow, node_function, parameter) + @current_authentication = current_authentication + @flow = flow + @node_function = node_function + @parameter = parameter + end + + def execute + logger.debug("Validating node parameter: #{parameter.id} for flow: #{flow.id}") + + transactional do |t| + if parameter.invalid? + logger.debug(message: "Node parameter validation failed", + errors: parameter.errors.full_messages) + t.rollback_and_return!( + ServiceResponse.error( + message: 'Node function is invalid', + payload: parameter.errors + ) + ) + end + if parameter.literal_value.present? + return + end + if parameter.reference_value.present? + ReferenceValueValidationService.new( + current_authentication, + flow, + parameter.reference_value + ).execute + end + end + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb new file mode 100644 index 00000000..ab9ee48c --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module NodeFunction + class NodeFunctionValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :node_function + + def initialize(current_authentication, flow, node_function) + @current_authentication = current_authentication + @flow = flow + @node_function = node_function + end + + def execute + logger.debug("Validating node function: #{node_function.id} for flow: #{flow.id}") + + transactional do |t| + if node_function.invalid? + logger.debug(message: "Node function validation failed", + errors: node_function.errors.full_messages) + t.rollback_and_return!( + ServiceResponse.error( + message: 'Node function is invalid', + payload: node_function.errors + ) + ) + end + + node_function.next_node&.tap do |next_node| + logger.debug("Validating next node function: #{next_node.id} for flow: #{flow.id}") + NodeFunctionValidationService.new( + current_authentication, + flow, + next_node + ).execute + end + + node_function.runtime_function.tap do |runtime_function| + logger.debug("Validating runtime function: #{runtime_function.id} for node function: #{node_function.id}") + if runtime_function.runtime != flow.project.primary_runtime + logger.debug(message: "Runtime function runtime mismatch", + primary_runtime: flow.project.primary_runtime.id, + given_runtime: runtime_function.runtime.id, + flow: flow.id, + node_function: node_function.id) + + t.rollback_and_return!( + ServiceResponse.error( + message: 'Function runtime definition does not match the primary runtime of the project', + payload: :runtime_mismatch + ) + ) + end + end + + node_function.node_parameters.each do |parameter| + logger.debug("Validating node parameter: #{parameter.id} for function: #{node_function.id}") + + if parameter.runtime_parameter != node_function.runtime_function + logger.debug(message: "Node parameter does not match its function", + node_function: node_function.id, + runtime_parameter: parameter.runtime_parameter.id, + flow: flow.id) + t.rollback_and_return!( + ServiceResponse.error( + message: 'Node parameter does not match its function', + payload: :parameter_mismatch + ) + ) + end + + ::NodeFunctionParameterValidationService.new( + current_authentication, + flow, + node_function, + parameter + ).execute + end + end + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb new file mode 100644 index 00000000..b6a1aa1f --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + module NodeFunction + class ReferenceValueValidationService + include Code0::ZeroTrack::Loggable + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow, :node_function + + def initialize(current_authentication, flow, node_function) + @current_authentication = current_authentication + @flow = flow + @node_function = node_function + end + + def execute + transactional do |t| + ::DataType::DataTypeIdentifierValidationService.new( + current_authentication, + flow, + node_function, + parameter.reference_value.data_type_identifier + ).execute + + identifier = parameter.reference_value.data_type_identifier + + if identifier.generic_key.present? + t.rollback_and_return!( + ServiceResponse.error( + message: 'Data type identifier cannot have a generic key in a function', + payload: :generic_key_present + ) + ) + end + + if identifier.generic_type.present? + GenericTypeValidationService.new( + current_authentication, + flow, + node_function, + identifier.generic_type + ).execute + end + end + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation/validation_service.rb b/app/services/namespaces/projects/flows/validation/validation_service.rb new file mode 100644 index 00000000..d0883e99 --- /dev/null +++ b/app/services/namespaces/projects/flows/validation/validation_service.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Namespaces + module Projects + module Flows + module Validation + class ValidationService + include Sagittarius::Database::Transactional + + attr_reader :current_authentication, :flow + + def initialize(current_authentication, flow) + @current_authentication = current_authentication + @flow = flow + end + + def execute + transactional do |t| + primary_runtime = flow.project.primary_runtime + if primary_runtime.nil? + return ServiceResponse.error( + message: 'No primary runtime found for the project, first configure a primary runtime', + payload: :no_primary_runtime + ) + end + + # --- + # Input Type Validation + # --- + Namespaces::Projects::Flows::Validation::DataTypeValidationService( + current_authentication, + flow, + flow.input_type + ).execute + + # --- + # Return Type Validation + # --- + Namespaces::Projects::Flows::Validation::DataTypeValidationService( + current_authentication, + flow, + flow.return_type + ).execute + + # --- + # Setting + # --- + flow.flow_settings.each do |setting| + Namespaces::Projects::Flows::Validation::FlowSettingValidationService( + current_authentication, + flow, + setting + ).execute + end + + # --- + # Starting node + # --- + Namespaces::Projects::Flows::Validation::NodeFunctionValidationService( + current_authentication, + flow, + flow.starting_node + ).execute + + ServiceResponse.success(message: 'Validation service executed successfully', payload: flow) + end + end + end + end + end + end +end diff --git a/app/services/namespaces/projects/flows/validation_service.rb b/app/services/namespaces/projects/flows/validation_service.rb deleted file mode 100644 index 98205347..00000000 --- a/app/services/namespaces/projects/flows/validation_service.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module Namespaces - module Projects - module Flows - class ValidationService - include Sagittarius::Database::Transactional - - attr_reader :current_authentication, :flow - - def initialize(current_authentication, flow) - @current_authentication = current_authentication - @flow = flow - end - - def execute - # TODO: Implement validation logic for the flow - ServiceResponse.success(message: 'Validation service executed successfully', payload: flow) - end - end - end - end -end diff --git a/docs/graphql/input_object/flowinput.md b/docs/graphql/input_object/flowinput.md index 168c0067..2c56c6c2 100644 --- a/docs/graphql/input_object/flowinput.md +++ b/docs/graphql/input_object/flowinput.md @@ -8,8 +8,8 @@ Input type for creating or updating a flow | Name | Type | Description | |------|------|-------------| -| `inputTypeId` | [`ID`](../scalar/id.md) | The ID of the input data type | -| `returnTypeId` | [`ID`](../scalar/id.md) | The ID of the return data type | +| `inputType` | [`DataTypeID`](../scalar/datatypeid.md) | The ID of the input data type | +| `returnType` | [`DataTypeID`](../scalar/datatypeid.md) | The ID of the return data type | | `settings` | [`[FlowSettingInput!]`](../input_object/flowsettinginput.md) | The settings of the flow | | `startingNode` | [`NodeFunctionInput!`](../input_object/nodefunctioninput.md) | The starting node of the flow | -| `type` | [`String!`](../scalar/string.md) | The identifier of the flow type | +| `type` | [`FlowTypeID!`](../scalar/flowtypeid.md) | The identifier of the flow type | diff --git a/docs/graphql/input_object/flowsettinginput.md b/docs/graphql/input_object/flowsettinginput.md index 403e6ee7..5a39c64b 100644 --- a/docs/graphql/input_object/flowsettinginput.md +++ b/docs/graphql/input_object/flowsettinginput.md @@ -8,4 +8,5 @@ Input type for flow settings | Name | Type | Description | |------|------|-------------| -| `value` | [`JSON!`](../scalar/json.md) | The value of the flow setting | +| `flowSettingId` | [`String!`](../scalar/string.md) | The identifier of the flow setting | +| `object` | [`JSON!`](../scalar/json.md) | The value of the flow setting | diff --git a/docs/graphql/input_object/nodefunctiondefinitioninput.md b/docs/graphql/input_object/nodefunctiondefinitioninput.md deleted file mode 100644 index 93ba4433..00000000 --- a/docs/graphql/input_object/nodefunctiondefinitioninput.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: NodeFunctionDefinitionInput ---- - -Input type for Node Function definition - -## Fields - -| Name | Type | Description | -|------|------|-------------| -| `functionId` | [`String!`](../scalar/string.md) | The function ID of the Node Function | -| `runtimeFunctionId` | [`String!`](../scalar/string.md) | The runtime function ID of the Node Function | diff --git a/docs/graphql/input_object/nodefunctioninput.md b/docs/graphql/input_object/nodefunctioninput.md index 05ca758d..4c499591 100644 --- a/docs/graphql/input_object/nodefunctioninput.md +++ b/docs/graphql/input_object/nodefunctioninput.md @@ -8,6 +8,6 @@ Input type for a Node Function | Name | Type | Description | |------|------|-------------| -| `function` | [`NodeFunctionDefinitionInput!`](../input_object/nodefunctiondefinitioninput.md) | The definition of the Node Function | | `nextNode` | [`NodeFunctionInput`](../input_object/nodefunctioninput.md) | The next Node Function in the flow | | `parameters` | [`[NodeParameterInput!]!`](../input_object/nodeparameterinput.md) | The parameters of the Node Function | +| `runtimeFunctionId` | [`RuntimeFunctionDefinitionID!`](../scalar/runtimefunctiondefinitionid.md) | The identifier of the Runtime Function Definition | diff --git a/docs/graphql/input_object/nodeparameterdefinitioninput.md b/docs/graphql/input_object/nodeparameterdefinitioninput.md deleted file mode 100644 index ff91d064..00000000 --- a/docs/graphql/input_object/nodeparameterdefinitioninput.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: NodeParameterDefinitionInput ---- - -Input type for Node parameter definition - -## Fields - -| Name | Type | Description | -|------|------|-------------| -| `parameterId` | [`String!`](../scalar/string.md) | The ID of the parameter | -| `runtimeParameterId` | [`String!`](../scalar/string.md) | The runtime ID of the parameter | diff --git a/docs/graphql/input_object/nodeparameterinput.md b/docs/graphql/input_object/nodeparameterinput.md index 07eb83e7..e44021ac 100644 --- a/docs/graphql/input_object/nodeparameterinput.md +++ b/docs/graphql/input_object/nodeparameterinput.md @@ -8,5 +8,5 @@ Input type for Node parameter | Name | Type | Description | |------|------|-------------| -| `definition` | [`NodeParameterDefinitionInput!`](../input_object/nodeparameterdefinitioninput.md) | The definition of the parameter | +| `runtimeParameterDefinitionId` | [`RuntimeParameterDefinitionID!`](../scalar/runtimeparameterdefinitionid.md) | The identifier of the Runtime Parameter Definition | | `value` | [`NodeParameterValueInput`](../input_object/nodeparametervalueinput.md) | The value of the parameter | diff --git a/docs/graphql/mutation/namespacesprojectsflowscreate.md b/docs/graphql/mutation/namespacesprojectsflowscreate.md index d39efe16..1dadc182 100644 --- a/docs/graphql/mutation/namespacesprojectsflowscreate.md +++ b/docs/graphql/mutation/namespacesprojectsflowscreate.md @@ -10,6 +10,7 @@ Creates a new flow. |------|------|-------------| | `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. | | `flow` | [`FlowInput!`](../input_object/flowinput.md) | | +| `projectId` | [`NamespaceProjectID!`](../scalar/namespaceprojectid.md) | The ID of the project to which the flow belongs to | ## Fields diff --git a/docs/graphql/scalar/flowtypeid.md b/docs/graphql/scalar/flowtypeid.md new file mode 100644 index 00000000..d6945b32 --- /dev/null +++ b/docs/graphql/scalar/flowtypeid.md @@ -0,0 +1,5 @@ +--- +title: FlowTypeID +--- + +A unique identifier for all FlowType entities of the application diff --git a/docs/graphql/scalar/runtimefunctiondefinitionid.md b/docs/graphql/scalar/runtimefunctiondefinitionid.md new file mode 100644 index 00000000..0f2ceeaf --- /dev/null +++ b/docs/graphql/scalar/runtimefunctiondefinitionid.md @@ -0,0 +1,5 @@ +--- +title: RuntimeFunctionDefinitionID +--- + +A unique identifier for all RuntimeFunctionDefinition entities of the application diff --git a/docs/graphql/scalar/runtimeparameterdefinitionid.md b/docs/graphql/scalar/runtimeparameterdefinitionid.md new file mode 100644 index 00000000..2ade32cf --- /dev/null +++ b/docs/graphql/scalar/runtimeparameterdefinitionid.md @@ -0,0 +1,5 @@ +--- +title: RuntimeParameterDefinitionID +--- + +A unique identifier for all RuntimeParameterDefinition entities of the application diff --git a/lib/sagittarius/validators/json_schema_validator.rb b/lib/sagittarius/validators/json_schema_validator.rb new file mode 100644 index 00000000..e8885f3b --- /dev/null +++ b/lib/sagittarius/validators/json_schema_validator.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +# Heavily inspired by the implementation of GitLab +# (https://gitlab.com/gitlab-org/gitlab/-/blob/d81c871959acc16f2433b44363a2dfa91ed0e362/app/validators/json_schema_validator.rb) +# which is licensed under a modified version of the MIT license which can be found at +# https://gitlab.com/gitlab-org/gitlab/-/blob/d81c871959acc16f2433b44363a2dfa91ed0e362/LICENSE +# +# The code might have been modified to accommodate for the needs of this project +module Sagittarius + module Validators + class JsonSchemaValidator < ActiveModel::EachValidator + FilenameError = Class.new(StandardError) + BASE_DIRECTORY = %w[app models json_schemas].freeze + + def initialize(options) + raise ArgumentError, "Expected 'filename' as an argument" unless options[:filename] + + @base_directory = options.delete(:base_directory) || BASE_DIRECTORY + + super(options) + end + + def validate_each(record, attribute, value) + value = JSON.parse(JSON.dump(value)) if options[:hash_conversion] == true + value = JSON.parse(value.to_s) if options[:parse_json] == true && !value.nil? + + if options[:detail_errors] + JSON::Validator.validate(schema,value).each do |error| + message = format_error_message(error) + record.errors.add(attribute, message) + end + else + record.errors.add(attribute, error_message) unless valid_schema?(value) + end + end + + private + + attr_reader :base_directory + + def format_error_message(error) + case error['type'] + when 'oneOf' + format_one_of_error(error) + else + error['error'] + end + end + + def format_one_of_error(error) + if error['errors'].present? + error['errors'].map { |e| format_error_message(e) }.join(', ') + else + error['error'] + end + end + + def valid_schema?(value) + JSON::Validator.validate(schema_path, value, :validate_schema => true) + end + + def schema_path + @schema_path ||= Rails.root.join(*base_directory, filename_with_extension).to_s + end + + def filename_with_extension + "#{options[:filename]}.json" + end + + def error_message + options[:message] || 'is not a valid JSON schema' + end + end + end +end diff --git a/spec/factories/data_type_rules.rb b/spec/factories/data_type_rules.rb index 6f18f4c0..5e408428 100644 --- a/spec/factories/data_type_rules.rb +++ b/spec/factories/data_type_rules.rb @@ -3,7 +3,7 @@ FactoryBot.define do factory :data_type_rule do data_type - variant { 1 } - config { {} } + variant { :regex } + config { { pattern: '.*' } } end end diff --git a/spec/models/data_type_rule_spec.rb b/spec/models/data_type_rule_spec.rb index b7ae3910..763d182e 100644 --- a/spec/models/data_type_rule_spec.rb +++ b/spec/models/data_type_rule_spec.rb @@ -11,5 +11,113 @@ describe 'validations' do it { is_expected.to allow_values(*described_class::VARIANTS.keys).for(:variant) } + + context 'when variant is contains_key' do + before { subject.variant = :contains_key } + + context 'validates config with DataTypeContainsKeyRuleConfig schema' do + it 'is correct' do + subject.config = { + key: "id", + data_type_identifier: { + data_type_identifier: "User" + } + } + expect(subject).to be_valid + end + it 'is incorrect' do + subject.config = { + data_type_identifier: { + data_type_identifier: "User" + } + } + expect(subject).not_to be_valid + end + end + end + context 'when variant is contains_type' do + before { subject.variant = :contains_type } + + context 'is correct' do + it 'validates config with DataTypeContainsTypeRuleConfig schema' do + subject.config = { + data_type_identifier: { + data_type_identifier: "User" + } + } + expect(subject).to be_valid + end + end + context 'is incorrect' do + it 'validates config with DataTypeContainsTypeRuleConfig schema' do + subject.config = { + key: "id" + } + expect(subject).not_to be_valid + end + end + end + context 'when variant is item_of_collection' do + before { subject.variant = :item_of_collection } + + context 'validates config with DataTypeItemOfCollectionRuleConfig schema' do + it 'is correct' do + subject.config = { + "items": [ + ["a", 1, true, {"key": "value"}], + {"test": 2}, + [] + ] + } + expect(subject).to be_valid + end + it 'is incorrect' do + subject.config = { + key: "id" + } + expect(subject).not_to be_valid + end + end + end + context 'when variant is number_range' do + before { subject.variant = :number_range } + + context 'validates config with DataTypeNumberRangeRuleConfig schema' do + it 'is correct' do + subject.config = { + from: 1, + to: 10, + steps: 1 + } + expect(subject).to be_valid + end + it 'is incorrect' do + subject.config = { + from: "one", + to: 10, + steps: 1 + } + expect(subject).not_to be_valid + end + end + end + context 'when variant is regex' do + before { subject.variant = :regex } + + context 'validates config with DataTypeRegexRuleConfig schema' do + it 'is correct' do + subject.config = { + pattern: '.*' + } + expect(subject).to be_valid + end + it 'is incorrect' do + subject.config = { + pattern: 1234 + } + expect(subject).not_to be_valid + end + end + end end end diff --git a/spec/services/namespaces/projects/flows/validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation_service_spec.rb index 7d54047d..8894c621 100644 --- a/spec/services/namespaces/projects/flows/validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation_service_spec.rb @@ -2,12 +2,13 @@ require 'rails_helper' -RSpec.describe Namespaces::Projects::Flows::ValidationService do +RSpec.describe Namespaces::Projects::Flows::Validation::ValidationService do subject(:service_response) { described_class.new(create_authentication(current_user), flow).execute } - let(:namespace_project) { create(:namespace_project) } - let(:starting_node) { create(:node_function) } - let(:flow_type) { create(:flow_type) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project).tap { |np| np.update(primary_runtime: runtime) } } + let(:starting_node) { create(:node_function, runtime_function_definition: create(:runtime_function_definition, runtime: runtime)) } + let(:flow_type) { create(:flow_type, runtime: runtime) } let(:flow) { create(:flow, project: namespace_project, flow_type: flow_type, starting_node: starting_node) } context 'when validation succeeds' do From 2b6b2c9d11b6a840ba059ffaf084e40c2245463b Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Thu, 29 May 2025 02:31:12 +0200 Subject: [PATCH 34/54] Enhance flow creation and validation process with new data types and settings --- .../namespaces/projects/flows/create.rb | 25 +++-- .../input/data_type_identifier_input_type.rb | 2 +- .../types/input/flow_setting_input_type.rb | 2 +- .../types/input/generic_mapper_input_type.rb | 2 +- .../types/input/generic_type_input_type.rb | 2 +- .../projects/flows/create_service.rb | 96 +++++++++++++++++++ .../data_type/data_type_validation_service.rb | 2 +- ...e_function_parameter_validation_service.rb | 9 ++ .../flows/validation/validation_service.rb | 37 ++++--- .../projects/flows/validation_service_spec.rb | 4 +- 10 files changed, 157 insertions(+), 24 deletions(-) diff --git a/app/graphql/mutations/namespaces/projects/flows/create.rb b/app/graphql/mutations/namespaces/projects/flows/create.rb index 930446ad..4d0bbaff 100644 --- a/app/graphql/mutations/namespaces/projects/flows/create.rb +++ b/app/graphql/mutations/namespaces/projects/flows/create.rb @@ -15,9 +15,6 @@ class Create < BaseMutation argument :flow, Types::Input::FlowInputType def resolve(project_id:, flow:, **params) - create_params = {} - - project = SagittariusSchema.object_from_id(project_id) if project.nil? @@ -30,11 +27,27 @@ def resolve(project_id:, flow:, **params) return error('Invalid input type id') end + return_type = SagittariusSchema.object_from_id(flow.return_type) + if return_type.nil? + return error('Invalid return type id') + end + flow_type = SagittariusSchema.object_from_id(flow.flow_type) + if flow_type.nil? + return error('Invalid flow type id') + end - - - + Namespaces::Projects::Flows::CreateService.new( + create_authentication(context[:current_user]), + namespace_project: project, + params: { + return_type: return_type, + input_type: input_type, + flow_type: flow_type, + starting_node: params[:starting_node], + settings: params[:settings] || [], + } + ).execute.to_mutation_response(success_key: :flow); end def error(message) diff --git a/app/graphql/types/input/data_type_identifier_input_type.rb b/app/graphql/types/input/data_type_identifier_input_type.rb index c8e5be82..e3a9d20f 100644 --- a/app/graphql/types/input/data_type_identifier_input_type.rb +++ b/app/graphql/types/input/data_type_identifier_input_type.rb @@ -5,7 +5,7 @@ module Input class DataTypeIdentifierInputType < Types::BaseInputObject description 'Input type for data type identifier' - argument :data_type_identifier, String, required: false, + argument :data_type_id, Types::GlobalIdType[::DataTypeIdentifier], required: false, description: 'Data type ID' argument :generic_key, String, required: false, description: 'Generic key value' diff --git a/app/graphql/types/input/flow_setting_input_type.rb b/app/graphql/types/input/flow_setting_input_type.rb index d1ee6266..76894fab 100644 --- a/app/graphql/types/input/flow_setting_input_type.rb +++ b/app/graphql/types/input/flow_setting_input_type.rb @@ -6,7 +6,7 @@ class FlowSettingInputType < Types::BaseInputObject description 'Input type for flow settings' argument :flow_setting_id, String, required: true, - description: 'The identifier of the flow setting' + description: 'The identifier (not database id) of the flow setting' argument :object, GraphQL::Types::JSON, required: true, description: 'The value of the flow setting' diff --git a/app/graphql/types/input/generic_mapper_input_type.rb b/app/graphql/types/input/generic_mapper_input_type.rb index 3ab6f4fa..6b7a8bdd 100644 --- a/app/graphql/types/input/generic_mapper_input_type.rb +++ b/app/graphql/types/input/generic_mapper_input_type.rb @@ -8,7 +8,7 @@ class GenericMapperInputType < Types::BaseInputObject argument :source, Types::Input::DataTypeIdentifierInputType, required: true, description: 'The source data type identifier for the mapper' - argument :target, Types::Input::DataTypeIdentifierInputType, required: true, + argument :target, String, required: true, description: 'The target data type identifier for the mapper' end end diff --git a/app/graphql/types/input/generic_type_input_type.rb b/app/graphql/types/input/generic_type_input_type.rb index eda9c1e2..efc07468 100644 --- a/app/graphql/types/input/generic_type_input_type.rb +++ b/app/graphql/types/input/generic_type_input_type.rb @@ -5,7 +5,7 @@ module Input class GenericTypeInputType < Types::BaseInputObject description 'Input type for generic type operations.' - argument :data_type, Types::Input::DataTypeTypeInput, required: true, description: 'The data type associated with this generic type.' + argument :data_type_id, Types::GlobaIdType[::DataType], required: true, description: 'The data type associated with this generic type.' argument :generic_mappers, [Types::Input::GenericMapperInputType], required: true, description: 'The mappers associated with this generic type.' diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb index cfe75d5e..7f6bf2a2 100644 --- a/app/services/namespaces/projects/flows/create_service.rb +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -20,6 +20,22 @@ def execute end transactional do |t| + settings = [] + params[:settings].each do |graphql_setting| + setting = FlowSetting.new(flow_setting_id: graphql_setting.flow_setting_id, object: graphql_setting.object) + unless setting.valid? + t.rollback_and_return! ServiceResponse.error( + message: 'Invalid flow setting', + payload: setting.errors + ) + settings << setting + end + end + params[:settings] = settings + + node = create_node_function(params[:starting_node], t) + params[:starting_node] = node + flow = Flow.create(project: namespace_project, **params) unless flow.persisted? t.rollback_and_return! ServiceResponse.error( @@ -50,6 +66,86 @@ def execute ServiceResponse.success(message: 'Created new project', payload: flow) end end + + def create_node_function(node_function, t) + runtime_function_definition = SagittariusSchema.object_from_id(node_function.runtime_function_id) + if runtime_function_definition.nil? + t.rollback_and_return! ServiceResponse.error( + message: 'Invalid runtime function id', + payload: :invalid_runtime_function_id + ) + end + + params = [] + node_function.parameters.each do |parameter| + runtime_parameter = SagittariusSchema.object_from_id(parameter.runtime_parameter_definition_id) + if runtime_parameter.nil? + t.rollback_and_return! ServiceResponse.error( + message: 'Invalid runtime parameter id', + payload: :invalid_runtime_parameter_id + ) + end + if parameter.literal_value.present? + params << NodeParameter.create( + runtime_parameter: runtime_parameter, + literal_value: parameter.literal_value, + ) + next + end + if parameter.function_value.present? + params << NodeParameter.create( + runtime_parameter: runtime_parameter, + function_value: create_node_function(parameter.function_value, t), + ) + next + end + if parameter.reference_value.present? + identifier = parameter.reference_value.data_type_identifier + + ReferenceValue.create( + reference_value_id: parameter.reference_value.reference_value_id, + data_type_identifier: get_data_type_identifier(identifier), + ) + end + + end + + next_node = nil + if node_function.next_node.present? + next_node = create_node_function(node_function.next_node, t) + end + + + NodeFunction.create( + next_node: next_node, + runtime_function_definition: runtime_function_definition, + parameters: params + ) + end + + private + + def get_data_type_identifier(identifier) + if identifier.generic_key.present? + return DataTypeIdentifier.create(generic_key: identifier.generic_key) + end + + if identifier.generic_type.present? + data_type = SagittariusSchema.object_from_id(identifier.generic_type.data_type_id) + mappers = identifier.generic_type.mappers.map do |mapper| + GenericMapper.create( + generic_mapper_id: mapper.generic_mapper_id, + source: mapper.source, + target: mapper.target + ) + end + return DataTypeIdentifier.create(generic_type: GenericType.create(data_type: data_type, mappers: mappers)) + end + + if identifier.data_type_id.present? + return DataTypeIdentifier.create(data_type: SagittariusSchema.object_from_id(identifier.data_type_id)) + end + end end end end diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb index b44afc99..cd02a40e 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb @@ -18,7 +18,7 @@ def initialize(current_authentication, flow, data_type) end def execute - logger.debug("Validating data type: #{data_type.name} for flow: #{flow.name}") + logger.debug("Validating data type: #{data_type.name} for flow: #{flow.id}") transactional do |t| if data_type.invalid? diff --git a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb index 5d1b4ede..7a36da94 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb @@ -41,6 +41,15 @@ def execute flow, parameter.reference_value ).execute + return + end + if parameter.function_value.present? + logger.debug("Validating function value: #{parameter.function_value.id} for node parameter: #{parameter.id}") + NodeFunctionValidationService.new( + current_authentication, + flow, + parameter.function_value + ).execute end end end diff --git a/app/services/namespaces/projects/flows/validation/validation_service.rb b/app/services/namespaces/projects/flows/validation/validation_service.rb index d0883e99..270684cb 100644 --- a/app/services/namespaces/projects/flows/validation/validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/validation_service.rb @@ -27,26 +27,30 @@ def execute # --- # Input Type Validation # --- - Namespaces::Projects::Flows::Validation::DataTypeValidationService( - current_authentication, - flow, - flow.input_type - ).execute + if flow.input_type.present? + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService.new( + current_authentication, + flow, + flow.input_type + ).execute + end # --- # Return Type Validation # --- - Namespaces::Projects::Flows::Validation::DataTypeValidationService( - current_authentication, - flow, - flow.return_type - ).execute + if flow.return_type.present? + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService.new( + current_authentication, + flow, + flow.return_type + ).execute + end # --- # Setting # --- flow.flow_settings.each do |setting| - Namespaces::Projects::Flows::Validation::FlowSettingValidationService( + Namespaces::Projects::Flows::Validation::FlowSettingValidationService.new( current_authentication, flow, setting @@ -56,12 +60,21 @@ def execute # --- # Starting node # --- - Namespaces::Projects::Flows::Validation::NodeFunctionValidationService( + Namespaces::Projects::Flows::Validation::NodeFunction::NodeFunctionValidationService.new( current_authentication, flow, flow.starting_node ).execute + # --- + # Flow Type + # --- + FlowTypeValidationService.new( + current_authentication, + flow, + flow.flow_type + ).execute + ServiceResponse.success(message: 'Validation service executed successfully', payload: flow) end end diff --git a/spec/services/namespaces/projects/flows/validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation_service_spec.rb index 8894c621..24d83fb8 100644 --- a/spec/services/namespaces/projects/flows/validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation_service_spec.rb @@ -7,7 +7,9 @@ let(:runtime) { create(:runtime) } let(:namespace_project) { create(:namespace_project).tap { |np| np.update(primary_runtime: runtime) } } - let(:starting_node) { create(:node_function, runtime_function_definition: create(:runtime_function_definition, runtime: runtime)) } + let(:starting_node) { create(:node_function, + runtime_function: create(:runtime_function_definition, runtime: runtime) + ) } let(:flow_type) { create(:flow_type, runtime: runtime) } let(:flow) { create(:flow, project: namespace_project, flow_type: flow_type, starting_node: starting_node) } From d8f76e706de317a1bf85c4020484322a1f0e9fe5 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Thu, 29 May 2025 02:42:46 +0200 Subject: [PATCH 35/54] Recompile structure.sql --- db/structure.sql | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index e2a4fb01..db5259a9 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -280,14 +280,16 @@ ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; CREATE TABLE function_generic_mappers ( id bigint NOT NULL, - source_id bigint, + data_type_identifier_id bigint, + generic_key text, target text NOT NULL, parameter_id text, runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL + updated_at timestamp with time zone NOT NULL, + CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) ); CREATE SEQUENCE function_generic_mappers_id_seq @@ -301,12 +303,14 @@ ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers CREATE TABLE generic_mappers ( id bigint NOT NULL, - runtime_id bigint NOT NULL, target text NOT NULL, - source_id bigint NOT NULL, + generic_key text, + data_type_identifier_id bigint, generic_type_id bigint, + runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL + updated_at timestamp with time zone NOT NULL, + CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) ); CREATE SEQUENCE generic_mappers_id_seq @@ -320,8 +324,8 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, + data_type_identifier_id bigint NOT NULL, runtime_id bigint NOT NULL, - data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); @@ -1136,17 +1140,17 @@ CREATE INDEX index_function_definitions_on_return_type_id ON function_definition CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); +CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); + CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); -CREATE INDEX index_function_generic_mappers_on_source_id ON function_generic_mappers USING btree (source_id); +CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); -CREATE INDEX index_generic_mappers_on_source_id ON generic_mappers USING btree (source_id); - -CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); +CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); @@ -1271,19 +1275,19 @@ ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_2adace81b8 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -1301,7 +1305,7 @@ ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1364,7 +1368,7 @@ ALTER TABLE ONLY node_functions ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_8f97500cd4 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; @@ -1376,7 +1380,7 @@ ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY user_sessions ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -1396,9 +1400,6 @@ ALTER TABLE ONLY reference_values ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_bb587eff6a FOREIGN KEY (input_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_be1833ba72 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; - ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; @@ -1412,7 +1413,7 @@ ALTER TABLE ONLY namespace_project_runtime_assignments ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1427,7 +1428,7 @@ ALTER TABLE ONLY flow_settings ADD CONSTRAINT fk_rails_da3b2fb3c5 FOREIGN KEY (flow_id) REFERENCES flows(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1435,6 +1436,9 @@ ALTER TABLE ONLY runtime_parameter_definitions ALTER TABLE ONLY runtimes ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ALTER TABLE ONLY audit_events ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; From bf83653188e8867f9b1be79d23baab4f59e26586 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Thu, 29 May 2025 20:38:58 +0200 Subject: [PATCH 36/54] Refactor generic types and mappers, update data type associations, and enhance validation services --- Gemfile | 2 +- Gemfile.lock | 4 +- .../types/input/generic_type_input_type.rb | 2 +- app/models/data_type.rb | 5 +- app/models/data_type_identifier.rb | 7 +- app/models/function_generic_mapper.rb | 12 +- app/models/node_function.rb | 3 +- app/models/node_parameter.rb | 3 +- .../projects/flows/create_service.rb | 2 +- .../projects/flows/update_service.rb | 2 +- .../data_type_rule_validation_service.rb | 2 +- .../data_type/data_type_validation_service.rb | 5 +- ...data_type_identifier_validation_service.rb | 10 +- ...data_type_identifier_validation_service.rb | 20 ++-- .../flow_setting_validation_service.rb | 10 ++ .../flow_type_validation_service.rb | 1 - .../update_service.rb | 22 ++-- .../20250525192143_implement_generics.rb | 53 ++++----- db/migrate/20250526124346_create_flows.rb | 1 + db/structure.sql | 54 ++++----- .../input_object/datatypeidentifierinput.md | 2 +- .../datatyperulecontainskeyconfiginput.md | 12 -- .../datatyperulecontainstypeconfiginput.md | 11 -- .../graphql/input_object/datatyperuleinput.md | 12 -- .../graphql/input_object/datatypetypeinput.md | 16 --- docs/graphql/input_object/flowsettinginput.md | 2 +- .../input_object/genericmapperinput.md | 2 +- docs/graphql/input_object/generictypeinput.md | 2 +- docs/graphql/scalar/datatypeidentifierid.md | 5 + spec/factories/function_generic_mappers.rb | 3 +- spec/factories/generic_mappers.rb | 3 +- spec/factories/generic_types.rb | 2 +- spec/factories/node_functions.rb | 1 + spec/factories/node_parameters.rb | 1 + spec/models/data_type_identifier_spec.rb | 9 +- spec/models/function_generic_mapper_spec.rb | 29 +---- spec/models/generic_mapper_spec.rb | 39 +------ spec/models/generic_type_spec.rb | 13 +-- spec/models/node_function_spec.rb | 3 +- spec/models/node_parameter_spec.rb | 3 +- ...untime_function_definition_service_spec.rb | 29 ++--- .../data_type_rule_validation_service_spec.rb | 26 +++++ .../data_type_validation_service_spec.rb | 68 +++++++++++ ...type_identifier_validation_service_spec.rb | 50 ++++++++ ...type_identifier_validation_service_spec.rb | 33 ++++++ .../flow_setting_validation_service_spec.rb | 35 ++++++ .../flow_type_validation_service_spec.rb | 28 +++++ .../validation/validation_service_spec.rb | 108 ++++++++++++++++++ .../projects/flows/validation_service_spec.rb | 25 ---- spec/support/validation_helpers.rb | 26 +++++ 50 files changed, 517 insertions(+), 301 deletions(-) delete mode 100644 docs/graphql/input_object/datatyperulecontainskeyconfiginput.md delete mode 100644 docs/graphql/input_object/datatyperulecontainstypeconfiginput.md delete mode 100644 docs/graphql/input_object/datatyperuleinput.md delete mode 100644 docs/graphql/input_object/datatypetypeinput.md create mode 100644 docs/graphql/scalar/datatypeidentifierid.md create mode 100644 spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/validation_service_spec.rb delete mode 100644 spec/services/namespaces/projects/flows/validation_service_spec.rb create mode 100644 spec/support/validation_helpers.rb diff --git a/Gemfile b/Gemfile index 6671cff6..9b0707dd 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.27' +gem 'tucana', '0.0.28' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 18325aed..4271cf60 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -362,7 +362,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.27) + tucana (0.0.28) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -416,7 +416,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.27) + tucana (= 0.0.28) tzinfo-data RUBY VERSION diff --git a/app/graphql/types/input/generic_type_input_type.rb b/app/graphql/types/input/generic_type_input_type.rb index efc07468..95d9d4d8 100644 --- a/app/graphql/types/input/generic_type_input_type.rb +++ b/app/graphql/types/input/generic_type_input_type.rb @@ -5,7 +5,7 @@ module Input class GenericTypeInputType < Types::BaseInputObject description 'Input type for generic type operations.' - argument :data_type_id, Types::GlobaIdType[::DataType], required: true, description: 'The data type associated with this generic type.' + argument :data_type_id, Types::GlobalIdType[::DataType], required: true, description: 'The data type associated with this generic type.' argument :generic_mappers, [Types::Input::GenericMapperInputType], required: true, description: 'The mappers associated with this generic type.' diff --git a/app/models/data_type.rb b/app/models/data_type.rb index e162af9f..8cc41553 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -7,8 +7,8 @@ class DataType < ApplicationRecord object: 3, datatype: 4, array: 5, - generic: 6, - function: 7, + error: 6, + node: 7, }.with_indifferent_access enum :variant, VARIANTS, prefix: :variant @@ -20,6 +20,7 @@ class DataType < ApplicationRecord has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :rules, class_name: 'DataTypeRule', inverse_of: :data_type has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :data_type + has_many :generic_types, class_name: 'GenericType', inverse_of: :data_type validates :variant, presence: true, inclusion: { diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 69503d06..4daa8ac9 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -2,12 +2,11 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers - belongs_to :generic_type, optional: true, inverse_of: :data_type_identifier + belongs_to :generic_type, optional: true, inverse_of: :data_type_identifiers belongs_to :runtime, inverse_of: :data_type_identifiers - has_many :generic_types, inverse_of: :data_type_identifier - has_many :generic_mappers, inverse_of: :data_type_identifier - has_many :function_generic_mappers, class_name: 'GenericMapper', inverse_of: :data_type_identifier + has_many :generic_mappers, inverse_of: :source + has_many :function_generic_mappers, class_name: 'FunctionGenericMapper', inverse_of: :source validate :exactly_one_of_generic_key_data_type_id_generic_type_id diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 0612a21a..10d8b015 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -1,21 +1,11 @@ # frozen_string_literal: true class FunctionGenericMapper < ApplicationRecord - belongs_to :data_type_identifier, optional: true, inverse_of: :function_generic_mappers + belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, inverse_of: :function_generic_mappers validates :target, presence: true - validate :exactly_one_of_generic_key_or_data_type_identifier_id - - private - - def exactly_one_of_generic_key_or_data_type_identifier_id - values = [generic_key.present?, data_type_identifier.present?] - return if values.count(true) == 1 - - errors.add(:base, 'Exactly one of generic_key or data_type_identifier_id must be present') - end end diff --git a/app/models/node_function.rb b/app/models/node_function.rb index 5359cb1c..6d81530c 100644 --- a/app/models/node_function.rb +++ b/app/models/node_function.rb @@ -4,7 +4,8 @@ class NodeFunction < ApplicationRecord belongs_to :runtime_function, class_name: 'RuntimeFunctionDefinition' belongs_to :next_node, class_name: 'NodeFunction', optional: true - has_many :node_parameters, inverse_of: :function_value + has_many :node_parameter_values, class_name: 'NodeParameter', inverse_of: :function_value + has_many :node_parameters, class_name: 'NodeParameter', inverse_of: :node_function validate :validate_recursion, if: :next_node_changed? diff --git a/app/models/node_parameter.rb b/app/models/node_parameter.rb index 1f6ca1c7..f580828d 100644 --- a/app/models/node_parameter.rb +++ b/app/models/node_parameter.rb @@ -3,7 +3,8 @@ class NodeParameter < ApplicationRecord belongs_to :runtime_parameter, class_name: 'RuntimeParameterDefinition' belongs_to :reference_value, optional: true - belongs_to :function_value, class_name: 'NodeFunction', optional: true + belongs_to :function_value, class_name: 'NodeFunction', optional: true, inverse_of: :node_parameter_values + belongs_to :node_function, class_name: 'NodeFunction', inverse_of: :node_parameters validate :only_one_value_present diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb index 7f6bf2a2..f4751e18 100644 --- a/app/services/namespaces/projects/flows/create_service.rb +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -44,7 +44,7 @@ def execute ) end - res = ValidationService.new(current_authentication, flow).execute + res = Validation::ValidationService.new(current_authentication, flow).execute if res.error? t.rollback_and_return! ServiceResponse.error( diff --git a/app/services/namespaces/projects/flows/update_service.rb b/app/services/namespaces/projects/flows/update_service.rb index 2f35e77b..24703656 100644 --- a/app/services/namespaces/projects/flows/update_service.rb +++ b/app/services/namespaces/projects/flows/update_service.rb @@ -31,7 +31,7 @@ def execute ) end - res = ValidationService.new(current_authentication, flow).execute + res = Validation::ValidationService.new(current_authentication, flow).execute if res.error? t.rollback_and_return! ServiceResponse.error( diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb index bb2f7034..8d209321 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb @@ -21,7 +21,7 @@ def initialize(current_authentication, flow, data_type, rule) def execute logger.debug("Validating data type rule #{rule.id}") - transaction do |t| + transactional do |t| if rule.invalid? logger.debug(message: "Data type rule validation (model) failed", flow: flow.id, diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb index cd02a40e..e603eb68 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb @@ -18,7 +18,7 @@ def initialize(current_authentication, flow, data_type) end def execute - logger.debug("Validating data type: #{data_type.name} for flow: #{flow.id}") + logger.debug("Validating data type: #{data_type.id} for flow: #{flow.id}") transactional do |t| if data_type.invalid? @@ -62,7 +62,7 @@ def execute data_type.rules.each do |rule| logger.debug("Validating data type rule: #{rule.id} for data type: #{data_type.id}") - ::DataTypeRuleValidationService.new( + DataTypeRuleValidationService.new( current_authentication, flow, data_type, @@ -71,6 +71,7 @@ def execute end logger.debug(message: "Data type is valid", flow: flow.id, data_type: data_type.id) + nil end end end diff --git a/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb index e5cf82d5..ae4dd839 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb @@ -33,6 +33,13 @@ def execute ) ) end + if data_type_identifier.data_type.present? + DataTypeValidationService.new( + current_authentication, + flow, + data_type_identifier.data_type + ).execute + end if data_type_identifier.runtime != flow.project.primary_runtime logger.debug(message: "Data type identifier runtime mismatch", primary_runtime: flow.project.primary_runtime.id, @@ -46,9 +53,6 @@ def execute ) ) end - - - end end end diff --git a/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb index fc7ace12..69d8046a 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb @@ -9,28 +9,28 @@ class GenericMapperDataTypeIdentifierValidationService include Code0::ZeroTrack::Loggable include Sagittarius::Database::Transactional - attr_reader :current_authentication, :flow, :parameter, :mapper, :source + attr_reader :current_authentication, :flow, :parameter, :mapper, :data_type_identifier - def initialize(current_authentication, flow, parameter, mapper, source) + def initialize(current_authentication, flow, parameter, mapper, data_type_identifier) @current_authentication = current_authentication @flow = flow @parameter = parameter @mapper = mapper - @source = source + @data_type_identifier = data_type_identifier end def execute - logger.debug("Validating flow_type: #{data_type_identifier.inspect} for flow: #{flow.id}") + logger.debug("Validating generic_mapper: #{mapper.inspect}, source for flow: #{flow.id}") transactional do |t| ::GenericDataTypeIdentifierValidationService.new( current_authentication, flow, - source + data_type_identifier ).execute - if source.generic_key.present? - unless parameter.function_value.runtime_function_definition.generic_keys.has?(source.generic_key) + if data_type_identifier.generic_key.present? + unless parameter.function_value.runtime_function_definition.generic_keys.has?(data_type_identifier.generic_key) t.rollback_and_return!( ServiceResponse.error( message: "Generic type #{parameter.generic_type.data_type.id} does not have a generic key for source #{source.generic_key}", @@ -40,15 +40,15 @@ def execute end return end - if source.data_type.present? + if data_type_identifier.data_type.present? DataTypeValidationService.new( current_authentication, flow, - source.data_type + data_type_identifier.data_type ).execute return end - if source.generic_type.present? + if data_type_identifier.generic_type.present? ::NodeFunction::GenericTypeValidationService.new( current_authentication, flow, diff --git a/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb b/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb index 43aa8240..939d0f14 100644 --- a/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb @@ -19,6 +19,16 @@ def initialize(current_authentication, flow, setting) def execute logger.debug("Validating setting: #{setting.inspect} for flow: #{flow.id}") + transactional do |t| + if setting.invalid? + logger.debug("Invalid setting: #{setting.errors.full_messages.join(', ')}") + t.rollback_and_return! ServiceResponse.error( + message: 'Invalid flow setting', + payload: setting.errors + ) + end + end + # Maybe something in the future we will validate the setting object but currently its not typed end diff --git a/app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb index 3253e259..e1dc403a 100644 --- a/app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb @@ -29,7 +29,6 @@ def execute ) end end - end end end diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index e61b1c88..537d28fd 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -51,7 +51,7 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.deprecation_messages) db_object.error_types = update_error_types(runtime_function_definition.error_type_identifiers, db_object, t) - db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object) + db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object, t) if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -69,23 +69,20 @@ def update_runtime_function_definition(runtime_function_definition, t) end # These mappers can be either generic mappers or generic function mappers. - def update_mappers(generic_mappers, runtime_function_definition = nil) + def update_mappers(generic_mappers, runtime_function_definition, t) generic_mappers.to_a.map do |generic_mapper| if generic_mapper.is_a? Tucana::Shared::GenericMapper mapper = GenericMapper.create_or_find_by(runtime: current_runtime, target: generic_mapper.target, - generic_key: generic_mapper.generic_key, - data_type_identifier: - (generic_mapper.generic_key.nil? ? data_type_identifier : nil)) - + source: find_data_type_identifier(generic_mapper.source, + generic_mappers, t)) end if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper mapper = FunctionGenericMapper.create_or_find_by( runtime_id: current_runtime.id, runtime_function_definition: runtime_function_definition, - data_type_identifier: (generic_mapper.generic_key.nil? ? data_type_identifier : nil), + source: find_data_type_identifier(generic_mapper.source, generic_mappers, t), target: generic_mapper.target, - generic_key: generic_mapper.generic_key, parameter_id: generic_mapper.parameter_id ) end @@ -110,16 +107,16 @@ def find_data_type_identifier(identifier, generic_mappers, t) identifier.generic_type.generic_mappers.each do |generic_mapper| arr << generic_mapper end - data_type_identifier = find_data_type_identifier(identifier.generic_type.data_type_identifier, arr, t) + data_type = find_data_type(identifier.generic_type.data_type_identifier, t) generic_type = GenericType.find_by( runtime_id: current_runtime.id, - data_type_identifier_id: data_type_identifier.id + data_type: data_type ) if generic_type.nil? generic_type = GenericType.create( runtime_id: current_runtime.id, - data_type_identifier_id: data_type_identifier.id + data_type: data_type ) end @@ -130,7 +127,8 @@ def find_data_type_identifier(identifier, generic_mappers, t) ) end - generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers)) + generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers, nil, + t)) return create_data_type_identifier(t, generic_type_id: generic_type.id) end diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 4151d076..65926c2e 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -8,37 +8,28 @@ def change add_column :data_types, :generic_keys, 'text[]', null: false, default: [] create_table :data_type_identifiers do |t| - # One of them needs to be set + # One of them needs to be set will be enforced later t.text :generic_key, null: true t.references :data_type, null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end create_table :generic_types do |t| - t.references :data_type_identifier, null: false, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + t.references :data_type, null: false, foreign_key: { to_table: :data_types, on_delete: :cascade } t.timestamps_with_timezone end create_table :generic_mappers do |t| - t.text :target, null: false - # One of them needs to be set - t.text :generic_key, null: true - t.references :data_type_identifier, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } - - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:generic_mappers, :source, :one_of) + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } - t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :cascade } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + t.text :target, null: false + t.references :source, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } + t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :restrict } t.timestamps_with_timezone end @@ -50,44 +41,42 @@ def change name: check_constraint_name(:data_type_identifiers, :type, :one_of) create_table :function_generic_mappers do |t| - t.references :data_type_identifier, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :cascade } - t.text :generic_key, null: true - - t.check_constraint '(num_nonnulls(generic_key, data_type_identifier_id) = 1)', - name: check_constraint_name(:function_generic_mappers, :source, :one_of) + t.references :source, null: true, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } t.text :target, null: false t.text :parameter_id, null: true t.references :runtime_parameter_definition, null: true, foreign_key: { to_table: :runtime_parameter_definitions, - on_delete: :cascade } + on_delete: :restrict } t.references :runtime_function_definition, null: true, foreign_key: { to_table: :runtime_function_definitions, - on_delete: :cascade } - # Unsure if restrict is correct here - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :restrict } + on_delete: :restrict } + + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.timestamps_with_timezone end - remove_column :runtime_function_definitions, :return_type_id + remove_reference :runtime_function_definitions, :return_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] - remove_column :runtime_parameter_definitions, :data_type_id + remove_reference :runtime_parameter_definitions, :data_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_column :parameter_definitions, :data_type_id + remove_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_column :function_definitions, :return_type_id + remove_reference :function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true end diff --git a/db/migrate/20250526124346_create_flows.rb b/db/migrate/20250526124346_create_flows.rb index 9a7f3948..bc605938 100644 --- a/db/migrate/20250526124346_create_flows.rb +++ b/db/migrate/20250526124346_create_flows.rb @@ -33,6 +33,7 @@ def change create_table :node_parameters do |t| t.references :runtime_parameter, null: false, foreign_key: { to_table: :runtime_parameter_definitions, on_delete: :cascade } + t.references :node_function, null: false, foreign_key: { to_table: :node_functions, on_delete: :cascade } t.jsonb :literal_value, null: true t.references :reference_value, null: true, foreign_key: { to_table: :reference_values, diff --git a/db/structure.sql b/db/structure.sql index db5259a9..29eb09c4 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -280,16 +280,14 @@ ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; CREATE TABLE function_generic_mappers ( id bigint NOT NULL, - data_type_identifier_id bigint, - generic_key text, + source_id bigint, target text NOT NULL, parameter_id text, runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - CONSTRAINT check_8b2921e4ae CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) + updated_at timestamp with time zone NOT NULL ); CREATE SEQUENCE function_generic_mappers_id_seq @@ -303,14 +301,12 @@ ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers CREATE TABLE generic_mappers ( id bigint NOT NULL, + runtime_id bigint NOT NULL, target text NOT NULL, - generic_key text, - data_type_identifier_id bigint, + source_id bigint NOT NULL, generic_type_id bigint, - runtime_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - CONSTRAINT check_48eccc6485 CHECK ((num_nonnulls(generic_key, data_type_identifier_id) = 1)) + updated_at timestamp with time zone NOT NULL ); CREATE SEQUENCE generic_mappers_id_seq @@ -324,8 +320,8 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, - data_type_identifier_id bigint NOT NULL, runtime_id bigint NOT NULL, + data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); @@ -593,6 +589,7 @@ ALTER SEQUENCE node_functions_id_seq OWNED BY node_functions.id; CREATE TABLE node_parameters ( id bigint NOT NULL, runtime_parameter_id bigint NOT NULL, + node_function_id bigint NOT NULL, literal_value jsonb, reference_value_id bigint, function_value_id bigint, @@ -1140,17 +1137,17 @@ CREATE INDEX index_function_definitions_on_return_type_id ON function_definition CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); -CREATE INDEX index_function_generic_mappers_on_data_type_identifier_id ON function_generic_mappers USING btree (data_type_identifier_id); - CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); -CREATE INDEX index_generic_mappers_on_data_type_identifier_id ON generic_mappers USING btree (data_type_identifier_id); +CREATE INDEX index_function_generic_mappers_on_source_id ON function_generic_mappers USING btree (source_id); CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); -CREATE INDEX index_generic_types_on_data_type_identifier_id ON generic_types USING btree (data_type_identifier_id); +CREATE INDEX index_generic_mappers_on_source_id ON generic_mappers USING btree (source_id); + +CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); @@ -1216,6 +1213,8 @@ CREATE INDEX index_node_functions_on_runtime_function_id ON node_functions USING CREATE INDEX index_node_parameters_on_function_value_id ON node_parameters USING btree (function_value_id); +CREATE INDEX index_node_parameters_on_node_function_id ON node_parameters USING btree (node_function_id); + CREATE INDEX index_node_parameters_on_reference_value_id ON node_parameters USING btree (reference_value_id); CREATE INDEX index_node_parameters_on_runtime_parameter_id ON node_parameters USING btree (runtime_parameter_id); @@ -1265,6 +1264,9 @@ ALTER TABLE ONLY runtime_function_definition_error_types ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_0c2eb746ef FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT fk_rails_0d79310cfa FOREIGN KEY (node_function_id) REFERENCES node_functions(id) ON DELETE CASCADE; + ALTER TABLE ONLY node_parameters ADD CONSTRAINT fk_rails_0ff4fd0049 FOREIGN KEY (runtime_parameter_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; @@ -1275,19 +1277,19 @@ ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_29b2651173 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_31f6eb3ef3 FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_2adace81b8 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -1305,7 +1307,7 @@ ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1368,7 +1370,7 @@ ALTER TABLE ONLY node_functions ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_8f97500cd4 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; @@ -1380,7 +1382,7 @@ ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; ALTER TABLE ONLY user_sessions ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -1400,6 +1402,9 @@ ALTER TABLE ONLY reference_values ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_bb587eff6a FOREIGN KEY (input_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_be1833ba72 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; + ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; @@ -1413,7 +1418,7 @@ ALTER TABLE ONLY namespace_project_runtime_assignments ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1428,7 +1433,7 @@ ALTER TABLE ONLY flow_settings ADD CONSTRAINT fk_rails_da3b2fb3c5 FOREIGN KEY (flow_id) REFERENCES flows(id) ON DELETE CASCADE; ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; + ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; @@ -1436,9 +1441,6 @@ ALTER TABLE ONLY runtime_parameter_definitions ALTER TABLE ONLY runtimes ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_f32ba64eee FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE CASCADE; - ALTER TABLE ONLY audit_events ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; diff --git a/docs/graphql/input_object/datatypeidentifierinput.md b/docs/graphql/input_object/datatypeidentifierinput.md index 47f83fa4..d658295c 100644 --- a/docs/graphql/input_object/datatypeidentifierinput.md +++ b/docs/graphql/input_object/datatypeidentifierinput.md @@ -8,6 +8,6 @@ Input type for data type identifier | Name | Type | Description | |------|------|-------------| -| `dataTypeIdentifier` | [`String`](../scalar/string.md) | Data type ID | +| `dataTypeId` | [`DataTypeIdentifierID`](../scalar/datatypeidentifierid.md) | Data type ID | | `genericKey` | [`String`](../scalar/string.md) | Generic key value | | `genericType` | [`GenericTypeInput`](../input_object/generictypeinput.md) | Generic type information | diff --git a/docs/graphql/input_object/datatyperulecontainskeyconfiginput.md b/docs/graphql/input_object/datatyperulecontainskeyconfiginput.md deleted file mode 100644 index 74c25d61..00000000 --- a/docs/graphql/input_object/datatyperulecontainskeyconfiginput.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: DataTypeRuleContainsKeyConfigInput ---- - -Input type for Data Type Rule Contains A Key configuration - -## Fields - -| Name | Type | Description | -|------|------|-------------| -| `dataTypeIdentifier` | [`DataTypeIdentifierInput`](../input_object/datatypeidentifierinput.md) | The identifier of the data type this rule applies to | -| `key` | [`String!`](../scalar/string.md) | The key to check for in the data type rule | diff --git a/docs/graphql/input_object/datatyperulecontainstypeconfiginput.md b/docs/graphql/input_object/datatyperulecontainstypeconfiginput.md deleted file mode 100644 index 14cb28b6..00000000 --- a/docs/graphql/input_object/datatyperulecontainstypeconfiginput.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: DataTypeRuleContainsTypeConfigInput ---- - -Input type for Data Type Rule Contains Type configuration - -## Fields - -| Name | Type | Description | -|------|------|-------------| -| `dataTypeIdentifier` | [`DataTypeIdentifierInput`](../input_object/datatypeidentifierinput.md) | The identifier of the data type this rule applies to | diff --git a/docs/graphql/input_object/datatyperuleinput.md b/docs/graphql/input_object/datatyperuleinput.md deleted file mode 100644 index 0b569307..00000000 --- a/docs/graphql/input_object/datatyperuleinput.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: DataTypeRuleInput ---- - -Input type for Data Type Rule - -## Fields - -| Name | Type | Description | -|------|------|-------------| -| `containsKey` | [`DataTypeRuleContainsKeyConfigInput`](../input_object/datatyperulecontainskeyconfiginput.md) | Configuration for contains key rule | -| `containsValue` | [`DataTypeRuleContainsTypeConfigInput`](../input_object/datatyperulecontainstypeconfiginput.md) | Configuration for contains type rule | diff --git a/docs/graphql/input_object/datatypetypeinput.md b/docs/graphql/input_object/datatypetypeinput.md deleted file mode 100644 index 501d38e5..00000000 --- a/docs/graphql/input_object/datatypetypeinput.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: DataTypeTypeInput ---- - -Represents a DataType - -## Fields - -| Name | Type | Description | -|------|------|-------------| -| `genericKeys` | [`[String!]`](../scalar/string.md) | The generic keys for the datatype | -| `identifier` | [`String!`](../scalar/string.md) | The identifier scoped to the namespace | -| `namespaceId` | [`NamespaceID!`](../scalar/namespaceid.md) | The namespace where this datatype belongs to | -| `parentTypeIdentifier` | [`String`](../scalar/string.md) | The identifier of the parent data type, if any | -| `rules` | [`[DataTypeRuleInput!]`](../input_object/datatyperuleinput.md) | The rules for the datatype | -| `variant` | [`DataTypeVariant!`](../enum/datatypevariant.md) | The type of the datatype | diff --git a/docs/graphql/input_object/flowsettinginput.md b/docs/graphql/input_object/flowsettinginput.md index 5a39c64b..7f2be2c2 100644 --- a/docs/graphql/input_object/flowsettinginput.md +++ b/docs/graphql/input_object/flowsettinginput.md @@ -8,5 +8,5 @@ Input type for flow settings | Name | Type | Description | |------|------|-------------| -| `flowSettingId` | [`String!`](../scalar/string.md) | The identifier of the flow setting | +| `flowSettingId` | [`String!`](../scalar/string.md) | The identifier (not database id) of the flow setting | | `object` | [`JSON!`](../scalar/json.md) | The value of the flow setting | diff --git a/docs/graphql/input_object/genericmapperinput.md b/docs/graphql/input_object/genericmapperinput.md index 2316955b..3a9bb9b8 100644 --- a/docs/graphql/input_object/genericmapperinput.md +++ b/docs/graphql/input_object/genericmapperinput.md @@ -9,4 +9,4 @@ Input type for generic mappers | Name | Type | Description | |------|------|-------------| | `source` | [`DataTypeIdentifierInput!`](../input_object/datatypeidentifierinput.md) | The source data type identifier for the mapper | -| `target` | [`DataTypeIdentifierInput!`](../input_object/datatypeidentifierinput.md) | The target data type identifier for the mapper | +| `target` | [`String!`](../scalar/string.md) | The target data type identifier for the mapper | diff --git a/docs/graphql/input_object/generictypeinput.md b/docs/graphql/input_object/generictypeinput.md index 446d0cfa..8201dc8d 100644 --- a/docs/graphql/input_object/generictypeinput.md +++ b/docs/graphql/input_object/generictypeinput.md @@ -8,5 +8,5 @@ Input type for generic type operations. | Name | Type | Description | |------|------|-------------| -| `dataType` | [`DataTypeTypeInput!`](../input_object/datatypetypeinput.md) | The data type associated with this generic type. | +| `dataTypeId` | [`DataTypeID!`](../scalar/datatypeid.md) | The data type associated with this generic type. | | `genericMappers` | [`[GenericMapperInput!]!`](../input_object/genericmapperinput.md) | The mappers associated with this generic type. | diff --git a/docs/graphql/scalar/datatypeidentifierid.md b/docs/graphql/scalar/datatypeidentifierid.md new file mode 100644 index 00000000..b106460b --- /dev/null +++ b/docs/graphql/scalar/datatypeidentifierid.md @@ -0,0 +1,5 @@ +--- +title: DataTypeIdentifierID +--- + +A unique identifier for all DataTypeIdentifier entities of the application diff --git a/spec/factories/function_generic_mappers.rb b/spec/factories/function_generic_mappers.rb index 96e28ab6..e448ce1d 100644 --- a/spec/factories/function_generic_mappers.rb +++ b/spec/factories/function_generic_mappers.rb @@ -4,7 +4,6 @@ factory :function_generic_mapper do target { nil } runtime_parameter_definition { nil } - generic_key { nil } - data_type_identifier { nil } + source { nil } end end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index 33a5cd58..36a7fdc9 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -4,7 +4,6 @@ factory :generic_mapper do runtime target { nil } - generic_key { nil } - data_type_identifier { nil } + source { nil } end end diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index a4eef104..a7601bec 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -4,6 +4,6 @@ factory :generic_type do runtime generic_mappers { [] } - data_type_identifier { nil } + data_type end end diff --git a/spec/factories/node_functions.rb b/spec/factories/node_functions.rb index 5dd5bfa2..85097149 100644 --- a/spec/factories/node_functions.rb +++ b/spec/factories/node_functions.rb @@ -5,5 +5,6 @@ runtime_function factory: %i[runtime_function_definition] next_node { nil } node_parameters { [] } + node_parameter_values { [] } end end diff --git a/spec/factories/node_parameters.rb b/spec/factories/node_parameters.rb index 5cbf0a59..213c71c7 100644 --- a/spec/factories/node_parameters.rb +++ b/spec/factories/node_parameters.rb @@ -3,6 +3,7 @@ FactoryBot.define do factory :node_parameter do runtime_parameter factory: %i[runtime_parameter_definition] + node_function literal_value { 'value' } reference_value { nil } function_value { nil } diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index 11d422d7..a2270dcd 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -8,18 +8,17 @@ it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to have_many(:generic_types) } - it { is_expected.to have_many(:generic_mappers) } + it { is_expected.to have_many(:generic_mappers).inverse_of(:source) } + it { is_expected.to have_many(:function_generic_mappers).inverse_of(:source) } end describe 'validations' do it 'is valid with exactly one of generic_key, data_type_id, or generic_type_id' do expect(build(:data_type_identifier, generic_key: 'key')).to be_valid expect(build(:data_type_identifier, data_type: create(:data_type))).to be_valid + generic_type = create(:generic_type, data_type: create(:data_type)) expect(build(:data_type_identifier, - generic_type: create(:generic_type, - data_type_identifier: create(:data_type_identifier, - generic_key: 'x')))).to be_valid + generic_type: generic_type)).to be_valid end it 'is invalid when none of generic_key, data_type_id, or generic_type_id are set' do diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index c83b8546..6dd7b9b6 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -4,7 +4,7 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do - it { is_expected.to belong_to(:data_type_identifier).optional } + it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier').inverse_of(:function_generic_mappers) } it { is_expected.to belong_to(:runtime_parameter_definition).optional } it { @@ -12,31 +12,4 @@ .optional.inverse_of(:generic_mappers) } end - - describe 'validations' do - it 'is valid with target and one of generic_key or data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'x') - expect(build(:function_generic_mapper, target: 'do_something', generic_key: 'param')).to be_valid - expect(build(:function_generic_mapper, target: 'do_something', data_type_identifier: dti)).to be_valid - end - - it 'is invalid with both generic_key and data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'x') - mapper = build(:function_generic_mapper, target: 'x', generic_key: 'param', data_type_identifier: dti) - expect(mapper).not_to be_valid - expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') - end - - it 'is invalid with neither generic_key nor data_type_identifier' do - mapper = build(:function_generic_mapper, target: 'x', generic_key: nil, data_type_identifier: nil) - expect(mapper).not_to be_valid - expect(mapper.errors[:base]).to include('Exactly one of generic_key or data_type_identifier_id must be present') - end - - it 'is invalid without a target' do - mapper = build(:function_generic_mapper, target: nil, generic_key: 'something') - expect(mapper).not_to be_valid - expect(mapper.errors[:target]).to include("can't be blank") - end - end end diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index bdc7873f..843a3649 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -7,43 +7,6 @@ describe 'associations' do it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to belong_to(:data_type_identifier).optional } - end - - describe 'validations' do - it 'is valid with target and exactly one of generic_key or data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - - expect(build(:generic_mapper, target: 'target', generic_key: 'key1', generic_type: generic_type)).to be_valid - expect(build(:generic_mapper, target: 'target', data_type_identifier: dti, - generic_type: generic_type)).to be_valid - end - - it 'is invalid without a target' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: nil, generic_key: 'key1', generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:target]).to include("can't be blank") - end - - it 'is invalid when neither generic_key nor data_type_identifier is set' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: 'target', generic_key: nil, data_type_identifier: nil, - generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') - end - - it 'is invalid when both generic_key and data_type_identifier are set' do - dti = create(:data_type_identifier, generic_key: 'key') - generic_type = create(:generic_type, data_type_identifier: dti) - gm = build(:generic_mapper, target: 'target', generic_key: 'key1', data_type_identifier: dti, - generic_type: generic_type) - expect(gm).not_to be_valid - expect(gm.errors[:base]).to include('Exactly one of generic_key or data_type_identifier must be present') - end + it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier') } end end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index b97b9ca7..86ff0fec 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -5,19 +5,8 @@ RSpec.describe GenericType do describe 'associations' do - it { is_expected.to belong_to(:data_type_identifier) } + it { is_expected.to belong_to(:data_type) } it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_mappers) } end - - describe 'validations' do - it 'is valid with a data_type_identifier' do - dti = create(:data_type_identifier, generic_key: 'key') - expect(build(:generic_type, data_type_identifier: dti)).to be_valid - end - - it 'is invalid without a data_type_identifier' do - expect(build(:generic_type, data_type_identifier: nil)).not_to be_valid - end - end end diff --git a/spec/models/node_function_spec.rb b/spec/models/node_function_spec.rb index fc349531..dd584522 100644 --- a/spec/models/node_function_spec.rb +++ b/spec/models/node_function_spec.rb @@ -9,6 +9,7 @@ it { is_expected.to belong_to(:runtime_function).class_name('RuntimeFunctionDefinition') } it { is_expected.to belong_to(:next_node).class_name('NodeFunction').optional } - it { is_expected.to have_many(:node_parameters).inverse_of(:function_value) } + it { is_expected.to have_many(:node_parameter_values).inverse_of(:function_value) } + it { is_expected.to have_many(:node_parameters).inverse_of(:node_function) } end end diff --git a/spec/models/node_parameter_spec.rb b/spec/models/node_parameter_spec.rb index 000ead41..5da2e292 100644 --- a/spec/models/node_parameter_spec.rb +++ b/spec/models/node_parameter_spec.rb @@ -12,7 +12,8 @@ describe 'associations' do it { is_expected.to belong_to(:runtime_parameter).class_name('RuntimeParameterDefinition') } it { is_expected.to belong_to(:reference_value).optional } - it { is_expected.to belong_to(:function_value).class_name('NodeFunction').optional } + it { is_expected.to belong_to(:function_value).class_name('NodeFunction').inverse_of(:node_parameter_values).optional } + it { is_expected.to belong_to(:node_function).class_name('NodeFunction').inverse_of(:node_parameters) } end describe 'validations' do diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 5473a97a..8aada144 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -15,13 +15,7 @@ end let!(:generic_type) do - create(:generic_type, - runtime: runtime, - data_type_identifier: - create(:data_type_identifier, - runtime: runtime, - data_type: create(:data_type, - runtime: runtime).reload).reload).reload + create(:generic_type, runtime: runtime, data_type: create(:data_type, runtime: runtime)) end let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload } let(:error_type) { create(:data_type, runtime: runtime) } @@ -44,16 +38,13 @@ ], return_type_identifier: { generic_type: { - data_type_identifier: { # Without reloads it just fails - data_type_identifier: return_type.reload.generic_type - .reload.data_type_identifier.reload.data_type.reload.identifier, - }, - generic_mappers: [{ generic_key: 'T', target: 'V' }], + data_type_identifier: return_type.generic_type.data_type.identifier, + generic_mappers: [{ source: { generic_key: 'T' }, target: 'V' }], }, }, generic_mappers: [ { - generic_key: 'X', + source: { generic_key: 'X' }, target: 'Y', parameter_id: 'some_id', } @@ -89,15 +80,15 @@ expect(stub.update(message, authorization(runtime)).success).to be(true) expect(GenericMapper.count).to eq(1) - expect(GenericMapper.last.generic_key).to eq('T') + expect(GenericMapper.last.source.generic_key).to eq('T') expect(GenericMapper.last.target).to eq('V') expect(GenericType.count).to eq(1) function = RuntimeFunctionDefinition.last expect(function.runtime_name).to eq('runtime_function_id') - expect(function.return_type.generic_type.reload.data_type_identifier.data_type.identifier) - .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) + expect(function.return_type.generic_type.reload.data_type.identifier) + .to eq(return_type.generic_type.data_type.identifier) expect(function.names.first.content).to eq('Eine Funktion') expect(function.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function.documentations.first.content).to eq('Eine Funktionsdokumentation') @@ -115,8 +106,8 @@ expect(function_definition.names.first.content).to eq('Eine Funktion') expect(function_definition.descriptions.first.content).to eq('Eine Funktionsbeschreibung') expect(function_definition.documentations.first.content).to eq('Eine Funktionsdokumentation') - expect(function_definition.return_type.generic_type.reload.data_type_identifier.data_type.identifier) - .to eq(return_type.generic_type.data_type_identifier.data_type.identifier) + expect(function_definition.return_type.generic_type.reload.data_type.identifier) + .to eq(return_type.generic_type.data_type.identifier) parameter_definition = ParameterDefinition.first expect(parameter_definition.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) expect(parameter_definition.names.first.content).to eq('Ein Parameter') @@ -125,7 +116,7 @@ expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) expect(FunctionGenericMapper.count).to eq(1) - expect(FunctionGenericMapper.last.generic_key).to eq('X') + expect(FunctionGenericMapper.last.source.generic_key).to eq('X') expect(FunctionGenericMapper.last.target).to eq('Y') expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb new file mode 100644 index 00000000..4dbfa152 --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::Validation::DataType::DataTypeRuleValidationService do + + subject(:service_response) { described_class.new(create_authentication(current_user), flow, data_type, rule).execute } + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } + let(:flow) { create(:flow, project: namespace_project) } + let(:data_type) { create(:data_type) } + let(:rule) { create(:data_type_rule, data_type: data_type, variant: :regex, config: { pattern: '.*' }) } + + context 'when rule is valid' do + it { expect(service_response).to eq(nil) } + end + + context 'when rule is invalid' do + let(:rule) { build(:data_type_rule, data_type: data_type, variant: :regex, config: { not_a_valid_key: '.*' }) } + + it 'returns an error message' do + expect(service_response).to be_error + expect(rule.errors.full_messages).to include("Config is not a valid JSON schema") + end + end +end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb new file mode 100644 index 00000000..891c2848 --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb @@ -0,0 +1,68 @@ +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService do + include_context 'mocked service class instances' + + let(:all_service_expectations) do + # Default case + { + Namespaces::Projects::Flows::Validation::DataType::DataTypeRuleValidationService => 0, + } + end + + let(:default_execute_response) { ServiceResponse.success(payload: default_payload) } + + let(:mocked_service_expectations) { all_service_expectations } + + subject(:service_response) { described_class.new(create_authentication(current_user), flow, data_type).execute } + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } + + let(:flow) { create(:flow, project: namespace_project) } + let(:data_type) { create(:data_type, runtime: runtime) } + + context 'when data_type.runtime == runtime' do + it { expect(service_response).to eq(nil) } + end + + context 'when data_type.runtime != runtime' do + let(:data_type) { create(:data_type) } + + + it 'returns an error' do + expect(service_response).to be_error + expect(service_response.payload).to eq(:runtime_mismatch) + end + end + + context 'when rules are set' do + let(:data_type) { create(:data_type, runtime: runtime, rules: [create(:data_type_rule)]) } + + let(:mocked_service_expectations) do + { + **all_service_expectations, + Namespaces::Projects::Flows::Validation::DataType::DataTypeRuleValidationService => 1, + } + end + + it { expect(service_response).to eq(nil) } + end + + context 'when parent type is set' do + let(:parent_data_type) { create(:data_type, runtime: runtime) } + let(:data_type) { create(:data_type, runtime: runtime, parent_type: parent_data_type) } + + it { expect(service_response).to eq(nil) } + end + + context 'when parent type is set and invalid' do + let(:parent_data_type) { create(:data_type) } + let(:data_type) { create(:data_type, runtime: runtime, parent_type: parent_data_type) } + + it { expect(service_response.payload).to eq(:runtime_mismatch) } + end + + +end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb new file mode 100644 index 00000000..e1e9cdfa --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb @@ -0,0 +1,50 @@ +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::Validation::DataType::GenericDataTypeIdentifierValidationService do + include_context 'mocked service class instances' + + let(:all_service_expectations) do + # Default case + { + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 1, + } + end + let(:mocked_service_expectations) { all_service_expectations } + let(:default_execute_response) { nil } + + subject(:service_response) { described_class.new(create_authentication(current_user), flow, data_type_identifier).execute } + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } + + let(:flow) { create(:flow, project: namespace_project) } + let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type), runtime: runtime) } + + context 'when data_type.runtime == runtime' do + it { expect(service_response).to eq(nil) } + end + + context 'when data_type.runtime != runtime' do + let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type)) } + + it 'returns an error' do + expect(service_response).to be_error + expect(service_response.payload).to eq(:runtime_mismatch) + end + end + + context 'when data_type_identifier is not a data_type' do + let(:data_type_identifier) { create(:data_type_identifier, generic_key: 'T', runtime: runtime) } + + let(:mocked_service_expectations) do + { + **all_service_expectations, + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, + } + end + + + it { expect(service_response).to eq(nil) } + end +end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb new file mode 100644 index 00000000..d2d45ee2 --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::Validation::DataType::GenericMapperDataTypeIdentifierValidationService do + include_context 'mocked service class instances' + + let(:all_service_expectations) do + # Default case + { + Namespaces::Projects::Flows::Validation::DataType::GenericDataTypeIdentifierValidationService => 1, + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, + Namespaces::Projects::Flows::Validation::NodeFunction::GenericTypeValidationService => 0, + } + end + let(:mocked_service_expectations) { all_service_expectations } + let(:default_execute_response) { nil } + + subject(:service_response) { described_class.new(create_authentication(current_user), flow, parameter, mapper, data_type_identifier).execute } + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } + let(:parameter) { create(:node_parameter, runtime: runtime, + node_function: create(:node_function, + runtime: runtime, + + + )) } + + let(:flow) { create(:flow, project: namespace_project) } + let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type), runtime: runtime) } + let(:generic_mapper) { create(:generic_mapper, source: data_type_identifier, target: 'T') } + +end diff --git a/spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb new file mode 100644 index 00000000..83b83f36 --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb @@ -0,0 +1,35 @@ +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::Validation::FlowSettingValidationService do + + let(:default_payload) { flow } + + subject(:service_response) { described_class.new(create_authentication(current_user), flow, setting).execute } + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } + + let(:flow) { create(:flow, project: namespace_project) } + let(:setting) { create(:flow_setting, flow: flow) } + + context 'when setting.flow == flow' do + it { expect(service_response).to eq(nil) } + end + + + context 'when setting is invalid' do + let(:setting) { build(:flow_setting, flow: flow) } + + before do + expect(setting).to receive(:invalid?).and_return(true) + # debug, payload, test -> 3 times + expect(setting).to receive(:errors).exactly(3).times.and_return(ActiveModel::Errors.new(setting)) + end + + it 'returns an error' do + expect(service_response).to be_error + expect(service_response.payload).to eq(setting.errors) + end + end +end diff --git a/spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb new file mode 100644 index 00000000..1a1444fa --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::Validation::FlowTypeValidationService do + + let(:default_payload) { flow } + + subject(:service_response) { described_class.new(create_authentication(current_user), flow, flow_type).execute } + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } + let(:flow_type) { create(:flow_type, runtime: runtime) } + let(:flow) { create(:flow, flow_type: flow_type, project: namespace_project) } + + context 'when primary runtime is equal to flow type runtime' do + it { expect(service_response).to eq(nil) } + end + + + context 'when primary runtime is not equal to flow type runtime' do + let(:flow_type) { create(:flow_type) } + + it 'returns an error' do + expect(service_response).to be_error + expect(service_response.payload).to eq(:runtime_mismatch) + end + end +end diff --git a/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb new file mode 100644 index 00000000..ddf16437 --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb @@ -0,0 +1,108 @@ +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::Validation::ValidationService do + include_context 'mocked service class instances' + + let(:all_service_expectations) do + # Default case + { + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, + Namespaces::Projects::Flows::Validation::FlowSettingValidationService => 0, + Namespaces::Projects::Flows::Validation::NodeFunction::NodeFunctionValidationService => 1, + Namespaces::Projects::Flows::Validation::FlowTypeValidationService => 1 + } + end + let(:mocked_service_expectations) { all_service_expectations } + + let(:default_payload) { flow } + + subject(:service_response) { described_class.new(create_authentication(current_user), flow).execute } + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } + let(:flow) { create(:flow, project: namespace_project) } + + context 'when primary runtime is set and return and input and settings empty' do + it { is_expected.to be_success } + it { expect(service_response.payload).to eq(flow) } + end + + context 'when input type is set' do + before do + flow.update!(input_type: create(:data_type)) + end + let(:mocked_service_expectations) do + { + **all_service_expectations, + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 1, + } + end + it { is_expected.to be_success } + it { expect(service_response.payload).to eq(flow) } + end + + context 'when return type is set' do + before do + flow.update!(return_type: create(:data_type)) + end + let(:mocked_service_expectations) do + { + **all_service_expectations, + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 1, + } + end + it { is_expected.to be_success } + it { expect(service_response.payload).to eq(flow) } + end + + context 'when return type and input type is set' do + before do + flow.update!(return_type: create(:data_type), input_type: create(:data_type)) + end + let(:mocked_service_expectations) do + { + **all_service_expectations, + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 2, + } + end + it { is_expected.to be_success } + it { expect(service_response.payload).to eq(flow) } + end + + context 'when flow settings are set' do + let(:amount_of_flow_settings) { SecureRandom.random_number(5) + 1 } + before do + flow.flow_settings = Array.new(amount_of_flow_settings) { create(:flow_setting, flow: flow) } + flow.save! + end + let(:mocked_service_expectations) do + { + **all_service_expectations, + Namespaces::Projects::Flows::Validation::FlowSettingValidationService => amount_of_flow_settings, + } + end + it { is_expected.to be_success } + it { expect(service_response.payload).to eq(flow) } + end + + context 'when primary runtime is not set' do + before do + namespace_project.update!(primary_runtime: nil) + end + + let(:mocked_service_expectations) do + { + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, + Namespaces::Projects::Flows::Validation::FlowSettingValidationService => 0, + Namespaces::Projects::Flows::Validation::NodeFunction::NodeFunctionValidationService => 0, + Namespaces::Projects::Flows::Validation::FlowTypeValidationService => 0 + } + end + + it 'returns an error' do + expect(service_response).to be_error + expect(service_response.payload).to eq(:no_primary_runtime) + end + end +end diff --git a/spec/services/namespaces/projects/flows/validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation_service_spec.rb deleted file mode 100644 index 24d83fb8..00000000 --- a/spec/services/namespaces/projects/flows/validation_service_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Namespaces::Projects::Flows::Validation::ValidationService do - subject(:service_response) { described_class.new(create_authentication(current_user), flow).execute } - - let(:runtime) { create(:runtime) } - let(:namespace_project) { create(:namespace_project).tap { |np| np.update(primary_runtime: runtime) } } - let(:starting_node) { create(:node_function, - runtime_function: create(:runtime_function_definition, runtime: runtime) - ) } - let(:flow_type) { create(:flow_type, runtime: runtime) } - let(:flow) { create(:flow, project: namespace_project, flow_type: flow_type, starting_node: starting_node) } - - context 'when validation succeeds' do - let(:current_user) { create(:user) } - - it { is_expected.to be_success } - it { expect(service_response.payload).to eq flow } - it { expect(service_response.message).to eq 'Validation service executed successfully' } - end - - # Add more test cases when validation logic is implemented in ValidationService -end diff --git a/spec/support/validation_helpers.rb b/spec/support/validation_helpers.rb new file mode 100644 index 00000000..9b87ca91 --- /dev/null +++ b/spec/support/validation_helpers.rb @@ -0,0 +1,26 @@ +RSpec.shared_context 'mocked service class instances' do + let(:service_instances) do + mocked_service_expectations.keys.index_with do |klass| + instance_double(klass, execute: default_execute_response) + end + end + + let(:default_execute_response) { ServiceResponse.success(payload: default_payload) } + let(:default_payload) { nil } + + before do + service_instances.each do |klass, instance| + allow(klass).to receive(:new).with(any_args).and_return(instance) + end + end + + after do + expect_service_calls + end + + def expect_service_calls + mocked_service_expectations.each do |klass, expectation| + expect(service_instances[klass]).to have_received(:execute).exactly(expectation).times + end + end +end From 50475880ab20d965e2e585e088d42dd127db62a4 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 30 May 2025 00:16:48 +0200 Subject: [PATCH 37/54] Refactor validation services and input types, enhance logging, and improve code readability --- Gemfile | 3 +- .../namespaces/projects/flows/create.rb | 26 ++-- app/graphql/sagittarius_schema.rb | 8 -- .../input/data_type_identifier_input_type.rb | 5 +- .../types/input/data_type_type_input.rb | 7 +- app/graphql/types/input/flow_input_type.rb | 10 +- .../types/input/flow_setting_input_type.rb | 4 +- .../types/input/generic_mapper_input_type.rb | 8 +- .../types/input/generic_type_input_type.rb | 9 +- .../types/input/node_function_input_type.rb | 4 +- .../types/input/node_parameter_input_type.rb | 4 +- .../input/node_parameter_value_input_type.rb | 14 +- ...ype_rule_contains_key_config_input_type.rb | 6 +- ...pe_rule_contains_type_config_input_type.rb | 5 +- .../input/rules/data_type_rule_input_type.rb | 9 +- app/models/data_type_rule.rb | 47 +++++-- app/models/node_function.rb | 1 - .../projects/flows/create_service.rb | 49 ++++--- .../data_type_rule_validation_service.rb | 2 +- .../data_type/data_type_validation_service.rb | 11 +- ...data_type_identifier_validation_service.rb | 4 +- ...data_type_identifier_validation_service.rb | 6 +- .../flow_setting_validation_service.rb | 1 - .../generic_mapper_validation_service.rb | 4 +- .../generic_type_validation_service.rb | 5 +- ...e_function_parameter_validation_service.rb | 10 +- .../node_function_validation_service.rb | 9 +- .../flows/validation/validation_service.rb | 2 +- .../validators/json_schema_validator.rb | 6 +- spec/models/data_type_rule_spec.rb | 121 ++++++++++-------- spec/models/node_parameter_spec.rb | 6 +- .../data_type_rule_validation_service_spec.rb | 7 +- .../data_type_validation_service_spec.rb | 27 ++-- ...type_identifier_validation_service_spec.rb | 21 +-- ...type_identifier_validation_service_spec.rb | 28 ++-- .../flow_setting_validation_service_spec.rb | 17 ++- .../flow_type_validation_service_spec.rb | 9 +- .../validation/validation_service_spec.rb | 28 ++-- spec/support/validation_helpers.rb | 4 +- 39 files changed, 280 insertions(+), 267 deletions(-) diff --git a/Gemfile b/Gemfile index 9b0707dd..036eb6a5 100644 --- a/Gemfile +++ b/Gemfile @@ -90,5 +90,4 @@ gem 'code0-zero_track', '0.0.4' gem 'image_processing', '>= 1.2' - -gem "json-schema", "~> 5.1" +gem 'json-schema', '~> 5.1' diff --git a/app/graphql/mutations/namespaces/projects/flows/create.rb b/app/graphql/mutations/namespaces/projects/flows/create.rb index 4d0bbaff..df9e2589 100644 --- a/app/graphql/mutations/namespaces/projects/flows/create.rb +++ b/app/graphql/mutations/namespaces/projects/flows/create.rb @@ -9,33 +9,25 @@ class Create < BaseMutation field :flow, Types::FlowType, null: true, description: 'The newly created flow.' - argument :project_id, Types::GlobalIdType[NamespaceProject], required: true, - description: 'The ID of the project to which the flow belongs to' + argument :project_id, Types::GlobalIdType[NamespaceProject], + required: true, description: 'The ID of the project to which the flow belongs to' - argument :flow, Types::Input::FlowInputType + argument :flow, Types::Input::FlowInputType, description: 'The flow to create', required: true def resolve(project_id:, flow:, **params) project = SagittariusSchema.object_from_id(project_id) - if project.nil? - return error('Invalid project id') - end + return error('Invalid project id') if project.nil? input_type = SagittariusSchema.object_from_id(flow.input_type) - if input_type.nil? - return error('Invalid input type id') - end + return error('Invalid input type id') if input_type.nil? return_type = SagittariusSchema.object_from_id(flow.return_type) - if return_type.nil? - return error('Invalid return type id') - end + return error('Invalid return type id') if return_type.nil? flow_type = SagittariusSchema.object_from_id(flow.flow_type) - if flow_type.nil? - return error('Invalid flow type id') - end + return error('Invalid flow type id') if flow_type.nil? Namespaces::Projects::Flows::CreateService.new( create_authentication(context[:current_user]), @@ -47,13 +39,13 @@ def resolve(project_id:, flow:, **params) starting_node: params[:starting_node], settings: params[:settings] || [], } - ).execute.to_mutation_response(success_key: :flow); + ).execute.to_mutation_response(success_key: :flow) end def error(message) { flow: nil, - errors: [create_message_error(message)] + errors: [create_message_error(message)], } end end diff --git a/app/graphql/sagittarius_schema.rb b/app/graphql/sagittarius_schema.rb index 8a47972a..a766e14d 100644 --- a/app/graphql/sagittarius_schema.rb +++ b/app/graphql/sagittarius_schema.rb @@ -52,14 +52,6 @@ def self.object_from_id(global_id, query_ctx = nil) nil end - def self.object_from_id_or_error(global_id) - obj = object_from_id(global_id) - if obj.nil? - - end - obj - end - # rubocop:enable Lint/UnusedMethodArgument end # rubocop:enable GraphQL/MaxDepthSchema diff --git a/app/graphql/types/input/data_type_identifier_input_type.rb b/app/graphql/types/input/data_type_identifier_input_type.rb index e3a9d20f..bd79bf96 100644 --- a/app/graphql/types/input/data_type_identifier_input_type.rb +++ b/app/graphql/types/input/data_type_identifier_input_type.rb @@ -6,12 +6,11 @@ class DataTypeIdentifierInputType < Types::BaseInputObject description 'Input type for data type identifier' argument :data_type_id, Types::GlobalIdType[::DataTypeIdentifier], required: false, - description: 'Data type ID' + description: 'Data type ID' argument :generic_key, String, required: false, description: 'Generic key value' argument :generic_type, Types::Input::GenericTypeInputType, required: false, - description: 'Generic type information' - + description: 'Generic type information' end end end diff --git a/app/graphql/types/input/data_type_type_input.rb b/app/graphql/types/input/data_type_type_input.rb index b2fce072..00ce2aed 100644 --- a/app/graphql/types/input/data_type_type_input.rb +++ b/app/graphql/types/input/data_type_type_input.rb @@ -6,8 +6,8 @@ class DataTypeTypeInput < Types::BaseInputObject description 'Represents a DataType' argument :identifier, String, required: true, description: 'The identifier scoped to the namespace' - argument :namespace_id, Types::GlobalIdType[::Namespace], required: true, - description: 'The namespace where this datatype belongs to' + argument :namespace_id, Types::GlobalIdType[::Namespace], + required: true, description: 'The namespace where this datatype belongs to' argument :variant, Types::DataTypeVariantEnum, required: true, description: 'The type of the datatype' argument :generic_keys, [String], required: false, description: 'The generic keys for the datatype' @@ -15,8 +15,7 @@ class DataTypeTypeInput < Types::BaseInputObject argument :rules, [Rules::DataTypeRuleInputType], required: false, description: 'The rules for the datatype' argument :parent_type_identifier, String, required: false, - description: 'The identifier of the parent data type, if any' - + description: 'The identifier of the parent data type, if any' end end end diff --git a/app/graphql/types/input/flow_input_type.rb b/app/graphql/types/input/flow_input_type.rb index 94a75ca6..c358c719 100644 --- a/app/graphql/types/input/flow_input_type.rb +++ b/app/graphql/types/input/flow_input_type.rb @@ -6,15 +6,15 @@ class FlowInputType < Types::BaseInputObject description 'Input type for creating or updating a flow' argument :input_type, Types::GlobalIdType[::DataType], required: false, - description: 'The ID of the input data type' + description: 'The ID of the input data type' argument :return_type, Types::GlobalIdType[::DataType], required: false, - description: 'The ID of the return data type' + description: 'The ID of the return data type' argument :settings, [Types::Input::FlowSettingInputType], required: false, - description: 'The settings of the flow' + description: 'The settings of the flow' argument :starting_node, Types::Input::NodeFunctionInputType, required: true, - description: 'The starting node of the flow' + description: 'The starting node of the flow' argument :type, Types::GlobalIdType[::FlowType], required: true, - description: 'The identifier of the flow type' + description: 'The identifier of the flow type' end end end diff --git a/app/graphql/types/input/flow_setting_input_type.rb b/app/graphql/types/input/flow_setting_input_type.rb index 76894fab..0c243e40 100644 --- a/app/graphql/types/input/flow_setting_input_type.rb +++ b/app/graphql/types/input/flow_setting_input_type.rb @@ -6,10 +6,10 @@ class FlowSettingInputType < Types::BaseInputObject description 'Input type for flow settings' argument :flow_setting_id, String, required: true, - description: 'The identifier (not database id) of the flow setting' + description: 'The identifier (not database id) of the flow setting' argument :object, GraphQL::Types::JSON, required: true, - description: 'The value of the flow setting' + description: 'The value of the flow setting' end end end diff --git a/app/graphql/types/input/generic_mapper_input_type.rb b/app/graphql/types/input/generic_mapper_input_type.rb index 6b7a8bdd..6d5ed6cf 100644 --- a/app/graphql/types/input/generic_mapper_input_type.rb +++ b/app/graphql/types/input/generic_mapper_input_type.rb @@ -5,11 +5,11 @@ module Input class GenericMapperInputType < Types::BaseInputObject description 'Input type for generic mappers' - argument :source, Types::Input::DataTypeIdentifierInputType, required: true, - description: 'The source data type identifier for the mapper' + argument :source, Types::Input::DataTypeIdentifierInputType, + required: true, description: 'The source data type identifier for the mapper' - argument :target, String, required: true, - description: 'The target data type identifier for the mapper' + argument :target, String, + required: true, description: 'The target data type identifier for the mapper' end end end diff --git a/app/graphql/types/input/generic_type_input_type.rb b/app/graphql/types/input/generic_type_input_type.rb index 95d9d4d8..c58d8255 100644 --- a/app/graphql/types/input/generic_type_input_type.rb +++ b/app/graphql/types/input/generic_type_input_type.rb @@ -5,11 +5,10 @@ module Input class GenericTypeInputType < Types::BaseInputObject description 'Input type for generic type operations.' - argument :data_type_id, Types::GlobalIdType[::DataType], required: true, description: 'The data type associated with this generic type.' - argument :generic_mappers, [Types::Input::GenericMapperInputType], required: true, - description: 'The mappers associated with this generic type.' - - + argument :data_type_id, Types::GlobalIdType[::DataType], + required: true, description: 'The data type associated with this generic type.' + argument :generic_mappers, [Types::Input::GenericMapperInputType], + required: true, description: 'The mappers associated with this generic type.' end end end diff --git a/app/graphql/types/input/node_function_input_type.rb b/app/graphql/types/input/node_function_input_type.rb index c8e1fd8e..1c9c51df 100644 --- a/app/graphql/types/input/node_function_input_type.rb +++ b/app/graphql/types/input/node_function_input_type.rb @@ -9,9 +9,9 @@ class NodeFunctionInputType < Types::BaseInputObject required: true, description: 'The identifier of the Runtime Function Definition' argument :next_node, Types::Input::NodeFunctionInputType, required: false, - description: 'The next Node Function in the flow' + description: 'The next Node Function in the flow' argument :parameters, [Types::Input::NodeParameterInputType], required: true, - description: 'The parameters of the Node Function' + description: 'The parameters of the Node Function' end end end diff --git a/app/graphql/types/input/node_parameter_input_type.rb b/app/graphql/types/input/node_parameter_input_type.rb index d6001c40..16d5f3a3 100644 --- a/app/graphql/types/input/node_parameter_input_type.rb +++ b/app/graphql/types/input/node_parameter_input_type.rb @@ -6,10 +6,10 @@ class NodeParameterInputType < Types::BaseInputObject description 'Input type for Node parameter' argument :runtime_parameter_definition_id, Types::GlobalIdType[::RuntimeParameterDefinition], - required: true, description: 'The identifier of the Runtime Parameter Definition' + required: true, description: 'The identifier of the Runtime Parameter Definition' argument :value, Types::Input::NodeParameterValueInputType, required: false, - description: 'The value of the parameter' + description: 'The value of the parameter' end end end diff --git a/app/graphql/types/input/node_parameter_value_input_type.rb b/app/graphql/types/input/node_parameter_value_input_type.rb index 4cecf61a..cfd486b2 100644 --- a/app/graphql/types/input/node_parameter_value_input_type.rb +++ b/app/graphql/types/input/node_parameter_value_input_type.rb @@ -5,16 +5,14 @@ module Input class NodeParameterValueInputType < Types::BaseInputObject description 'Input type for parameter value' - argument :function_value, Types::Input::NodeFunctionInputType, required: false, - description: 'The function value of the parameter' - argument :literal_value, GraphQL::Types::JSON, required: false, - description: 'The literal value of the parameter' - argument :reference_value, Types::Input::ReferenceValueInputType, required: false, - description: 'The reference value of the parameter' + argument :function_value, Types::Input::NodeFunctionInputType, + required: false, description: 'The function value of the parameter' + argument :literal_value, GraphQL::Types::JSON, + required: false, description: 'The literal value of the parameter' + argument :reference_value, Types::Input::ReferenceValueInputType, + required: false, description: 'The reference value of the parameter' require_one_of %i[function_value literal_value reference_value] - - end end end diff --git a/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb b/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb index dbf92408..091e1c74 100644 --- a/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb +++ b/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb @@ -6,10 +6,10 @@ module Rules class DataTypeRuleContainsKeyConfigInputType < Types::BaseInputObject description 'Input type for Data Type Rule Contains A Key configuration' - argument :key, String, required: true, description: 'The key to check for in the data type rule' - argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, required: false, - description: 'The identifier of the data type this rule applies to' + argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, + required: false, description: 'The identifier of the data type this rule applies to' + argument :key, String, required: true, description: 'The key to check for in the data type rule' end end end diff --git a/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb b/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb index 8dc65113..138fa70e 100644 --- a/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb +++ b/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb @@ -6,9 +6,8 @@ module Rules class DataTypeRuleContainsTypeConfigInputType < Types::BaseInputObject description 'Input type for Data Type Rule Contains Type configuration' - argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, required: false, - description: 'The identifier of the data type this rule applies to' - + argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, + required: false, description: 'The identifier of the data type this rule applies to' end end end diff --git a/app/graphql/types/input/rules/data_type_rule_input_type.rb b/app/graphql/types/input/rules/data_type_rule_input_type.rb index c104ac23..0425c6e0 100644 --- a/app/graphql/types/input/rules/data_type_rule_input_type.rb +++ b/app/graphql/types/input/rules/data_type_rule_input_type.rb @@ -6,12 +6,11 @@ module Rules class DataTypeRuleInputType < Types::BaseInputObject description 'Input type for Data Type Rule' - argument :contains_key, DataTypeRuleContainsKeyConfigInputType, required: false, - description: 'Configuration for contains key rule' - - argument :contains_value, DataTypeRuleContainsTypeConfigInputType, required: false, - description: 'Configuration for contains type rule' + argument :contains_key, DataTypeRuleContainsKeyConfigInputType, + required: false, description: 'Configuration for contains key rule' + argument :contains_value, DataTypeRuleContainsTypeConfigInputType, + required: false, description: 'Configuration for contains type rule' end end end diff --git a/app/models/data_type_rule.rb b/app/models/data_type_rule.rb index 49283133..d601b0a4 100644 --- a/app/models/data_type_rule.rb +++ b/app/models/data_type_rule.rb @@ -14,18 +14,37 @@ class DataTypeRule < ApplicationRecord belongs_to :data_type, inverse_of: :rules validates :variant, presence: true, - inclusion: { - in: VARIANTS.keys.map(&:to_s), - } - - validates :config, if: :variant_contains_key?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeContainsKeyRuleConfig', hash_conversion: true } - - validates :config, if: :variant_contains_type?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeContainsTypeRuleConfig', hash_conversion: true } - - validates :config, if: :variant_item_of_collection?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeItemOfCollectionRuleConfig', hash_conversion: true } - - validates :config, if: :variant_number_range?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeNumberRangeRuleConfig', hash_conversion: true } - - validates :config, if: :variant_regex?, 'sagittarius/validators/json_schema': { filename: 'data_types/DataTypeRegexRuleConfig', hash_conversion: true } - + inclusion: { + in: VARIANTS.keys.map(&:to_s), + } + + validates :config, if: :variant_contains_key?, + 'sagittarius/validators/json_schema': { + filename: 'data_types/DataTypeContainsKeyRuleConfig', + hash_conversion: true, + } + + validates :config, if: :variant_contains_type?, + 'sagittarius/validators/json_schema': { + filename: 'data_types/DataTypeContainsTypeRuleConfig', + hash_conversion: true, + } + + validates :config, if: :variant_item_of_collection?, + 'sagittarius/validators/json_schema': { + filename: 'data_types/DataTypeItemOfCollectionRuleConfig', + hash_conversion: true, + } + + validates :config, if: :variant_number_range?, + 'sagittarius/validators/json_schema': { + filename: 'data_types/DataTypeNumberRangeRuleConfig', + hash_conversion: true, + } + + validates :config, if: :variant_regex?, + 'sagittarius/validators/json_schema': { + filename: 'data_types/DataTypeRegexRuleConfig', + hash_conversion: true, + } end diff --git a/app/models/node_function.rb b/app/models/node_function.rb index 6d81530c..4ec99d80 100644 --- a/app/models/node_function.rb +++ b/app/models/node_function.rb @@ -7,7 +7,6 @@ class NodeFunction < ApplicationRecord has_many :node_parameter_values, class_name: 'NodeParameter', inverse_of: :function_value has_many :node_parameters, class_name: 'NodeParameter', inverse_of: :node_function - validate :validate_recursion, if: :next_node_changed? def validate_recursion diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb index f4751e18..165ca4ef 100644 --- a/app/services/namespaces/projects/flows/create_service.rb +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -22,14 +22,15 @@ def execute transactional do |t| settings = [] params[:settings].each do |graphql_setting| - setting = FlowSetting.new(flow_setting_id: graphql_setting.flow_setting_id, object: graphql_setting.object) - unless setting.valid? - t.rollback_and_return! ServiceResponse.error( - message: 'Invalid flow setting', - payload: setting.errors - ) - settings << setting - end + setting = FlowSetting.new(flow_setting_id: graphql_setting.flow_setting_id, + object: graphql_setting.object) + next if setting.valid? + + t.rollback_and_return! ServiceResponse.error( + message: 'Invalid flow setting', + payload: setting.errors + ) + settings << setting end params[:settings] = settings @@ -88,33 +89,29 @@ def create_node_function(node_function, t) if parameter.literal_value.present? params << NodeParameter.create( runtime_parameter: runtime_parameter, - literal_value: parameter.literal_value, + literal_value: parameter.literal_value ) next end if parameter.function_value.present? params << NodeParameter.create( runtime_parameter: runtime_parameter, - function_value: create_node_function(parameter.function_value, t), + function_value: create_node_function(parameter.function_value, t) ) next end - if parameter.reference_value.present? - identifier = parameter.reference_value.data_type_identifier + next if parameter.reference_value.blank? - ReferenceValue.create( - reference_value_id: parameter.reference_value.reference_value_id, - data_type_identifier: get_data_type_identifier(identifier), - ) - end + identifier = parameter.reference_value.data_type_identifier + ReferenceValue.create( + reference_value_id: parameter.reference_value.reference_value_id, + data_type_identifier: get_data_type_identifier(identifier) + ) end next_node = nil - if node_function.next_node.present? - next_node = create_node_function(node_function.next_node, t) - end - + next_node = create_node_function(node_function.next_node, t) if node_function.next_node.present? NodeFunction.create( next_node: next_node, @@ -126,9 +123,7 @@ def create_node_function(node_function, t) private def get_data_type_identifier(identifier) - if identifier.generic_key.present? - return DataTypeIdentifier.create(generic_key: identifier.generic_key) - end + return DataTypeIdentifier.create(generic_key: identifier.generic_key) if identifier.generic_key.present? if identifier.generic_type.present? data_type = SagittariusSchema.object_from_id(identifier.generic_type.data_type_id) @@ -142,9 +137,9 @@ def get_data_type_identifier(identifier) return DataTypeIdentifier.create(generic_type: GenericType.create(data_type: data_type, mappers: mappers)) end - if identifier.data_type_id.present? - return DataTypeIdentifier.create(data_type: SagittariusSchema.object_from_id(identifier.data_type_id)) - end + return if identifier.data_type_id.blank? + + DataTypeIdentifier.create(data_type: SagittariusSchema.object_from_id(identifier.data_type_id)) end end end diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb index 8d209321..886c80e1 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb @@ -23,7 +23,7 @@ def execute transactional do |t| if rule.invalid? - logger.debug(message: "Data type rule validation (model) failed", + logger.debug(message: 'Data type rule validation (model) failed', flow: flow.id, data_type: data_type.id, rule: rule.id, diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb index e603eb68..f384657c 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb @@ -22,14 +22,14 @@ def execute transactional do |t| if data_type.invalid? - logger.debug(message: "Data type validation failed", + logger.debug(message: 'Data type validation failed', flow: flow.id, data_type: data_type.id, errors: data_type.errors.full_messages) t.rollback_and_return!( ServiceResponse.error( message: 'Data type is invalid', - payload: data_type.errors, + payload: data_type.errors ) ) end @@ -37,12 +37,11 @@ def execute primary_runtime = flow.project.primary_runtime if primary_runtime != data_type.runtime - logger.debug(message: "Data type runtime mismatch", + logger.debug(message: 'Data type runtime mismatch', primary_runtime: primary_runtime.id, given_runtime: data_type.runtime.id, flow: flow.id, - data_type: data_type.id - ) + data_type: data_type.id) t.rollback_and_return!( ServiceResponse.error( message: 'Data type runtime does not match the primary runtime of the project', @@ -70,7 +69,7 @@ def execute ).execute end - logger.debug(message: "Data type is valid", flow: flow.id, data_type: data_type.id) + logger.debug(message: 'Data type is valid', flow: flow.id, data_type: data_type.id) nil end end diff --git a/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb index ae4dd839..832d93ac 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb @@ -22,7 +22,7 @@ def execute transactional do |t| if data_type_identifier.invalid? - logger.debug(message: "Data type identifier validation failed", + logger.debug(message: 'Data type identifier validation failed', flow: flow.id, data_type_identifier: data_type_identifier.id, errors: data_type_identifier.errors.full_messages) @@ -41,7 +41,7 @@ def execute ).execute end if data_type_identifier.runtime != flow.project.primary_runtime - logger.debug(message: "Data type identifier runtime mismatch", + logger.debug(message: 'Data type identifier runtime mismatch', primary_runtime: flow.project.primary_runtime.id, given_runtime: data_type_identifier.runtime.id, flow: flow.id, diff --git a/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb index 69d8046a..a6914cdd 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb @@ -30,10 +30,12 @@ def execute ).execute if data_type_identifier.generic_key.present? - unless parameter.function_value.runtime_function_definition.generic_keys.has?(data_type_identifier.generic_key) + unless parameter.function_value.runtime_function_definition + .generic_keys.has?(data_type_identifier.generic_key) t.rollback_and_return!( ServiceResponse.error( - message: "Generic type #{parameter.generic_type.data_type.id} does not have a generic key for source #{source.generic_key}", + message: "Generic type #{parameter.generic_type.data_type.id} " \ + "does not have a generic key for source #{source.generic_key}", payload: :generic_key_not_found ) ) diff --git a/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb b/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb index 939d0f14..c46f5c8a 100644 --- a/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb @@ -30,7 +30,6 @@ def execute end # Maybe something in the future we will validate the setting object but currently its not typed - end end end diff --git a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb index 413767a0..c6c17847 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb @@ -28,7 +28,8 @@ def execute unless parameter.generic_type.data_type.generic_keys.has?(target) t.rollback_and_return!( ServiceResponse.error( - message: "Generic type #{parameter.generic_type.data_type.id} does not have a generic key for target #{target}", + message: "Generic type #{parameter.generic_type.data_type.id} " \ + "does not have a generic key for target #{target}", payload: :generic_key_not_found ) ) @@ -41,7 +42,6 @@ def execute generic_mapper, generic_mapper.source ).execute - end ServiceResponse.success(message: 'Node function generic mapper validation passed') diff --git a/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb index 77ef9ced..d835cb77 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb @@ -19,7 +19,7 @@ def initialize(current_authentication, flow, node_function, generic_type) end def execute - transactional do |t| + transactional do |_t| ::DataType::DataTypeValidationService.new( current_authentication, flow, @@ -27,7 +27,8 @@ def execute ).execute identifier.data_type.generic_mappers.each do |generic_mapper| - logger.debug("Validating generic mapper: #{generic_mapper.id} for data type identifier: #{identifier.id}") + logger.debug("Validating generic mapper: #{generic_mapper.id}" \ + "for data type identifier: #{identifier.id}") ::DataType::GenericMapperValidationService.new( current_authentication, flow, diff --git a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb index 7a36da94..87b50c8d 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb @@ -23,7 +23,7 @@ def execute transactional do |t| if parameter.invalid? - logger.debug(message: "Node parameter validation failed", + logger.debug(message: 'Node parameter validation failed', errors: parameter.errors.full_messages) t.rollback_and_return!( ServiceResponse.error( @@ -32,9 +32,8 @@ def execute ) ) end - if parameter.literal_value.present? - return - end + return if parameter.literal_value.present? + if parameter.reference_value.present? ReferenceValueValidationService.new( current_authentication, @@ -44,7 +43,8 @@ def execute return end if parameter.function_value.present? - logger.debug("Validating function value: #{parameter.function_value.id} for node parameter: #{parameter.id}") + logger.debug("Validating function value: + #{parameter.function_value.id} for node parameter: #{parameter.id}") NodeFunctionValidationService.new( current_authentication, flow, diff --git a/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb index ab9ee48c..7ff5c3a6 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb @@ -22,7 +22,7 @@ def execute transactional do |t| if node_function.invalid? - logger.debug(message: "Node function validation failed", + logger.debug(message: 'Node function validation failed', errors: node_function.errors.full_messages) t.rollback_and_return!( ServiceResponse.error( @@ -42,9 +42,10 @@ def execute end node_function.runtime_function.tap do |runtime_function| - logger.debug("Validating runtime function: #{runtime_function.id} for node function: #{node_function.id}") + logger + .debug("Validating runtime function: #{runtime_function.id} for node function: #{node_function.id}") if runtime_function.runtime != flow.project.primary_runtime - logger.debug(message: "Runtime function runtime mismatch", + logger.debug(message: 'Runtime function runtime mismatch', primary_runtime: flow.project.primary_runtime.id, given_runtime: runtime_function.runtime.id, flow: flow.id, @@ -63,7 +64,7 @@ def execute logger.debug("Validating node parameter: #{parameter.id} for function: #{node_function.id}") if parameter.runtime_parameter != node_function.runtime_function - logger.debug(message: "Node parameter does not match its function", + logger.debug(message: 'Node parameter does not match its function', node_function: node_function.id, runtime_parameter: parameter.runtime_parameter.id, flow: flow.id) diff --git a/app/services/namespaces/projects/flows/validation/validation_service.rb b/app/services/namespaces/projects/flows/validation/validation_service.rb index 270684cb..e800d754 100644 --- a/app/services/namespaces/projects/flows/validation/validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/validation_service.rb @@ -15,7 +15,7 @@ def initialize(current_authentication, flow) end def execute - transactional do |t| + transactional do |_t| primary_runtime = flow.project.primary_runtime if primary_runtime.nil? return ServiceResponse.error( diff --git a/lib/sagittarius/validators/json_schema_validator.rb b/lib/sagittarius/validators/json_schema_validator.rb index e8885f3b..1fdac2af 100644 --- a/lib/sagittarius/validators/json_schema_validator.rb +++ b/lib/sagittarius/validators/json_schema_validator.rb @@ -17,7 +17,7 @@ def initialize(options) @base_directory = options.delete(:base_directory) || BASE_DIRECTORY - super(options) + super end def validate_each(record, attribute, value) @@ -25,7 +25,7 @@ def validate_each(record, attribute, value) value = JSON.parse(value.to_s) if options[:parse_json] == true && !value.nil? if options[:detail_errors] - JSON::Validator.validate(schema,value).each do |error| + JSON::Validator.validate(schema, value).each do |error| message = format_error_message(error) record.errors.add(attribute, message) end @@ -56,7 +56,7 @@ def format_one_of_error(error) end def valid_schema?(value) - JSON::Validator.validate(schema_path, value, :validate_schema => true) + JSON::Validator.validate(schema_path, value, validate_schema: true) end def schema_path diff --git a/spec/models/data_type_rule_spec.rb b/spec/models/data_type_rule_spec.rb index 763d182e..bca5a99a 100644 --- a/spec/models/data_type_rule_spec.rb +++ b/spec/models/data_type_rule_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe DataTypeRule do - subject { create(:data_type_rule) } + subject(:rule) { create(:data_type_rule) } describe 'associations' do it { is_expected.to belong_to(:data_type).inverse_of(:rules) } @@ -13,109 +13,118 @@ it { is_expected.to allow_values(*described_class::VARIANTS.keys).for(:variant) } context 'when variant is contains_key' do - before { subject.variant = :contains_key } + before { rule.variant = :contains_key } - context 'validates config with DataTypeContainsKeyRuleConfig schema' do + context 'when validating config with DataTypeContainsKeyRuleConfig schema' do it 'is correct' do - subject.config = { - key: "id", + rule.config = { + key: 'id', data_type_identifier: { - data_type_identifier: "User" - } + data_type_identifier: 'User', + }, } - expect(subject).to be_valid + is_expected.to be_valid end - it 'is incorrect' do - subject.config = { + + it 'when its incorrect' do + rule.config = { data_type_identifier: { - data_type_identifier: "User" - } + data_type_identifier: 'User', + }, } - expect(subject).not_to be_valid + is_expected.not_to be_valid end end end + context 'when variant is contains_type' do - before { subject.variant = :contains_type } + before { rule.variant = :contains_type } - context 'is correct' do - it 'validates config with DataTypeContainsTypeRuleConfig schema' do - subject.config = { + context 'when its correct' do + it 'when validating config with DataTypeContainsTypeRuleConfig schema' do + rule.config = { data_type_identifier: { - data_type_identifier: "User" - } + data_type_identifier: 'User', + }, } - expect(subject).to be_valid + is_expected.to be_valid end end - context 'is incorrect' do - it 'validates config with DataTypeContainsTypeRuleConfig schema' do - subject.config = { - key: "id" + + context 'when its incorrect' do + it 'when validating config with DataTypeContainsTypeRuleConfig schema' do + rule.config = { + key: 'id', } - expect(subject).not_to be_valid + is_expected.not_to be_valid end end end + context 'when variant is item_of_collection' do - before { subject.variant = :item_of_collection } + before { rule.variant = :item_of_collection } - context 'validates config with DataTypeItemOfCollectionRuleConfig schema' do + context 'when validating config with DataTypeItemOfCollectionRuleConfig schema' do it 'is correct' do - subject.config = { - "items": [ - ["a", 1, true, {"key": "value"}], - {"test": 2}, + rule.config = { + items: [ + ['a', 1, true, { key: 'value' }], + { test: 2 }, [] - ] + ], } - expect(subject).to be_valid + is_expected.to be_valid end - it 'is incorrect' do - subject.config = { - key: "id" + + it 'when its incorrect' do + rule.config = { + key: 'id', } - expect(subject).not_to be_valid + is_expected.not_to be_valid end end end + context 'when variant is number_range' do - before { subject.variant = :number_range } + before { rule.variant = :number_range } - context 'validates config with DataTypeNumberRangeRuleConfig schema' do + context 'when validating config with DataTypeNumberRangeRuleConfig schema' do it 'is correct' do - subject.config = { + rule.config = { from: 1, to: 10, - steps: 1 + steps: 1, } - expect(subject).to be_valid + is_expected.to be_valid end - it 'is incorrect' do - subject.config = { - from: "one", + + it 'when its incorrect' do + rule.config = { + from: 'one', to: 10, - steps: 1 + steps: 1, } - expect(subject).not_to be_valid + is_expected.not_to be_valid end end end + context 'when variant is regex' do - before { subject.variant = :regex } + before { rule.variant = :regex } - context 'validates config with DataTypeRegexRuleConfig schema' do + context 'when validating config with DataTypeRegexRuleConfig schema' do it 'is correct' do - subject.config = { - pattern: '.*' + rule.config = { + pattern: '.*', } - expect(subject).to be_valid + is_expected.to be_valid end - it 'is incorrect' do - subject.config = { - pattern: 1234 + + it 'when its incorrect' do + rule.config = { + pattern: 1234, } - expect(subject).not_to be_valid + is_expected.not_to be_valid end end end diff --git a/spec/models/node_parameter_spec.rb b/spec/models/node_parameter_spec.rb index 5da2e292..bc0c2593 100644 --- a/spec/models/node_parameter_spec.rb +++ b/spec/models/node_parameter_spec.rb @@ -12,7 +12,11 @@ describe 'associations' do it { is_expected.to belong_to(:runtime_parameter).class_name('RuntimeParameterDefinition') } it { is_expected.to belong_to(:reference_value).optional } - it { is_expected.to belong_to(:function_value).class_name('NodeFunction').inverse_of(:node_parameter_values).optional } + + it { + is_expected.to belong_to(:function_value).class_name('NodeFunction').inverse_of(:node_parameter_values).optional + } + it { is_expected.to belong_to(:node_function).class_name('NodeFunction').inverse_of(:node_parameters) } end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb index 4dbfa152..27732cb7 100644 --- a/spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb @@ -1,7 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Namespaces::Projects::Flows::Validation::DataType::DataTypeRuleValidationService do - subject(:service_response) { described_class.new(create_authentication(current_user), flow, data_type, rule).execute } let(:current_user) { create(:user) } @@ -12,7 +13,7 @@ let(:rule) { create(:data_type_rule, data_type: data_type, variant: :regex, config: { pattern: '.*' }) } context 'when rule is valid' do - it { expect(service_response).to eq(nil) } + it { expect(service_response).to be_nil } end context 'when rule is invalid' do @@ -20,7 +21,7 @@ it 'returns an error message' do expect(service_response).to be_error - expect(rule.errors.full_messages).to include("Config is not a valid JSON schema") + expect(rule.errors.full_messages).to include('Config is not a valid JSON schema') end end end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb index 891c2848..a34ecf04 100644 --- a/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb @@ -1,7 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService do - include_context 'mocked service class instances' + subject(:service_response) { described_class.new(create_authentication(current_user), flow, data_type).execute } + + include_context 'with mocked services' let(:all_service_expectations) do # Default case @@ -9,28 +13,23 @@ Namespaces::Projects::Flows::Validation::DataType::DataTypeRuleValidationService => 0, } end - - let(:default_execute_response) { ServiceResponse.success(payload: default_payload) } - - let(:mocked_service_expectations) { all_service_expectations } - - subject(:service_response) { described_class.new(create_authentication(current_user), flow, data_type).execute } - let(:current_user) { create(:user) } let(:runtime) { create(:runtime) } let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } - let(:flow) { create(:flow, project: namespace_project) } let(:data_type) { create(:data_type, runtime: runtime) } + let(:default_execute_response) { ServiceResponse.success(payload: default_payload) } + + let(:mocked_service_expectations) { all_service_expectations } + context 'when data_type.runtime == runtime' do - it { expect(service_response).to eq(nil) } + it { expect(service_response).to be_nil } end context 'when data_type.runtime != runtime' do let(:data_type) { create(:data_type) } - it 'returns an error' do expect(service_response).to be_error expect(service_response.payload).to eq(:runtime_mismatch) @@ -47,14 +46,14 @@ } end - it { expect(service_response).to eq(nil) } + it { expect(service_response).to be_nil } end context 'when parent type is set' do let(:parent_data_type) { create(:data_type, runtime: runtime) } let(:data_type) { create(:data_type, runtime: runtime, parent_type: parent_data_type) } - it { expect(service_response).to eq(nil) } + it { expect(service_response).to be_nil } end context 'when parent type is set and invalid' do @@ -63,6 +62,4 @@ it { expect(service_response.payload).to eq(:runtime_mismatch) } end - - end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb index e1e9cdfa..5c4e8056 100644 --- a/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb @@ -1,7 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Namespaces::Projects::Flows::Validation::DataType::GenericDataTypeIdentifierValidationService do - include_context 'mocked service class instances' + subject(:service_response) do + described_class.new(create_authentication(current_user), flow, data_type_identifier).execute + end + + include_context 'with mocked services' let(:all_service_expectations) do # Default case @@ -9,20 +15,16 @@ Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 1, } end - let(:mocked_service_expectations) { all_service_expectations } - let(:default_execute_response) { nil } - - subject(:service_response) { described_class.new(create_authentication(current_user), flow, data_type_identifier).execute } - let(:current_user) { create(:user) } let(:runtime) { create(:runtime) } let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } - let(:flow) { create(:flow, project: namespace_project) } let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type), runtime: runtime) } + let(:mocked_service_expectations) { all_service_expectations } + let(:default_execute_response) { nil } context 'when data_type.runtime == runtime' do - it { expect(service_response).to eq(nil) } + it { expect(service_response).to be_nil } end context 'when data_type.runtime != runtime' do @@ -44,7 +46,6 @@ } end - - it { expect(service_response).to eq(nil) } + it { expect(service_response).to be_nil } end end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb index d2d45ee2..08453d87 100644 --- a/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb @@ -1,7 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Namespaces::Projects::Flows::Validation::DataType::GenericMapperDataTypeIdentifierValidationService do - include_context 'mocked service class instances' + subject(:service_response) do + described_class.new(create_authentication(current_user), flow, parameter, mapper, data_type_identifier).execute + end + + include_context 'with mocked services' let(:all_service_expectations) do # Default case @@ -11,23 +17,17 @@ Namespaces::Projects::Flows::Validation::NodeFunction::GenericTypeValidationService => 0, } end - let(:mocked_service_expectations) { all_service_expectations } - let(:default_execute_response) { nil } - - subject(:service_response) { described_class.new(create_authentication(current_user), flow, parameter, mapper, data_type_identifier).execute } - let(:current_user) { create(:user) } let(:runtime) { create(:runtime) } let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } - let(:parameter) { create(:node_parameter, runtime: runtime, - node_function: create(:node_function, - runtime: runtime, - - - )) } - + let(:parameter) do + create(:node_parameter, runtime: runtime, + node_function: create(:node_function, + runtime: runtime)) + end let(:flow) { create(:flow, project: namespace_project) } let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type), runtime: runtime) } let(:generic_mapper) { create(:generic_mapper, source: data_type_identifier, target: 'T') } - + let(:mocked_service_expectations) { all_service_expectations } + let(:default_execute_response) { nil } end diff --git a/spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb index 83b83f36..341920eb 100644 --- a/spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb @@ -1,35 +1,34 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Namespaces::Projects::Flows::Validation::FlowSettingValidationService do - - let(:default_payload) { flow } - subject(:service_response) { described_class.new(create_authentication(current_user), flow, setting).execute } + let(:default_payload) { flow } let(:current_user) { create(:user) } let(:runtime) { create(:runtime) } let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } - let(:flow) { create(:flow, project: namespace_project) } let(:setting) { create(:flow_setting, flow: flow) } context 'when setting.flow == flow' do - it { expect(service_response).to eq(nil) } + it { expect(service_response).to be_nil } end - context 'when setting is invalid' do let(:setting) { build(:flow_setting, flow: flow) } before do - expect(setting).to receive(:invalid?).and_return(true) - # debug, payload, test -> 3 times - expect(setting).to receive(:errors).exactly(3).times.and_return(ActiveModel::Errors.new(setting)) + allow(setting).to receive_messages(invalid?: true, errors: ActiveModel::Errors.new(setting)) end it 'returns an error' do expect(service_response).to be_error expect(service_response.payload).to eq(setting.errors) + expect(setting).to have_received(:invalid?) + # debug, payload, test -> 3 times + expect(setting).to have_received(:errors).exactly(3).times end end end diff --git a/spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb index 1a1444fa..408dd007 100644 --- a/spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb @@ -1,11 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Namespaces::Projects::Flows::Validation::FlowTypeValidationService do - - let(:default_payload) { flow } - subject(:service_response) { described_class.new(create_authentication(current_user), flow, flow_type).execute } + let(:default_payload) { flow } let(:current_user) { create(:user) } let(:runtime) { create(:runtime) } let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } @@ -13,10 +13,9 @@ let(:flow) { create(:flow, flow_type: flow_type, project: namespace_project) } context 'when primary runtime is equal to flow type runtime' do - it { expect(service_response).to eq(nil) } + it { expect(service_response).to be_nil } end - context 'when primary runtime is not equal to flow type runtime' do let(:flow_type) { create(:flow_type) } diff --git a/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb index ddf16437..5d33b89d 100644 --- a/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb @@ -1,7 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Namespaces::Projects::Flows::Validation::ValidationService do - include_context 'mocked service class instances' + subject(:service_response) { described_class.new(create_authentication(current_user), flow).execute } + + include_context 'with mocked services' let(:all_service_expectations) do # Default case @@ -9,15 +13,13 @@ Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, Namespaces::Projects::Flows::Validation::FlowSettingValidationService => 0, Namespaces::Projects::Flows::Validation::NodeFunction::NodeFunctionValidationService => 1, - Namespaces::Projects::Flows::Validation::FlowTypeValidationService => 1 + Namespaces::Projects::Flows::Validation::FlowTypeValidationService => 1, } end let(:mocked_service_expectations) { all_service_expectations } let(:default_payload) { flow } - subject(:service_response) { described_class.new(create_authentication(current_user), flow).execute } - let(:current_user) { create(:user) } let(:runtime) { create(:runtime) } let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } @@ -32,12 +34,14 @@ before do flow.update!(input_type: create(:data_type)) end + let(:mocked_service_expectations) do { **all_service_expectations, Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 1, } end + it { is_expected.to be_success } it { expect(service_response.payload).to eq(flow) } end @@ -46,12 +50,14 @@ before do flow.update!(return_type: create(:data_type)) end + let(:mocked_service_expectations) do { **all_service_expectations, Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 1, } end + it { is_expected.to be_success } it { expect(service_response.payload).to eq(flow) } end @@ -60,28 +66,32 @@ before do flow.update!(return_type: create(:data_type), input_type: create(:data_type)) end + let(:mocked_service_expectations) do { **all_service_expectations, Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 2, } end + it { is_expected.to be_success } it { expect(service_response.payload).to eq(flow) } end context 'when flow settings are set' do let(:amount_of_flow_settings) { SecureRandom.random_number(5) + 1 } - before do - flow.flow_settings = Array.new(amount_of_flow_settings) { create(:flow_setting, flow: flow) } - flow.save! - end let(:mocked_service_expectations) do { **all_service_expectations, Namespaces::Projects::Flows::Validation::FlowSettingValidationService => amount_of_flow_settings, } end + + before do + flow.flow_settings = Array.new(amount_of_flow_settings) { create(:flow_setting, flow: flow) } + flow.save! + end + it { is_expected.to be_success } it { expect(service_response.payload).to eq(flow) } end @@ -96,7 +106,7 @@ Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, Namespaces::Projects::Flows::Validation::FlowSettingValidationService => 0, Namespaces::Projects::Flows::Validation::NodeFunction::NodeFunctionValidationService => 0, - Namespaces::Projects::Flows::Validation::FlowTypeValidationService => 0 + Namespaces::Projects::Flows::Validation::FlowTypeValidationService => 0, } end diff --git a/spec/support/validation_helpers.rb b/spec/support/validation_helpers.rb index 9b87ca91..cae0d16e 100644 --- a/spec/support/validation_helpers.rb +++ b/spec/support/validation_helpers.rb @@ -1,4 +1,6 @@ -RSpec.shared_context 'mocked service class instances' do +# frozen_string_literal: true + +RSpec.shared_context 'with mocked services' do let(:service_instances) do mocked_service_expectations.keys.index_with do |klass| instance_double(klass, execute: default_execute_response) From dc7aa4de0ba5acc0a205533dfbe8491386b12af7 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 30 May 2025 14:56:56 +0200 Subject: [PATCH 38/54] Refactor flow creation and validation services, enhance error handling, and update input types, add more specs --- .../namespaces/projects/flows/delete.rb | 32 ++++ .../input/data_type_identifier_input_type.rb | 4 +- .../types/input/data_type_type_input.rb | 21 --- ...ype_rule_contains_key_config_input_type.rb | 16 -- ...pe_rule_contains_type_config_input_type.rb | 14 -- .../input/rules/data_type_rule_input_type.rb | 17 -- app/grpc/concerns/grpc_stream_handler.rb | 2 +- .../projects/flows/create_service.rb | 30 ++-- .../projects/flows/update_service.rb | 60 ------- ...ata_type_identifier_validation_service.rb} | 43 +++-- ...data_type_identifier_validation_service.rb | 67 -------- .../generic_mapper_validation_service.rb | 9 +- .../generic_type_validation_service.rb | 4 +- ...e_function_parameter_validation_service.rb | 1 + .../reference_value_validation_service.rb | 96 ++++++++--- .../input_object/datatypeidentifierinput.md | 2 +- .../mutation/namespacesprojectsflowscreate.md | 2 +- docs/graphql/scalar/datatypeidentifierid.md | 5 - spec/factories/node_functions.rb | 1 - .../factories/runtime_function_definitions.rb | 1 + .../projects/flows/create_service_spec.rb | 11 +- .../projects/flows/update_service_spec.rb | 78 --------- ...type_identifier_validation_service_spec.rb | 89 ++++++++++ ...type_identifier_validation_service_spec.rb | 51 ------ ...type_identifier_validation_service_spec.rb | 33 ---- ...reference_value_validation_service_spec.rb | 152 ++++++++++++++++++ .../validation/validation_service_spec.rb | 20 +++ 27 files changed, 441 insertions(+), 420 deletions(-) create mode 100644 app/graphql/mutations/namespaces/projects/flows/delete.rb delete mode 100644 app/graphql/types/input/data_type_type_input.rb delete mode 100644 app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb delete mode 100644 app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb delete mode 100644 app/graphql/types/input/rules/data_type_rule_input_type.rb delete mode 100644 app/services/namespaces/projects/flows/update_service.rb rename app/services/namespaces/projects/flows/validation/data_type/{generic_data_type_identifier_validation_service.rb => data_type_identifier_validation_service.rb} (60%) delete mode 100644 app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb delete mode 100644 docs/graphql/scalar/datatypeidentifierid.md delete mode 100644 spec/services/namespaces/projects/flows/update_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service_spec.rb delete mode 100644 spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb delete mode 100644 spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb diff --git a/app/graphql/mutations/namespaces/projects/flows/delete.rb b/app/graphql/mutations/namespaces/projects/flows/delete.rb new file mode 100644 index 00000000..d76205bd --- /dev/null +++ b/app/graphql/mutations/namespaces/projects/flows/delete.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Mutations + module Namespaces + module Projects + module Flows + class Delete < BaseMutation + description 'Deletes a namespace project.' + + field :flow, Types::FlowType, null: true, description: 'The deleted flow.' + + argument :flow_id, Types::GlobalIdType[::Flow], + description: 'The id of the flow which will be deleted' + + def resolve(flow_id:) + flow = SagittariusSchema.object_from_id(flow_id) + + if flow.nil? + return { flow: nil, + errors: [create_message_error('Invalid flow')] } + end + + ::Namespaces::Projects::Flows::DeleteService.new( + current_authentication, + flow + ).execute.to_mutation_response(success_key: :flow) + end + end + end + end + end +end diff --git a/app/graphql/types/input/data_type_identifier_input_type.rb b/app/graphql/types/input/data_type_identifier_input_type.rb index bd79bf96..337e2957 100644 --- a/app/graphql/types/input/data_type_identifier_input_type.rb +++ b/app/graphql/types/input/data_type_identifier_input_type.rb @@ -5,8 +5,8 @@ module Input class DataTypeIdentifierInputType < Types::BaseInputObject description 'Input type for data type identifier' - argument :data_type_id, Types::GlobalIdType[::DataTypeIdentifier], required: false, - description: 'Data type ID' + argument :data_type_id, Types::GlobalIdType[::DataType], required: false, + description: 'Data type ID' argument :generic_key, String, required: false, description: 'Generic key value' argument :generic_type, Types::Input::GenericTypeInputType, required: false, diff --git a/app/graphql/types/input/data_type_type_input.rb b/app/graphql/types/input/data_type_type_input.rb deleted file mode 100644 index 00ce2aed..00000000 --- a/app/graphql/types/input/data_type_type_input.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Types - module Input - class DataTypeTypeInput < Types::BaseInputObject - description 'Represents a DataType' - - argument :identifier, String, required: true, description: 'The identifier scoped to the namespace' - argument :namespace_id, Types::GlobalIdType[::Namespace], - required: true, description: 'The namespace where this datatype belongs to' - argument :variant, Types::DataTypeVariantEnum, required: true, description: 'The type of the datatype' - - argument :generic_keys, [String], required: false, description: 'The generic keys for the datatype' - - argument :rules, [Rules::DataTypeRuleInputType], required: false, description: 'The rules for the datatype' - - argument :parent_type_identifier, String, required: false, - description: 'The identifier of the parent data type, if any' - end - end -end diff --git a/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb b/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb deleted file mode 100644 index 091e1c74..00000000 --- a/app/graphql/types/input/rules/data_type_rule_contains_key_config_input_type.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Types - module Input - module Rules - class DataTypeRuleContainsKeyConfigInputType < Types::BaseInputObject - description 'Input type for Data Type Rule Contains A Key configuration' - - argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, - required: false, description: 'The identifier of the data type this rule applies to' - - argument :key, String, required: true, description: 'The key to check for in the data type rule' - end - end - end -end diff --git a/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb b/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb deleted file mode 100644 index 138fa70e..00000000 --- a/app/graphql/types/input/rules/data_type_rule_contains_type_config_input_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Types - module Input - module Rules - class DataTypeRuleContainsTypeConfigInputType < Types::BaseInputObject - description 'Input type for Data Type Rule Contains Type configuration' - - argument :data_type_identifier, Types::Input::DataTypeIdentifierInputType, - required: false, description: 'The identifier of the data type this rule applies to' - end - end - end -end diff --git a/app/graphql/types/input/rules/data_type_rule_input_type.rb b/app/graphql/types/input/rules/data_type_rule_input_type.rb deleted file mode 100644 index 0425c6e0..00000000 --- a/app/graphql/types/input/rules/data_type_rule_input_type.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Types - module Input - module Rules - class DataTypeRuleInputType < Types::BaseInputObject - description 'Input type for Data Type Rule' - - argument :contains_key, DataTypeRuleContainsKeyConfigInputType, - required: false, description: 'Configuration for contains key rule' - - argument :contains_value, DataTypeRuleContainsTypeConfigInputType, - required: false, description: 'Configuration for contains type rule' - end - end - end -end diff --git a/app/grpc/concerns/grpc_stream_handler.rb b/app/grpc/concerns/grpc_stream_handler.rb index 10316a3a..59f24bfa 100644 --- a/app/grpc/concerns/grpc_stream_handler.rb +++ b/app/grpc/concerns/grpc_stream_handler.rb @@ -27,7 +27,7 @@ def grpc_stream(method) end define_singleton_method("end_#{method}") do |runtime_id| ActiveRecord::Base.connection.raw_connection - .exec("NOTIFY grpc_streams, '#{self.class},#{method},#{runtime_id},end'") + .exec("NOTIFY grpc_streams, '#{self},#{method},#{runtime_id},end'") end end end diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb index 165ca4ef..471cdd09 100644 --- a/app/services/namespaces/projects/flows/create_service.rb +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -21,21 +21,25 @@ def execute transactional do |t| settings = [] - params[:settings].each do |graphql_setting| - setting = FlowSetting.new(flow_setting_id: graphql_setting.flow_setting_id, - object: graphql_setting.object) - next if setting.valid? - - t.rollback_and_return! ServiceResponse.error( - message: 'Invalid flow setting', - payload: setting.errors - ) - settings << setting + if params.key?(:settings) + params[:settings].each do |graphql_setting| + setting = FlowSetting.new(flow_setting_id: graphql_setting.flow_setting_id, + object: graphql_setting.object) + next if setting.valid? + + t.rollback_and_return! ServiceResponse.error( + message: 'Invalid flow setting', + payload: setting.errors + ) + settings << setting + end + params[:settings] = settings end - params[:settings] = settings - node = create_node_function(params[:starting_node], t) - params[:starting_node] = node + if params.key?(:starting_node) && params[:starting_node].is_a?(Types::Input::NodeFunctionInputType) + node = create_node_function(params[:starting_node], t) + params[:starting_node] = node + end flow = Flow.create(project: namespace_project, **params) unless flow.persisted? diff --git a/app/services/namespaces/projects/flows/update_service.rb b/app/services/namespaces/projects/flows/update_service.rb deleted file mode 100644 index 24703656..00000000 --- a/app/services/namespaces/projects/flows/update_service.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -module Namespaces - module Projects - module Flows - class UpdateService - include Sagittarius::Database::Transactional - - attr_reader :current_authentication, :flow, :params - - def initialize(current_authentication, flow:, **params) - @current_authentication = current_authentication - @flow = flow - @params = params - end - - def execute - unless Ability.allowed?(current_authentication, :update_flows, flow.project) - return ServiceResponse.error(message: 'Missing permission', payload: :missing_permission) - end - - transactional do |t| - old_flow_attributes = flow.attributes.except('created_at', 'updated_at') - - success = flow.update(params) - - unless success - t.rollback_and_return! ServiceResponse.error( - message: 'Failed to update flow', - payload: flow.errors - ) - end - - res = Validation::ValidationService.new(current_authentication, flow).execute - - if res.error? - t.rollback_and_return! ServiceResponse.error( - message: 'Flow validation failed', - payload: res.payload - ) - end - - AuditService.audit( - :flow_updated, - author_id: current_authentication.user.id, - entity: flow, - target: flow.project, - details: { - new_flow: flow.attributes.except('created_at', 'updated_at'), - old_flow: old_flow_attributes, - } - ) - - ServiceResponse.success(message: 'Created new project', payload: flow) - end - end - end - end - end -end diff --git a/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service.rb similarity index 60% rename from app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb rename to app/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service.rb index 832d93ac..10896f64 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service.rb @@ -5,20 +5,21 @@ module Projects module Flows module Validation module DataType - class GenericDataTypeIdentifierValidationService + class DataTypeIdentifierValidationService include Code0::ZeroTrack::Loggable include Sagittarius::Database::Transactional - attr_reader :current_authentication, :flow, :data_type_identifier + attr_reader :current_authentication, :flow, :node, :data_type_identifier - def initialize(current_authentication, flow, data_type_identifier) + def initialize(current_authentication, flow, node, data_type_identifier) @current_authentication = current_authentication @flow = flow + @node = node @data_type_identifier = data_type_identifier end def execute - logger.debug("Validating flow_type: #{data_type_identifier.inspect} for flow: #{flow.id}") + logger.debug("Validating data_type_identifier: #{data_type_identifier.id} for flow: #{flow.id}") transactional do |t| if data_type_identifier.invalid? @@ -33,13 +34,6 @@ def execute ) ) end - if data_type_identifier.data_type.present? - DataTypeValidationService.new( - current_authentication, - flow, - data_type_identifier.data_type - ).execute - end if data_type_identifier.runtime != flow.project.primary_runtime logger.debug(message: 'Data type identifier runtime mismatch', primary_runtime: flow.project.primary_runtime.id, @@ -53,6 +47,33 @@ def execute ) ) end + + if data_type_identifier.generic_key.present? + unless node.runtime_function.generic_keys.include?(data_type_identifier.generic_key) + t.rollback_and_return!( + ServiceResponse.error( + message: "Data type identifier #{data_type_identifier.id} " \ + 'does not have a generic key which exists in the node function ' \ + "#{node.runtime_function.generic_keys}", + payload: :generic_key_not_found + ) + ) + end + elsif data_type_identifier.generic_type.present? + ::NodeFunction::GenericTypeValidationService.new( + current_authentication, + flow, + data_type_identifier.generic_type + ).execute + elsif data_type_identifier.data_type.present? + DataTypeValidationService.new( + current_authentication, + flow, + data_type_identifier.data_type + ).execute + end + + nil end end end diff --git a/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb deleted file mode 100644 index a6914cdd..00000000 --- a/app/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -module Namespaces - module Projects - module Flows - module Validation - module DataType - class GenericMapperDataTypeIdentifierValidationService - include Code0::ZeroTrack::Loggable - include Sagittarius::Database::Transactional - - attr_reader :current_authentication, :flow, :parameter, :mapper, :data_type_identifier - - def initialize(current_authentication, flow, parameter, mapper, data_type_identifier) - @current_authentication = current_authentication - @flow = flow - @parameter = parameter - @mapper = mapper - @data_type_identifier = data_type_identifier - end - - def execute - logger.debug("Validating generic_mapper: #{mapper.inspect}, source for flow: #{flow.id}") - - transactional do |t| - ::GenericDataTypeIdentifierValidationService.new( - current_authentication, - flow, - data_type_identifier - ).execute - - if data_type_identifier.generic_key.present? - unless parameter.function_value.runtime_function_definition - .generic_keys.has?(data_type_identifier.generic_key) - t.rollback_and_return!( - ServiceResponse.error( - message: "Generic type #{parameter.generic_type.data_type.id} " \ - "does not have a generic key for source #{source.generic_key}", - payload: :generic_key_not_found - ) - ) - end - return - end - if data_type_identifier.data_type.present? - DataTypeValidationService.new( - current_authentication, - flow, - data_type_identifier.data_type - ).execute - return - end - if data_type_identifier.generic_type.present? - ::NodeFunction::GenericTypeValidationService.new( - current_authentication, - flow, - source.generic_type - ).execute - end - end - end - end - end - end - end - end -end diff --git a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb index c6c17847..2a93777b 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb @@ -19,12 +19,12 @@ def initialize(current_authentication, flow, parameter, generic_mapper) end def execute - logger.debug("Validating node function: #{parameter.inspect} for flow: #{flow.id}") + logger.debug("Validating generic mapper: #{generic_mapper.inspect} for flow: #{flow.id}") transactional do |t| target = generic_mapper.target - # Validate the target + # Validate the target the identifier gets validated later unless parameter.generic_type.data_type.generic_keys.has?(target) t.rollback_and_return!( ServiceResponse.error( @@ -35,11 +35,10 @@ def execute ) end - ::DataType::GenericMapperDataTypeIdentifierValidationService.new( + ::DataType::DataTypeIdentifierValidationService.new( current_authentication, flow, - parameter, - generic_mapper, + parameter.node_function, generic_mapper.source ).execute end diff --git a/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb index d835cb77..e6fcfc23 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb @@ -23,10 +23,10 @@ def execute ::DataType::DataTypeValidationService.new( current_authentication, flow, - identifier.data_type + generic_type.data_type ).execute - identifier.data_type.generic_mappers.each do |generic_mapper| + generic_type.generic_mappers.each do |generic_mapper| logger.debug("Validating generic mapper: #{generic_mapper.id}" \ "for data type identifier: #{identifier.id}") ::DataType::GenericMapperValidationService.new( diff --git a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb index 87b50c8d..7a21f859 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb @@ -38,6 +38,7 @@ def execute ReferenceValueValidationService.new( current_authentication, flow, + parameter.node_function, parameter.reference_value ).execute return diff --git a/app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb index b6a1aa1f..bc41432c 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb @@ -9,42 +9,102 @@ class ReferenceValueValidationService include Code0::ZeroTrack::Loggable include Sagittarius::Database::Transactional - attr_reader :current_authentication, :flow, :node_function + attr_reader :current_authentication, :flow, :node, :reference_value - def initialize(current_authentication, flow, node_function) + def initialize(current_authentication, flow, node, reference_value) @current_authentication = current_authentication @flow = flow - @node_function = node_function + @node = node + @reference_value = reference_value + end + + def find_primary_nodes(search_node, curr_primary, primary_level) + found_node = nil + search_node.node_parameters.each do |param| + next if param.function_value.blank? + + curr_primary += 1 + if curr_primary == primary_level + found_node = param.function_value + break + end + find_node = find_primary_nodes(param.function_value, curr_primary, primary_level) + found_node = find_node[:found_node] + break if found_node.present? + end + { + found_node: found_node, + new_primary: curr_primary, + } end def execute transactional do |t| - ::DataType::DataTypeIdentifierValidationService.new( + Namespaces::Projects::Flows::Validation::DataType::DataTypeIdentifierValidationService.new( current_authentication, flow, - node_function, - parameter.reference_value.data_type_identifier + node, + reference_value.data_type_identifier ).execute - identifier = parameter.reference_value.data_type_identifier + primary_level = reference_value.primary_level + curr_primary = 0 + node = flow.starting_node + + while curr_primary < primary_level + if node.nil? + t.rollback_and_return!( + ServiceResponse.error( + message: "Primary value #{primary_level} not found in flow nodes (primary value to deep)", + payload: :primary_level_not_found + ) + ) + end + nodes = find_primary_nodes(node, curr_primary, primary_level) + if nodes[:found_node].nil? + curr_primary = nodes[:new_primary] + else + node = nodes[:found_node] + break + end + + next_node = node.next_node + node = next_node + end + + secondary_level = reference_value.secondary_level + + curr_secondary = 0 - if identifier.generic_key.present? + while curr_secondary != secondary_level + if node.next_node.nil? + t.rollback_and_return!( + ServiceResponse.error( + message: "Secondary value #{secondary_level} not found in flow nodes (secondary value to deep)", + payload: :secondary_level_not_found + ) + ) + end + next_node = node.next_node + node = next_node + + curr_secondary += 1 + end + + return if reference_value.tertiary_level.nil? + + tertiary_level = reference_value.tertiary_level + + if tertiary_level >= node.node_parameters.count t.rollback_and_return!( ServiceResponse.error( - message: 'Data type identifier cannot have a generic key in a function', - payload: :generic_key_present + message: "Tertiary level #{tertiary_level} exceeds the number of parameters in the node", + payload: :tertiary_level_exceeds_parameters ) ) end - if identifier.generic_type.present? - GenericTypeValidationService.new( - current_authentication, - flow, - node_function, - identifier.generic_type - ).execute - end + # TODO: verify reference paths end end end diff --git a/docs/graphql/input_object/datatypeidentifierinput.md b/docs/graphql/input_object/datatypeidentifierinput.md index d658295c..b8bbb539 100644 --- a/docs/graphql/input_object/datatypeidentifierinput.md +++ b/docs/graphql/input_object/datatypeidentifierinput.md @@ -8,6 +8,6 @@ Input type for data type identifier | Name | Type | Description | |------|------|-------------| -| `dataTypeId` | [`DataTypeIdentifierID`](../scalar/datatypeidentifierid.md) | Data type ID | +| `dataTypeId` | [`DataTypeID`](../scalar/datatypeid.md) | Data type ID | | `genericKey` | [`String`](../scalar/string.md) | Generic key value | | `genericType` | [`GenericTypeInput`](../input_object/generictypeinput.md) | Generic type information | diff --git a/docs/graphql/mutation/namespacesprojectsflowscreate.md b/docs/graphql/mutation/namespacesprojectsflowscreate.md index 1dadc182..21d74795 100644 --- a/docs/graphql/mutation/namespacesprojectsflowscreate.md +++ b/docs/graphql/mutation/namespacesprojectsflowscreate.md @@ -9,7 +9,7 @@ Creates a new flow. | Name | Type | Description | |------|------|-------------| | `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. | -| `flow` | [`FlowInput!`](../input_object/flowinput.md) | | +| `flow` | [`FlowInput!`](../input_object/flowinput.md) | The flow to create | | `projectId` | [`NamespaceProjectID!`](../scalar/namespaceprojectid.md) | The ID of the project to which the flow belongs to | ## Fields diff --git a/docs/graphql/scalar/datatypeidentifierid.md b/docs/graphql/scalar/datatypeidentifierid.md deleted file mode 100644 index b106460b..00000000 --- a/docs/graphql/scalar/datatypeidentifierid.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: DataTypeIdentifierID ---- - -A unique identifier for all DataTypeIdentifier entities of the application diff --git a/spec/factories/node_functions.rb b/spec/factories/node_functions.rb index 85097149..5dd5bfa2 100644 --- a/spec/factories/node_functions.rb +++ b/spec/factories/node_functions.rb @@ -5,6 +5,5 @@ runtime_function factory: %i[runtime_function_definition] next_node { nil } node_parameters { [] } - node_parameter_values { [] } end end diff --git a/spec/factories/runtime_function_definitions.rb b/spec/factories/runtime_function_definitions.rb index e61c3771..66c0e28e 100644 --- a/spec/factories/runtime_function_definitions.rb +++ b/spec/factories/runtime_function_definitions.rb @@ -7,5 +7,6 @@ runtime_name { generate(:runtime_function_definition_name) } return_type { nil } runtime + generic_keys { [] } end end diff --git a/spec/services/namespaces/projects/flows/create_service_spec.rb b/spec/services/namespaces/projects/flows/create_service_spec.rb index 2caa9f22..68cb79fe 100644 --- a/spec/services/namespaces/projects/flows/create_service_spec.rb +++ b/spec/services/namespaces/projects/flows/create_service_spec.rb @@ -7,9 +7,14 @@ described_class.new(create_authentication(current_user), namespace_project: namespace_project, **params).execute end - let(:namespace_project) { create(:namespace_project) } - let(:starting_node) { create(:node_function) } - let(:params) { { project: namespace_project, flow_type: create(:flow_type), starting_node: starting_node } } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project, primary_runtime: runtime) } + let(:starting_node) do + create(:node_function, runtime_function: create(:runtime_function_definition, runtime: runtime)) + end + let(:params) do + { project: namespace_project, flow_type: create(:flow_type, runtime: runtime), starting_node: starting_node } + end shared_examples 'does not create' do it { is_expected.to be_error } diff --git a/spec/services/namespaces/projects/flows/update_service_spec.rb b/spec/services/namespaces/projects/flows/update_service_spec.rb deleted file mode 100644 index 03a4a3ff..00000000 --- a/spec/services/namespaces/projects/flows/update_service_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Namespaces::Projects::Flows::UpdateService do - subject(:service_response) { described_class.new(create_authentication(current_user), flow: flow, **params).execute } - - let(:namespace_project) { create(:namespace_project) } - let(:starting_node) { create(:node_function) } - let(:flow_type) { create(:flow_type) } - let(:flow) { create(:flow, project: namespace_project, flow_type: flow_type, starting_node: starting_node) } - let(:new_starting_node) { create(:node_function) } - let(:params) { { starting_node: new_starting_node } } - - shared_examples 'does not update' do - it { is_expected.to be_error } - - it 'does not update flow' do - expect { service_response }.not_to change { flow.reload.starting_node_id } - end - - it { expect { service_response }.not_to create_audit_event } - end - - context 'when user does not exist' do - let(:current_user) { nil } - - it_behaves_like 'does not update' - end - - context 'when user does not have permission' do - let(:current_user) { create(:user) } - - it_behaves_like 'does not update' - end - - context 'when params are invalid' do - let(:current_user) { create(:user) } - let(:params) { { starting_node: nil } } # Invalid params - - before do - stub_allowed_ability(NamespaceProjectPolicy, :update_flows, user: current_user, subject: namespace_project) - end - - it_behaves_like 'does not update' - end - - context 'when user has permission and params are valid' do - let(:current_user) { create(:user) } - - before do - stub_allowed_ability(NamespaceProjectPolicy, :update_flows, user: current_user, subject: namespace_project) - end - - it { is_expected.to be_success } - - it 'updates the flow' do - expect { service_response }.to change { flow.reload.starting_node_id }.to(new_starting_node.id) - end - - it do - old_attributes = flow.attributes.except('created_at', 'updated_at') - - is_expected.to create_audit_event( - :flow_updated, - author_id: current_user.id, - entity_type: 'Flow', - entity_id: flow.id, - details: { - old_flow: old_attributes, - new_flow: flow.reload.attributes.except('created_at', 'updated_at'), - }, - target_id: flow.project.id, - target_type: 'NamespaceProject' - ) - end - end -end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service_spec.rb new file mode 100644 index 00000000..21cd6d65 --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service_spec.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Namespaces::Projects::Flows::Validation::DataType::DataTypeIdentifierValidationService do + subject(:service_response) do + described_class.new(create_authentication(current_user), flow, node, data_type_identifier).execute + end + + include_context 'with mocked services' + + let(:all_service_expectations) do + # Default case + { + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, + Namespaces::Projects::Flows::Validation::NodeFunction::GenericTypeValidationService => 0, + } + end + let(:mocked_service_expectations) { all_service_expectations } + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project, primary_runtime: runtime) } + let(:node) do + create(:node_function, + runtime_function: create(:runtime_function_definition, generic_keys: ['T'], runtime: runtime)) + end + let(:parameter) do + create( + :node_parameter, + runtime_parameter: create(:runtime_parameter_definition, data_type: data_type_identifier), + node_function: node + ) + end + let(:flow) { create(:flow, project: namespace_project) } + let(:data_type_identifier) { create(:data_type_identifier, generic_key: 'T', runtime: runtime) } + + let(:generic_mapper) do + create(:generic_mapper, source: + create(:data_type_identifier, data_type: create(:data_type, runtime: runtime)), target: 'T') + end + + context 'when data_type.runtime == runtime' do + it { expect(service_response).to be_nil } + end + + context 'when data_type.runtime != runtime' do + let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type)) } + + it 'returns an error' do + expect(service_response).to be_error + expect(service_response.payload).to eq(:runtime_mismatch) + end + end + + context 'when data_type_identifier is a data_type' do + let(:data_type_identifier) do + create(:data_type_identifier, data_type: create(:data_type, runtime: runtime), runtime: runtime) + end + + let(:mocked_service_expectations) do + { + **all_service_expectations, + Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 1, + } + end + + it { expect(service_response).to be_nil } + end + + context 'when T is contained in the function definition' do + let(:node) do + create(:node_function, + runtime_function: create(:runtime_function_definition, generic_keys: ['T'], runtime: runtime)) + end + + it { expect(service_response).to be_nil } + end + + context 'when T is not contained in the function definition' do + let(:node) do + create(:node_function, + runtime_function: create(:runtime_function_definition, generic_keys: [], runtime: runtime)) + end + + it { expect(service_response).to be_error } + it { expect(service_response.payload).to eq(:generic_key_not_found) } + end +end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb deleted file mode 100644 index 5c4e8056..00000000 --- a/spec/services/namespaces/projects/flows/validation/data_type/generic_data_type_identifier_validation_service_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Namespaces::Projects::Flows::Validation::DataType::GenericDataTypeIdentifierValidationService do - subject(:service_response) do - described_class.new(create_authentication(current_user), flow, data_type_identifier).execute - end - - include_context 'with mocked services' - - let(:all_service_expectations) do - # Default case - { - Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 1, - } - end - let(:current_user) { create(:user) } - let(:runtime) { create(:runtime) } - let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } - let(:flow) { create(:flow, project: namespace_project) } - let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type), runtime: runtime) } - let(:mocked_service_expectations) { all_service_expectations } - let(:default_execute_response) { nil } - - context 'when data_type.runtime == runtime' do - it { expect(service_response).to be_nil } - end - - context 'when data_type.runtime != runtime' do - let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type)) } - - it 'returns an error' do - expect(service_response).to be_error - expect(service_response.payload).to eq(:runtime_mismatch) - end - end - - context 'when data_type_identifier is not a data_type' do - let(:data_type_identifier) { create(:data_type_identifier, generic_key: 'T', runtime: runtime) } - - let(:mocked_service_expectations) do - { - **all_service_expectations, - Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, - } - end - - it { expect(service_response).to be_nil } - end -end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb deleted file mode 100644 index 08453d87..00000000 --- a/spec/services/namespaces/projects/flows/validation/data_type/generic_mapper_data_type_identifier_validation_service_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Namespaces::Projects::Flows::Validation::DataType::GenericMapperDataTypeIdentifierValidationService do - subject(:service_response) do - described_class.new(create_authentication(current_user), flow, parameter, mapper, data_type_identifier).execute - end - - include_context 'with mocked services' - - let(:all_service_expectations) do - # Default case - { - Namespaces::Projects::Flows::Validation::DataType::GenericDataTypeIdentifierValidationService => 1, - Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService => 0, - Namespaces::Projects::Flows::Validation::NodeFunction::GenericTypeValidationService => 0, - } - end - let(:current_user) { create(:user) } - let(:runtime) { create(:runtime) } - let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } - let(:parameter) do - create(:node_parameter, runtime: runtime, - node_function: create(:node_function, - runtime: runtime)) - end - let(:flow) { create(:flow, project: namespace_project) } - let(:data_type_identifier) { create(:data_type_identifier, data_type: create(:data_type), runtime: runtime) } - let(:generic_mapper) { create(:generic_mapper, source: data_type_identifier, target: 'T') } - let(:mocked_service_expectations) { all_service_expectations } - let(:default_execute_response) { nil } -end diff --git a/spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb new file mode 100644 index 00000000..5206b6e5 --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +require 'rails_helper' + +Rspec.describe Namespaces::Projects::Flows::Validation::NodeFunction::ReferenceValueValidationService do + subject(:service_response) do + described_class.new(create_authentication(current_user), flow, first_node, reference_value).execute + end + + include_context 'with mocked services' + + let(:mocked_service_expectations) do + { + Namespaces::Projects::Flows::Validation::DataType::DataTypeIdentifierValidationService => 1, + } + end + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project, primary_runtime: runtime) } + let(:flow) { create(:flow, project: namespace_project, starting_node: first_node) } + + let(:first_node) do + create(:node_function, + runtime_function: create(:runtime_function_definition, runtime: runtime), + node_parameters: [ + create(:node_parameter, + runtime_parameter: create(:runtime_parameter_definition, data_type: data_type_identifier), + literal_value: nil, + function_value: create(:node_function)) + ], + next_node: second_node) + end + let(:second_node) do + create(:node_function, + runtime_function: create(:runtime_function_definition, runtime: runtime), + node_parameters: [ + create(:node_parameter, + runtime_parameter: create(:runtime_parameter_definition, data_type: data_type_identifier), + literal_value: nil, + function_value: create(:node_function, node_parameters: [ + create(:node_parameter, + runtime_parameter: create(:runtime_parameter_definition, + data_type: data_type_identifier)) + ])), + create(:node_parameter, + runtime_parameter: create(:runtime_parameter_definition, data_type: data_type_identifier), + literal_value: nil, + function_value: create(:node_function)) + ]) + end + let(:data_type_identifier) do + create(:data_type_identifier, generic_key: 'T', runtime: runtime) + end + let(:primary_level) { 0 } + let(:secondary_level) { 0 } + let(:tertiary_level) { nil } + let(:reference_value) do + create(:reference_value, + data_type_identifier: data_type_identifier, + primary_level: primary_level, + secondary_level: secondary_level, + tertiary_level: tertiary_level) + end + + context 'with horizontal reference' do + let(:secondary_level) { 0 } + + it { expect(service_response).to be_nil } + + context 'with horizontal reference out of bounds' do + let(:secondary_level) { 2 } + + it { expect(service_response).to be_error } + it { expect(service_response.payload).to eq(:secondary_level_not_found) } + end + end + + context 'with primary level' do + let(:primary_level) { 1 } + + it { expect(service_response).to be_nil } + + context 'with primary level of 2' do + let(:primary_level) { 2 } + + it { expect(service_response).to be_nil } + end + + context 'with primary level of 3' do + let(:primary_level) { 3 } + + it { expect(service_response).to be_nil } + end + + context 'with primary level out of bounds' do + let(:primary_level) { 4 } + + it { expect(service_response).to be_error } + it { expect(service_response.payload).to eq(:primary_level_not_found) } + end + end + + context 'with tertiary level' do + let(:primary_level) { 0 } + let(:secondary_level) { 1 } + let(:tertiary_level) { 1 } + + it { expect(service_response).to be_nil } + + context 'with not existing parameter' do + let(:primary_level) { 0 } + let(:secondary_level) { 0 } + let(:tertiary_level) { 1 } + + it { expect(service_response.payload).to eq(:tertiary_level_exceeds_parameters) } + end + + context 'with no parameter' do + let(:primary_level) { 1 } + let(:secondary_level) { 0 } + let(:tertiary_level) { nil } + + it { expect(service_response).to be_nil } + + context 'with deeper primary level' do + let(:primary_level) { 1 } + let(:secondary_level) { 0 } + let(:tertiary_level) { 0 } + + it { expect(service_response.payload).to eq(:tertiary_level_exceeds_parameters) } + end + + context 'with deeper primary level nested' do + let(:primary_level) { 2 } + let(:secondary_level) { 0 } + let(:tertiary_level) { 0 } + + it { expect(service_response).to be_nil } + end + end + + context 'with tertiary level out of bounds' do + let(:primary_level) { 0 } + let(:secondary_level) { 0 } + let(:tertiary_level) { 2 } + + it { expect(service_response).to be_error } + it { expect(service_response.payload).to eq(:tertiary_level_exceeds_parameters) } + end + end +end diff --git a/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb index 5d33b89d..dfb8ad79 100644 --- a/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb @@ -115,4 +115,24 @@ expect(service_response.payload).to eq(:no_primary_runtime) end end + + # Some random examples to ensure the service works as expected + context 'with real unmocked examples' do + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project, primary_runtime: runtime) } + let(:starting_node) do + create(:node_function, runtime_function: create(:runtime_function_definition, runtime: runtime)) + end + let(:flow) do + create(:flow, project: namespace_project, flow_type: create(:flow_type, runtime: runtime), + starting_node: starting_node) + end + + context 'with simplest flow' do + let(:all_service_expectations) { {} } + + it { is_expected.to be_success } + it { expect(service_response.payload).to eq(flow) } + end + end end From 6a3872706ddda5611397d22f57c89b56cdc9da29 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Sat, 31 May 2025 00:19:51 +0200 Subject: [PATCH 39/54] Add generic combination strategies and update generic mapper structure, enhance validation services and input types --- Gemfile | 2 +- Gemfile.lock | 4 +- app/graphql/types/data_type_rule_type.rb | 19 + .../types/data_type_rules/config_type.rb | 29 + .../contains_key_config_type.rb | 15 + .../contains_type_config_type.rb | 14 + .../data_type_rule_variant_enum.rb | 24 + .../input_types_config_type.rb | 11 + .../item_of_collection_config_type.rb | 14 + .../number_range_config_type.rb | 18 + .../data_type_rules/regex_config_type.rb | 14 + app/graphql/types/data_type_type.rb | 10 +- app/graphql/types/data_type_variant_enum.rb | 4 +- .../types/input/generic_mapper_input_type.rb | 2 +- app/models/data_type.rb | 7 +- app/models/data_type_identifier.rb | 6 +- app/models/data_type_rule.rb | 14 + app/models/function_generic_mapper.rb | 3 +- app/models/generic_combination_strategy.rb | 12 + app/models/generic_mapper.rb | 4 +- .../data_types/InputTypeRuleConfig.json | 23 + .../data_types/ReturnTypeRuleConfig.json | 12 + .../projects/flows/create_service.rb | 2 +- .../data_type/data_type_validation_service.rb | 3 +- .../generic_mapper_validation_service.rb | 21 +- ...e_function_parameter_validation_service.rb | 9 + .../node_function_validation_service.rb | 8 + .../runtimes/data_types/update_service.rb | 5 +- .../update_service.rb | 7 +- .../20250525192143_implement_generics.rb | 16 +- ...4_create_generic_combination_strategies.rb | 15 + db/schema_migrations/20250530213244 | 1 + db/structure.sql | 2833 ++++++++++++++--- .../enum/datatyperulesdatatyperulevariant.md | 15 + docs/graphql/enum/datatypevariant.md | 4 +- .../input_object/genericmapperinput.md | 2 +- docs/graphql/object/containskeyconfig.md | 13 + docs/graphql/object/containstypeconfig.md | 12 + docs/graphql/object/datatype.md | 4 + docs/graphql/object/datatyperule.md | 15 + docs/graphql/object/datatyperuleconnection.md | 15 + docs/graphql/object/datatyperuleedge.md | 13 + docs/graphql/object/itemofcollectionconfig.md | 12 + docs/graphql/object/numberrangeconfig.md | 14 + docs/graphql/object/regexconfig.md | 12 + docs/graphql/union/config.md | 13 + .../generic_combination_strategies.rb | 8 + spec/factories/generic_mappers.rb | 3 +- spec/graphql/types/data_type_type_spec.rb | 4 + spec/models/data_type_identifier_spec.rb | 5 +- spec/models/data_type_spec.rb | 17 +- spec/models/function_generic_mapper_spec.rb | 2 +- .../generic_combination_strategy_spec.rb | 18 + spec/models/generic_mapper_spec.rb | 7 +- ...untime_function_definition_service_spec.rb | 9 +- .../data_type_validation_service_spec.rb | 12 +- .../generic_mapper_validation_service_spec.rb | 54 + ...reference_value_validation_service_spec.rb | 4 +- 58 files changed, 2966 insertions(+), 502 deletions(-) create mode 100644 app/graphql/types/data_type_rule_type.rb create mode 100644 app/graphql/types/data_type_rules/config_type.rb create mode 100644 app/graphql/types/data_type_rules/contains_key_config_type.rb create mode 100644 app/graphql/types/data_type_rules/contains_type_config_type.rb create mode 100644 app/graphql/types/data_type_rules/data_type_rule_variant_enum.rb create mode 100644 app/graphql/types/data_type_rules/input_types_config_type.rb create mode 100644 app/graphql/types/data_type_rules/item_of_collection_config_type.rb create mode 100644 app/graphql/types/data_type_rules/number_range_config_type.rb create mode 100644 app/graphql/types/data_type_rules/regex_config_type.rb create mode 100644 app/models/generic_combination_strategy.rb create mode 100644 app/models/json_schemas/data_types/InputTypeRuleConfig.json create mode 100644 app/models/json_schemas/data_types/ReturnTypeRuleConfig.json create mode 100644 db/migrate/20250530213244_create_generic_combination_strategies.rb create mode 100644 db/schema_migrations/20250530213244 create mode 100644 docs/graphql/enum/datatyperulesdatatyperulevariant.md create mode 100644 docs/graphql/object/containskeyconfig.md create mode 100644 docs/graphql/object/containstypeconfig.md create mode 100644 docs/graphql/object/datatyperule.md create mode 100644 docs/graphql/object/datatyperuleconnection.md create mode 100644 docs/graphql/object/datatyperuleedge.md create mode 100644 docs/graphql/object/itemofcollectionconfig.md create mode 100644 docs/graphql/object/numberrangeconfig.md create mode 100644 docs/graphql/object/regexconfig.md create mode 100644 docs/graphql/union/config.md create mode 100644 spec/factories/generic_combination_strategies.rb create mode 100644 spec/models/generic_combination_strategy_spec.rb create mode 100644 spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb diff --git a/Gemfile b/Gemfile index 036eb6a5..704d9b81 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.28' +gem 'tucana', '0.0.29' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 4271cf60..e8e27776 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -362,7 +362,7 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.28) + tucana (0.0.29) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -416,7 +416,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.28) + tucana (= 0.0.29) tzinfo-data RUBY VERSION diff --git a/app/graphql/types/data_type_rule_type.rb b/app/graphql/types/data_type_rule_type.rb new file mode 100644 index 00000000..e1528b44 --- /dev/null +++ b/app/graphql/types/data_type_rule_type.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Types + class DataTypeRuleType < Types::BaseObject + description 'Represents a rule that can be applied to a data type.' + + field :variant, Types::DataTypeRules::DataTypeRuleVariantEnum, null: false, + description: 'The type of the rule' + + field :config, Types::DataTypeRules::ConfigType, null: false, + description: 'The configuration of the rule' + + timestamps + + def config + object.config.merge(variant: object.variant) + end + end +end diff --git a/app/graphql/types/data_type_rules/config_type.rb b/app/graphql/types/data_type_rules/config_type.rb new file mode 100644 index 00000000..68e0b247 --- /dev/null +++ b/app/graphql/types/data_type_rules/config_type.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Types + module DataTypeRules + class ConfigType < Types::BaseUnion + description 'Represents a rule that can be applied to a data type.' + + possible_types ContainsKeyConfigType, ContainsTypeConfigType, NumberRangeConfigType, ItemOfCollectionConfigType, + RegexConfigType + + def self.resolve_type(object, _context) + case object[:variant] + when :contains_key + Types::DataTypeRuleContainsKeyType + when :contains_type + Types::DataTypeRuleContainsTypeType + when :number_range + Types::DataTypeRuleNumberRangeType + when :item_of_collection + Types::DataTypeRuleItemOfCollectionType + when :regex + Types::DataTypeRuleRegexType + else + raise GraphQL::ExecutionError, "Unknown data type rule variant: #{object.variant}" + end + end + end + end +end diff --git a/app/graphql/types/data_type_rules/contains_key_config_type.rb b/app/graphql/types/data_type_rules/contains_key_config_type.rb new file mode 100644 index 00000000..09d28e7c --- /dev/null +++ b/app/graphql/types/data_type_rules/contains_key_config_type.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module DataTypeRules + class ContainsKeyConfigType < Types::BaseObject + description 'Represents a rule that can be applied to a data type.' + + authorize :read_flow + + field :data_type_identifier, Types::DataTypeIdentifierType, + null: false, description: 'The identifier of the data type this rule belongs to' + field :key, String, null: false, description: 'The key of the rule' + end + end +end diff --git a/app/graphql/types/data_type_rules/contains_type_config_type.rb b/app/graphql/types/data_type_rules/contains_type_config_type.rb new file mode 100644 index 00000000..df9ff992 --- /dev/null +++ b/app/graphql/types/data_type_rules/contains_type_config_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module DataTypeRules + class ContainsTypeConfigType < Types::BaseObject + description 'Represents a rule that can be applied to a data type.' + + authorize :read_flow + + field :data_type_identifier, Types::DataTypeIdentifierType, + null: false, description: 'The identifier of the data type this rule belongs to' + end + end +end diff --git a/app/graphql/types/data_type_rules/data_type_rule_variant_enum.rb b/app/graphql/types/data_type_rules/data_type_rule_variant_enum.rb new file mode 100644 index 00000000..e8f99bf8 --- /dev/null +++ b/app/graphql/types/data_type_rules/data_type_rule_variant_enum.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Types + module DataTypeRules + class DataTypeRuleVariantEnum < Types::BaseEnum + description 'The type of rule that can be applied to a data type.' + + value :CONTAINS_KEY, 'The rule checks if a key is present in the data type.', + value: :contains_key + value :CONTAINS_TYPE, 'The rule checks if a specific type is present in the data type.', + value: :contains_type + value :NUMBER_RANGE, 'The rule checks if a number falls within a specified range.', + value: :number_range + value :ITEM_OF_COLLECTION, 'The rule checks if an item is part of a collection in the data type.', + value: :item_of_collection + value :REGEX, 'The rule checks if a string matches a specified regular expression.', + value: :regex + value :INPUT_TYPE, 'The rule checks if the data type matches a specific input type.', + value: :input_type + value :RETURN_TYPE, 'The rule checks if the data type matches a specific return type.', + value: :return_type + end + end +end diff --git a/app/graphql/types/data_type_rules/input_types_config_type.rb b/app/graphql/types/data_type_rules/input_types_config_type.rb new file mode 100644 index 00000000..e1f0c923 --- /dev/null +++ b/app/graphql/types/data_type_rules/input_types_config_type.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Types + module DataTypeRules + class InputTypesConfigType < Types::BaseObject + description 'Represents a rule that can be applied to a data type.' + + authorize :read_flow + end + end +end diff --git a/app/graphql/types/data_type_rules/item_of_collection_config_type.rb b/app/graphql/types/data_type_rules/item_of_collection_config_type.rb new file mode 100644 index 00000000..f7bd8720 --- /dev/null +++ b/app/graphql/types/data_type_rules/item_of_collection_config_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module DataTypeRules + class ItemOfCollectionConfigType < Types::BaseObject + description 'Represents a rule that can be applied to a data type.' + + authorize :read_flow + + field :items, [GraphQL::Types::JSON], null: true, + description: 'The items that can be configured for this rule.' + end + end +end diff --git a/app/graphql/types/data_type_rules/number_range_config_type.rb b/app/graphql/types/data_type_rules/number_range_config_type.rb new file mode 100644 index 00000000..72b7afec --- /dev/null +++ b/app/graphql/types/data_type_rules/number_range_config_type.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Types + module DataTypeRules + class NumberRangeConfigType < Types::BaseObject + description 'Represents a rule that can be applied to a data type.' + + authorize :read_flow + + field :from, Integer, null: false, + description: 'The minimum value of the range' + field :steps, Integer, null: true, + description: 'The step value for the range, if applicable' + field :to, Integer, null: false, + description: 'The maximum value of the range' + end + end +end diff --git a/app/graphql/types/data_type_rules/regex_config_type.rb b/app/graphql/types/data_type_rules/regex_config_type.rb new file mode 100644 index 00000000..8f379a29 --- /dev/null +++ b/app/graphql/types/data_type_rules/regex_config_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module DataTypeRules + class RegexConfigType < Types::BaseObject + description 'Represents a rule that can be applied to a data type.' + + authorize :read_flow + + field :pattern, String, null: false, + description: 'The regex pattern to match against the data type value.' + end + end +end diff --git a/app/graphql/types/data_type_type.rb b/app/graphql/types/data_type_type.rb index 7e3a550f..91af16c6 100644 --- a/app/graphql/types/data_type_type.rb +++ b/app/graphql/types/data_type_type.rb @@ -6,10 +6,18 @@ class DataTypeType < Types::BaseObject authorize :read_datatype + field :generic_keys, [String], null: true, description: 'Generic keys of the datatype' field :identifier, String, null: false, description: 'The identifier scoped to the namespace' + field :name, Types::TranslationType.connection_type, method: :names, null: false, + description: 'Names of the flow type setting' field :namespace, Types::NamespaceType, null: true, description: 'The namespace where this datatype belongs to' - field :variant, Types::DataTypeVariantEnum, null: false, description: 'The type of the datatype' + field :parent, Types::DataTypeIdentifierType, + null: true, description: 'The parent datatype' + field :rules, Types::DataTypeRuleType.connection_type, null: false, + description: 'Rules of the datatype' + field :variant, Types::DataTypeVariantEnum, null: false, + description: 'The type of the datatype' id_field DataType timestamps diff --git a/app/graphql/types/data_type_variant_enum.rb b/app/graphql/types/data_type_variant_enum.rb index 7c313f10..a5339660 100644 --- a/app/graphql/types/data_type_variant_enum.rb +++ b/app/graphql/types/data_type_variant_enum.rb @@ -9,7 +9,7 @@ class DataTypeVariantEnum < BaseEnum value :OBJECT, 'Represents an object', value: :object value :DATA_TYPE, 'Represents an data type containing a data type', value: :datatype value :ARRAY, 'Represents an array', value: :array - value :GENERIC, 'Represents a generic', value: :generic - value :FUNCTION, 'Represents a function', value: :function + value :ERROR, 'Represents a error', value: :error + value :NODE, 'Represents a node', value: :node end end diff --git a/app/graphql/types/input/generic_mapper_input_type.rb b/app/graphql/types/input/generic_mapper_input_type.rb index 6d5ed6cf..64f20293 100644 --- a/app/graphql/types/input/generic_mapper_input_type.rb +++ b/app/graphql/types/input/generic_mapper_input_type.rb @@ -5,7 +5,7 @@ module Input class GenericMapperInputType < Types::BaseInputObject description 'Input type for generic mappers' - argument :source, Types::Input::DataTypeIdentifierInputType, + argument :sources, [Types::Input::DataTypeIdentifierInputType], required: true, description: 'The source data type identifier for the mapper' argument :target, String, diff --git a/app/models/data_type.rb b/app/models/data_type.rb index 8cc41553..635c5459 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -13,10 +13,9 @@ class DataType < ApplicationRecord enum :variant, VARIANTS, prefix: :variant - belongs_to :parent_type, class_name: 'DataType', inverse_of: :child_types, optional: true + belongs_to :parent_type, class_name: 'DataTypeIdentifier', inverse_of: :child_types, optional: true belongs_to :runtime, inverse_of: :data_types - has_many :child_types, class_name: 'DataType', inverse_of: :parent_type has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :rules, class_name: 'DataTypeRule', inverse_of: :data_type has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :data_type @@ -31,8 +30,8 @@ class DataType < ApplicationRecord def validate_recursion current_type = self - until current_type.parent_type.nil? - current_type = current_type.parent_type + until current_type.parent_type&.data_type.nil? + current_type = current_type.parent_type&.data_type if current_type == self errors.add(:parent_type, :recursion) diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 4daa8ac9..526813a5 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -4,9 +4,11 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers belongs_to :generic_type, optional: true, inverse_of: :data_type_identifiers belongs_to :runtime, inverse_of: :data_type_identifiers + belongs_to :generic_mapper, class_name: 'GenericMapper', optional: true, inverse_of: :sources + belongs_to :function_generic_mapper, class_name: 'FunctionGenericMapper', + optional: true, inverse_of: :sources - has_many :generic_mappers, inverse_of: :source - has_many :function_generic_mappers, class_name: 'FunctionGenericMapper', inverse_of: :source + has_many :child_types, class_name: 'DataType', inverse_of: :parent_type validate :exactly_one_of_generic_key_data_type_id_generic_type_id diff --git a/app/models/data_type_rule.rb b/app/models/data_type_rule.rb index d601b0a4..02532e52 100644 --- a/app/models/data_type_rule.rb +++ b/app/models/data_type_rule.rb @@ -7,6 +7,8 @@ class DataTypeRule < ApplicationRecord item_of_collection: 3, number_range: 4, regex: 5, + return_type: 6, + input_type: 7, }.with_indifferent_access enum :variant, VARIANTS, prefix: :variant @@ -47,4 +49,16 @@ class DataTypeRule < ApplicationRecord filename: 'data_types/DataTypeRegexRuleConfig', hash_conversion: true, } + + validates :config, if: :variant_return_type?, + 'sagittarius/validators/json_schema': { + filename: 'data_types/ReturnTypeRuleConfig', + hash_conversion: true, + } + + validates :config, if: :variant_input_type?, + 'sagittarius/validators/json_schema': { + filename: 'data_types/InputTypeRuleConfig', + hash_conversion: true, + } end diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index 10d8b015..a8c9644d 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true class FunctionGenericMapper < ApplicationRecord - belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mappers belongs_to :runtime_function_definition, class_name: 'RuntimeFunctionDefinition', optional: true, inverse_of: :generic_mappers belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, inverse_of: :function_generic_mappers + has_many :sources, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mapper + validates :target, presence: true end diff --git a/app/models/generic_combination_strategy.rb b/app/models/generic_combination_strategy.rb new file mode 100644 index 00000000..66c58542 --- /dev/null +++ b/app/models/generic_combination_strategy.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class GenericCombinationStrategy < ApplicationRecord + TYPES = { + and: 1, + or: 2, + }.with_indifferent_access + + belongs_to :generic_mapper + + enum :type, TYPES, prefix: :type +end diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb index e81f9902..cb7fbf5c 100644 --- a/app/models/generic_mapper.rb +++ b/app/models/generic_mapper.rb @@ -2,10 +2,12 @@ class GenericMapper < ApplicationRecord belongs_to :generic_type, inverse_of: :generic_mappers, optional: true - belongs_to :source, class_name: 'DataTypeIdentifier', inverse_of: :generic_mappers belongs_to :runtime, inverse_of: :generic_mappers belongs_to :runtime_parameter_definition, optional: true, inverse_of: :generic_mappers + has_many :sources, class_name: 'DataTypeIdentifier', inverse_of: :generic_mapper + has_many :generic_combination_strategies, class_name: 'GenericCombinationStrategy', inverse_of: :generic_mapper + validates :target, presence: true def to_grpc diff --git a/app/models/json_schemas/data_types/InputTypeRuleConfig.json b/app/models/json_schemas/data_types/InputTypeRuleConfig.json new file mode 100644 index 00000000..1a95921c --- /dev/null +++ b/app/models/json_schemas/data_types/InputTypeRuleConfig.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "https://example.com/schemas/InputTypesRuleConfig.json", + "title": "InputTypesRuleConfig", + "type": "object", + "properties": { + "input_types": { + "type": "array", + "items": { + "type": "object", + "required": ["data_type_identifier", "input_identifier"], + "properties": { + "data_type_identifier": { + "$ref": "../DataTypeIdentifier.json" + }, + "input_identifier": { + "type": "string" + } + } + } + } + } +} diff --git a/app/models/json_schemas/data_types/ReturnTypeRuleConfig.json b/app/models/json_schemas/data_types/ReturnTypeRuleConfig.json new file mode 100644 index 00000000..f0cd02f1 --- /dev/null +++ b/app/models/json_schemas/data_types/ReturnTypeRuleConfig.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "https://example.com/schemas/ReturnTypeRuleConfig.json", + "title": "ReturnTypeRuleConfig", + "type": "object", + "required": ["data_type_identifier"], + "properties": { + "data_type_identifier": { + "$ref": "../DataTypeIdentifier.json" + } + } +} diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb index 471cdd09..313a1495 100644 --- a/app/services/namespaces/projects/flows/create_service.rb +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -134,7 +134,7 @@ def get_data_type_identifier(identifier) mappers = identifier.generic_type.mappers.map do |mapper| GenericMapper.create( generic_mapper_id: mapper.generic_mapper_id, - source: mapper.source, + sources: mapper.sources, target: mapper.target ) end diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb index f384657c..1d97d51b 100644 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb @@ -52,9 +52,10 @@ def execute data_type.parent_type&.tap do |parent_type| logger.debug("Validating parent type: #{parent_type.id} for data type: #{data_type.id}") - DataTypeValidationService.new( + DataTypeIdentifierValidationService.new( current_authentication, flow, + nil, parent_type ).execute end diff --git a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb index 2a93777b..0e14b645 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb @@ -25,25 +25,26 @@ def execute target = generic_mapper.target # Validate the target the identifier gets validated later - unless parameter.generic_type.data_type.generic_keys.has?(target) + unless parameter.node_function.runtime_function.generic_keys.include?(target) t.rollback_and_return!( ServiceResponse.error( - message: "Generic type #{parameter.generic_type.data_type.id} " \ + message: "Runtime function definition #{parameter.node_function.runtime_function} " \ "does not have a generic key for target #{target}", payload: :generic_key_not_found ) ) end - ::DataType::DataTypeIdentifierValidationService.new( - current_authentication, - flow, - parameter.node_function, - generic_mapper.source - ).execute + generic_mapper.sources.each do |source| + Namespaces::Projects::Flows::Validation::DataType::DataTypeIdentifierValidationService.new( + current_authentication, + flow, + parameter.node_function, + source + ).execute + end end - - ServiceResponse.success(message: 'Node function generic mapper validation passed') + nil end end end diff --git a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb index 7a21f859..618d1e42 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb @@ -32,6 +32,15 @@ def execute ) ) end + if parameter.runtime_parameter.runtime != flow.project.primary_runtime + t.rollback_and_return!( + ServiceResponse.error( + message: 'Node parameter runtime does not match the primary runtime of the project', + payload: :runtime_mismatch + ) + ) + end + return if parameter.literal_value.present? if parameter.reference_value.present? diff --git a/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb index 7ff5c3a6..15216b6f 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb @@ -31,6 +31,14 @@ def execute ) ) end + if node_function.runtime_function.runtime != flow.project.primary_runtime + t.rollback_and_return!( + ServiceResponse.error( + message: 'Node function runtime does not match the primary runtime of the project', + payload: :runtime_mismatch + ) + ) + end node_function.next_node&.tap do |next_node| logger.debug("Validating next node function: #{next_node.id} for flow: #{flow.id}") diff --git a/app/services/runtimes/data_types/update_service.rb b/app/services/runtimes/data_types/update_service.rb index 8069b2e5..c159e0b2 100644 --- a/app/services/runtimes/data_types/update_service.rb +++ b/app/services/runtimes/data_types/update_service.rb @@ -49,12 +49,13 @@ def sort_data_types(data_types) sorted_types + unsorted_types # any unsorted types also need to be processed. They might still fail validations end - def update_datatype(data_type, t) + def update_datatype(data_type, _t) db_object = DataType.find_or_initialize_by(runtime: current_runtime, identifier: data_type.identifier) db_object.removed_at = nil db_object.variant = data_type.variant.to_s.downcase if data_type.parent_type_identifier.present? - db_object.parent_type = find_datatype(data_type.parent_type_identifier, t) + # db_object.parent_type = find_datatype(data_type.parent_type_identifier, t) + # TODO: wait for parenttype get properly introduced in grpc end db_object.rules = update_rules(data_type.rules, db_object) db_object.names = update_translations(data_type.name, db_object.names) diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 537d28fd..713197e9 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -74,14 +74,15 @@ def update_mappers(generic_mappers, runtime_function_definition, t) if generic_mapper.is_a? Tucana::Shared::GenericMapper mapper = GenericMapper.create_or_find_by(runtime: current_runtime, target: generic_mapper.target, - source: find_data_type_identifier(generic_mapper.source, - generic_mappers, t)) + sources: generic_mapper.sources.map do |source| + find_data_type_identifier(source, generic_mappers, t) + end) end if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper mapper = FunctionGenericMapper.create_or_find_by( runtime_id: current_runtime.id, runtime_function_definition: runtime_function_definition, - source: find_data_type_identifier(generic_mapper.source, generic_mappers, t), + sources: generic_mapper.sources.map { |source| find_data_type_identifier(source, generic_mappers, t) }, target: generic_mapper.target, parameter_id: generic_mapper.parameter_id ) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 65926c2e..1307dd54 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -28,7 +28,6 @@ def change t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.text :target, null: false - t.references :source, null: false, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } t.references :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :restrict } t.timestamps_with_timezone @@ -41,9 +40,6 @@ def change name: check_constraint_name(:data_type_identifiers, :type, :one_of) create_table :function_generic_mappers do |t| - t.references :source, null: true, - foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } - t.text :target, null: false t.text :parameter_id, null: true @@ -79,5 +75,17 @@ def change remove_reference :function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true + + remove_reference :data_types, :parent_type + add_reference :data_types, :parent_type, null: true, + foreign_key: { to_table: :data_type_identifiers, + on_delete: :restrict } + + add_reference :data_type_identifiers, :generic_mapper, null: true, + foreign_key: { to_table: :generic_mappers, + on_delete: :restrict } + add_reference :data_type_identifiers, :function_generic_mapper, null: true, + foreign_key: { to_table: :function_generic_mappers, + on_delete: :restrict } end end diff --git a/db/migrate/20250530213244_create_generic_combination_strategies.rb b/db/migrate/20250530213244_create_generic_combination_strategies.rb new file mode 100644 index 00000000..9ff39137 --- /dev/null +++ b/db/migrate/20250530213244_create_generic_combination_strategies.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class CreateGenericCombinationStrategies < Code0::ZeroTrack::Database::Migration[1.0] + def change + create_table :generic_combination_strategies do |t| + t.integer :type + t.references :generic_mapper, null: false, foreign_key: { + to_table: :generic_mappers, + on_delete: :cascade, + } + + t.timestamps_with_timezone + end + end +end diff --git a/db/schema_migrations/20250530213244 b/db/schema_migrations/20250530213244 new file mode 100644 index 00000000..94542014 --- /dev/null +++ b/db/schema_migrations/20250530213244 @@ -0,0 +1 @@ +9db64337f6a23ca1adcc3a783141e2d8a5ccd50d347bb0c50056a1f876fab696 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 29eb09c4..2a1d6703 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1,4 +1,23 @@ -CREATE TABLE active_storage_attachments ( +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: active_storage_attachments; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.active_storage_attachments ( id bigint NOT NULL, name character varying NOT NULL, record_type character varying NOT NULL, @@ -8,16 +27,31 @@ CREATE TABLE active_storage_attachments ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE active_storage_attachments_id_seq + +-- +-- Name: active_storage_attachments_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.active_storage_attachments_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE active_storage_attachments_id_seq OWNED BY active_storage_attachments.id; -CREATE TABLE active_storage_blobs ( +-- +-- Name: active_storage_attachments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.active_storage_attachments_id_seq OWNED BY public.active_storage_attachments.id; + + +-- +-- Name: active_storage_blobs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.active_storage_blobs ( id bigint NOT NULL, key character varying NOT NULL, filename character varying NOT NULL, @@ -30,16 +64,31 @@ CREATE TABLE active_storage_blobs ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE active_storage_blobs_id_seq + +-- +-- Name: active_storage_blobs_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.active_storage_blobs_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE active_storage_blobs_id_seq OWNED BY active_storage_blobs.id; -CREATE TABLE active_storage_variant_records ( +-- +-- Name: active_storage_blobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.active_storage_blobs_id_seq OWNED BY public.active_storage_blobs.id; + + +-- +-- Name: active_storage_variant_records; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.active_storage_variant_records ( id bigint NOT NULL, blob_id bigint NOT NULL, variation_digest character varying NOT NULL, @@ -47,16 +96,31 @@ CREATE TABLE active_storage_variant_records ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE active_storage_variant_records_id_seq + +-- +-- Name: active_storage_variant_records_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.active_storage_variant_records_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE active_storage_variant_records_id_seq OWNED BY active_storage_variant_records.id; -CREATE TABLE application_settings ( +-- +-- Name: active_storage_variant_records_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.active_storage_variant_records_id_seq OWNED BY public.active_storage_variant_records.id; + + +-- +-- Name: application_settings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.application_settings ( id bigint NOT NULL, setting integer NOT NULL, value jsonb NOT NULL, @@ -64,23 +128,43 @@ CREATE TABLE application_settings ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE application_settings_id_seq + +-- +-- Name: application_settings_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.application_settings_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE application_settings_id_seq OWNED BY application_settings.id; -CREATE TABLE ar_internal_metadata ( +-- +-- Name: application_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.application_settings_id_seq OWNED BY public.application_settings.id; + + +-- +-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.ar_internal_metadata ( key character varying NOT NULL, value character varying, created_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL ); -CREATE TABLE audit_events ( + +-- +-- Name: audit_events; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.audit_events ( id bigint NOT NULL, author_id bigint NOT NULL, entity_id integer NOT NULL, @@ -94,16 +178,31 @@ CREATE TABLE audit_events ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE audit_events_id_seq + +-- +-- Name: audit_events_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.audit_events_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE audit_events_id_seq OWNED BY audit_events.id; -CREATE TABLE backup_codes ( +-- +-- Name: audit_events_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.audit_events_id_seq OWNED BY public.audit_events.id; + + +-- +-- Name: backup_codes; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.backup_codes ( id bigint NOT NULL, token text NOT NULL, user_id bigint NOT NULL, @@ -112,16 +211,31 @@ CREATE TABLE backup_codes ( CONSTRAINT check_458fe46218 CHECK ((char_length(token) <= 10)) ); -CREATE SEQUENCE backup_codes_id_seq + +-- +-- Name: backup_codes_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.backup_codes_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE backup_codes_id_seq OWNED BY backup_codes.id; -CREATE TABLE data_type_identifiers ( +-- +-- Name: backup_codes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.backup_codes_id_seq OWNED BY public.backup_codes.id; + + +-- +-- Name: data_type_identifiers; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.data_type_identifiers ( id bigint NOT NULL, generic_key text, data_type_id bigint, @@ -129,19 +243,36 @@ CREATE TABLE data_type_identifiers ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, generic_type_id bigint, + generic_mapper_id bigint, + function_generic_mapper_id bigint, CONSTRAINT check_480d44acbd CHECK ((num_nonnulls(generic_key, data_type_id, generic_type_id) = 1)) ); -CREATE SEQUENCE data_type_identifiers_id_seq + +-- +-- Name: data_type_identifiers_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.data_type_identifiers_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE data_type_identifiers_id_seq OWNED BY data_type_identifiers.id; -CREATE TABLE data_type_rules ( +-- +-- Name: data_type_identifiers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.data_type_identifiers_id_seq OWNED BY public.data_type_identifiers.id; + + +-- +-- Name: data_type_rules; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.data_type_rules ( id bigint NOT NULL, data_type_id bigint NOT NULL, variant integer NOT NULL, @@ -150,39 +281,69 @@ CREATE TABLE data_type_rules ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE data_type_rules_id_seq + +-- +-- Name: data_type_rules_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.data_type_rules_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE data_type_rules_id_seq OWNED BY data_type_rules.id; -CREATE TABLE data_types ( +-- +-- Name: data_type_rules_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.data_type_rules_id_seq OWNED BY public.data_type_rules.id; + + +-- +-- Name: data_types; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.data_types ( id bigint NOT NULL, identifier text NOT NULL, variant integer NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, - parent_type_id bigint, runtime_id bigint NOT NULL, removed_at timestamp with time zone, generic_keys text[] DEFAULT '{}'::text[] NOT NULL, + parent_type_id bigint, flows_id bigint, CONSTRAINT check_3a7198812e CHECK ((char_length(identifier) <= 50)) ); -CREATE SEQUENCE data_types_id_seq + +-- +-- Name: data_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.data_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE data_types_id_seq OWNED BY data_types.id; -CREATE TABLE flow_settings ( +-- +-- Name: data_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.data_types_id_seq OWNED BY public.data_types.id; + + +-- +-- Name: flow_settings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.flow_settings ( id bigint NOT NULL, flow_id bigint, flow_setting_id text NOT NULL, @@ -191,16 +352,31 @@ CREATE TABLE flow_settings ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE flow_settings_id_seq + +-- +-- Name: flow_settings_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.flow_settings_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE flow_settings_id_seq OWNED BY flow_settings.id; -CREATE TABLE flow_type_settings ( +-- +-- Name: flow_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.flow_settings_id_seq OWNED BY public.flow_settings.id; + + +-- +-- Name: flow_type_settings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.flow_type_settings ( id bigint NOT NULL, flow_type_id bigint NOT NULL, identifier text NOT NULL, @@ -211,16 +387,31 @@ CREATE TABLE flow_type_settings ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE flow_type_settings_id_seq + +-- +-- Name: flow_type_settings_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.flow_type_settings_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE flow_type_settings_id_seq OWNED BY flow_type_settings.id; -CREATE TABLE flow_types ( +-- +-- Name: flow_type_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.flow_type_settings_id_seq OWNED BY public.flow_type_settings.id; + + +-- +-- Name: flow_types; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.flow_types ( id bigint NOT NULL, runtime_id bigint NOT NULL, identifier text NOT NULL, @@ -232,16 +423,31 @@ CREATE TABLE flow_types ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE flow_types_id_seq + +-- +-- Name: flow_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.flow_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE flow_types_id_seq OWNED BY flow_types.id; -CREATE TABLE flows ( +-- +-- Name: flow_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.flow_types_id_seq OWNED BY public.flow_types.id; + + +-- +-- Name: flows; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.flows ( id bigint NOT NULL, project_id bigint NOT NULL, flow_type_id bigint NOT NULL, @@ -252,16 +458,31 @@ CREATE TABLE flows ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE flows_id_seq + +-- +-- Name: flows_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.flows_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE flows_id_seq OWNED BY flows.id; -CREATE TABLE function_definitions ( +-- +-- Name: flows_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.flows_id_seq OWNED BY public.flows.id; + + +-- +-- Name: function_definitions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.function_definitions ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, @@ -269,18 +490,32 @@ CREATE TABLE function_definitions ( return_type_id bigint ); -CREATE SEQUENCE function_definitions_id_seq + +-- +-- Name: function_definitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.function_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; -CREATE TABLE function_generic_mappers ( +-- +-- Name: function_definitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.function_definitions_id_seq OWNED BY public.function_definitions.id; + + +-- +-- Name: function_generic_mappers; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.function_generic_mappers ( id bigint NOT NULL, - source_id bigint, target text NOT NULL, parameter_id text, runtime_parameter_definition_id bigint, @@ -290,35 +525,96 @@ CREATE TABLE function_generic_mappers ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE function_generic_mappers_id_seq + +-- +-- Name: function_generic_mappers_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.function_generic_mappers_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: function_generic_mappers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.function_generic_mappers_id_seq OWNED BY public.function_generic_mappers.id; + + +-- +-- Name: generic_combination_strategies; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.generic_combination_strategies ( + id bigint NOT NULL, + type integer, + generic_mapper_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + + +-- +-- Name: generic_combination_strategies_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.generic_combination_strategies_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers.id; -CREATE TABLE generic_mappers ( +-- +-- Name: generic_combination_strategies_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.generic_combination_strategies_id_seq OWNED BY public.generic_combination_strategies.id; + + +-- +-- Name: generic_mappers; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.generic_mappers ( id bigint NOT NULL, runtime_id bigint NOT NULL, target text NOT NULL, - source_id bigint NOT NULL, generic_type_id bigint, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE generic_mappers_id_seq + +-- +-- Name: generic_mappers_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.generic_mappers_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; -CREATE TABLE generic_types ( +-- +-- Name: generic_mappers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.generic_mappers_id_seq OWNED BY public.generic_mappers.id; + + +-- +-- Name: generic_types; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.generic_types ( id bigint NOT NULL, runtime_id bigint NOT NULL, data_type_id bigint NOT NULL, @@ -326,16 +622,31 @@ CREATE TABLE generic_types ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE generic_types_id_seq + +-- +-- Name: generic_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.generic_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE generic_types_id_seq OWNED BY generic_types.id; -CREATE TABLE good_job_batches ( +-- +-- Name: generic_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.generic_types_id_seq OWNED BY public.generic_types.id; + + +-- +-- Name: good_job_batches; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.good_job_batches ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -352,7 +663,12 @@ CREATE TABLE good_job_batches ( jobs_finished_at timestamp with time zone ); -CREATE TABLE good_job_executions ( + +-- +-- Name: good_job_executions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.good_job_executions ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -369,7 +685,12 @@ CREATE TABLE good_job_executions ( duration interval ); -CREATE TABLE good_job_processes ( + +-- +-- Name: good_job_processes; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.good_job_processes ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -377,7 +698,12 @@ CREATE TABLE good_job_processes ( lock_type smallint ); -CREATE TABLE good_job_settings ( + +-- +-- Name: good_job_settings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.good_job_settings ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -385,7 +711,12 @@ CREATE TABLE good_job_settings ( value jsonb ); -CREATE TABLE good_jobs ( + +-- +-- Name: good_jobs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.good_jobs ( id uuid DEFAULT gen_random_uuid() NOT NULL, queue_name text, priority integer, @@ -412,7 +743,12 @@ CREATE TABLE good_jobs ( locked_at timestamp with time zone ); -CREATE TABLE namespace_licenses ( + +-- +-- Name: namespace_licenses; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespace_licenses ( id bigint NOT NULL, data text NOT NULL, created_at timestamp with time zone NOT NULL, @@ -420,16 +756,31 @@ CREATE TABLE namespace_licenses ( namespace_id bigint NOT NULL ); -CREATE SEQUENCE namespace_licenses_id_seq + +-- +-- Name: namespace_licenses_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespace_licenses_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespace_licenses_id_seq OWNED BY namespace_licenses.id; -CREATE TABLE namespace_member_roles ( +-- +-- Name: namespace_licenses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespace_licenses_id_seq OWNED BY public.namespace_licenses.id; + + +-- +-- Name: namespace_member_roles; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespace_member_roles ( id bigint NOT NULL, role_id bigint NOT NULL, member_id bigint NOT NULL, @@ -437,16 +788,31 @@ CREATE TABLE namespace_member_roles ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE namespace_member_roles_id_seq + +-- +-- Name: namespace_member_roles_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespace_member_roles_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespace_member_roles_id_seq OWNED BY namespace_member_roles.id; -CREATE TABLE namespace_members ( +-- +-- Name: namespace_member_roles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespace_member_roles_id_seq OWNED BY public.namespace_member_roles.id; + + +-- +-- Name: namespace_members; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespace_members ( id bigint NOT NULL, user_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, @@ -454,16 +820,31 @@ CREATE TABLE namespace_members ( namespace_id bigint NOT NULL ); -CREATE SEQUENCE namespace_members_id_seq + +-- +-- Name: namespace_members_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespace_members_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespace_members_id_seq OWNED BY namespace_members.id; -CREATE TABLE namespace_project_runtime_assignments ( +-- +-- Name: namespace_members_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespace_members_id_seq OWNED BY public.namespace_members.id; + + +-- +-- Name: namespace_project_runtime_assignments; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespace_project_runtime_assignments ( id bigint NOT NULL, runtime_id bigint NOT NULL, namespace_project_id bigint NOT NULL, @@ -471,16 +852,31 @@ CREATE TABLE namespace_project_runtime_assignments ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE namespace_project_runtime_assignments_id_seq + +-- +-- Name: namespace_project_runtime_assignments_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespace_project_runtime_assignments_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespace_project_runtime_assignments_id_seq OWNED BY namespace_project_runtime_assignments.id; -CREATE TABLE namespace_projects ( +-- +-- Name: namespace_project_runtime_assignments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespace_project_runtime_assignments_id_seq OWNED BY public.namespace_project_runtime_assignments.id; + + +-- +-- Name: namespace_projects; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespace_projects ( id bigint NOT NULL, name text NOT NULL, description text DEFAULT ''::text NOT NULL, @@ -492,16 +888,31 @@ CREATE TABLE namespace_projects ( CONSTRAINT check_a77bf7c685 CHECK ((char_length(description) <= 500)) ); -CREATE SEQUENCE namespace_projects_id_seq + +-- +-- Name: namespace_projects_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespace_projects_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespace_projects_id_seq OWNED BY namespace_projects.id; -CREATE TABLE namespace_role_abilities ( +-- +-- Name: namespace_projects_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespace_projects_id_seq OWNED BY public.namespace_projects.id; + + +-- +-- Name: namespace_role_abilities; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespace_role_abilities ( id bigint NOT NULL, ability integer NOT NULL, created_at timestamp with time zone NOT NULL, @@ -509,16 +920,31 @@ CREATE TABLE namespace_role_abilities ( namespace_role_id bigint NOT NULL ); -CREATE SEQUENCE namespace_role_abilities_id_seq + +-- +-- Name: namespace_role_abilities_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespace_role_abilities_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespace_role_abilities_id_seq OWNED BY namespace_role_abilities.id; -CREATE TABLE namespace_role_project_assignments ( +-- +-- Name: namespace_role_abilities_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespace_role_abilities_id_seq OWNED BY public.namespace_role_abilities.id; + + +-- +-- Name: namespace_role_project_assignments; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespace_role_project_assignments ( id bigint NOT NULL, role_id bigint NOT NULL, project_id bigint NOT NULL, @@ -526,16 +952,31 @@ CREATE TABLE namespace_role_project_assignments ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE namespace_role_project_assignments_id_seq + +-- +-- Name: namespace_role_project_assignments_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespace_role_project_assignments_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespace_role_project_assignments_id_seq OWNED BY namespace_role_project_assignments.id; -CREATE TABLE namespace_roles ( +-- +-- Name: namespace_role_project_assignments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespace_role_project_assignments_id_seq OWNED BY public.namespace_role_project_assignments.id; + + +-- +-- Name: namespace_roles; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespace_roles ( id bigint NOT NULL, name text NOT NULL, created_at timestamp with time zone NOT NULL, @@ -543,16 +984,31 @@ CREATE TABLE namespace_roles ( namespace_id bigint NOT NULL ); -CREATE SEQUENCE namespace_roles_id_seq + +-- +-- Name: namespace_roles_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespace_roles_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespace_roles_id_seq OWNED BY namespace_roles.id; -CREATE TABLE namespaces ( +-- +-- Name: namespace_roles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespace_roles_id_seq OWNED BY public.namespace_roles.id; + + +-- +-- Name: namespaces; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.namespaces ( id bigint NOT NULL, parent_type character varying NOT NULL, parent_id bigint NOT NULL, @@ -560,16 +1016,31 @@ CREATE TABLE namespaces ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE namespaces_id_seq + +-- +-- Name: namespaces_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.namespaces_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE namespaces_id_seq OWNED BY namespaces.id; -CREATE TABLE node_functions ( +-- +-- Name: namespaces_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.namespaces_id_seq OWNED BY public.namespaces.id; + + +-- +-- Name: node_functions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.node_functions ( id bigint NOT NULL, runtime_function_id bigint NOT NULL, next_node_id bigint, @@ -577,16 +1048,31 @@ CREATE TABLE node_functions ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE node_functions_id_seq + +-- +-- Name: node_functions_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.node_functions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE node_functions_id_seq OWNED BY node_functions.id; -CREATE TABLE node_parameters ( +-- +-- Name: node_functions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.node_functions_id_seq OWNED BY public.node_functions.id; + + +-- +-- Name: node_parameters; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.node_parameters ( id bigint NOT NULL, runtime_parameter_id bigint NOT NULL, node_function_id bigint NOT NULL, @@ -598,16 +1084,31 @@ CREATE TABLE node_parameters ( CONSTRAINT check_fdac0ea550 CHECK ((num_nonnulls(literal_value, reference_value_id, function_value_id) = 1)) ); -CREATE SEQUENCE node_parameters_id_seq + +-- +-- Name: node_parameters_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.node_parameters_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE node_parameters_id_seq OWNED BY node_parameters.id; -CREATE TABLE organizations ( +-- +-- Name: node_parameters_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.node_parameters_id_seq OWNED BY public.node_parameters.id; + + +-- +-- Name: organizations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.organizations ( id bigint NOT NULL, name text NOT NULL, created_at timestamp with time zone NOT NULL, @@ -615,16 +1116,31 @@ CREATE TABLE organizations ( CONSTRAINT check_d130d769e0 CHECK ((char_length(name) <= 50)) ); -CREATE SEQUENCE organizations_id_seq + +-- +-- Name: organizations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.organizations_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE organizations_id_seq OWNED BY organizations.id; -CREATE TABLE parameter_definitions ( +-- +-- Name: organizations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.organizations_id_seq OWNED BY public.organizations.id; + + +-- +-- Name: parameter_definitions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.parameter_definitions ( id bigint NOT NULL, runtime_parameter_definition_id bigint NOT NULL, default_value jsonb, @@ -633,16 +1149,31 @@ CREATE TABLE parameter_definitions ( data_type_id bigint ); -CREATE SEQUENCE parameter_definitions_id_seq + +-- +-- Name: parameter_definitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.parameter_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE parameter_definitions_id_seq OWNED BY parameter_definitions.id; -CREATE TABLE reference_paths ( +-- +-- Name: parameter_definitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.parameter_definitions_id_seq OWNED BY public.parameter_definitions.id; + + +-- +-- Name: reference_paths; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.reference_paths ( id bigint NOT NULL, path text, array_index integer, @@ -651,16 +1182,31 @@ CREATE TABLE reference_paths ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE reference_paths_id_seq + +-- +-- Name: reference_paths_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.reference_paths_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE reference_paths_id_seq OWNED BY reference_paths.id; -CREATE TABLE reference_values ( +-- +-- Name: reference_paths_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.reference_paths_id_seq OWNED BY public.reference_paths.id; + + +-- +-- Name: reference_values; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.reference_values ( id bigint NOT NULL, data_type_identifier_id bigint NOT NULL, primary_level integer NOT NULL, @@ -670,16 +1216,31 @@ CREATE TABLE reference_values ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE reference_values_id_seq + +-- +-- Name: reference_values_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.reference_values_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE reference_values_id_seq OWNED BY reference_values.id; -CREATE TABLE runtime_function_definition_error_types ( +-- +-- Name: reference_values_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.reference_values_id_seq OWNED BY public.reference_values.id; + + +-- +-- Name: runtime_function_definition_error_types; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.runtime_function_definition_error_types ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, data_type_id bigint NOT NULL, @@ -687,16 +1248,31 @@ CREATE TABLE runtime_function_definition_error_types ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE runtime_function_definition_error_types_id_seq + +-- +-- Name: runtime_function_definition_error_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.runtime_function_definition_error_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE runtime_function_definition_error_types_id_seq OWNED BY runtime_function_definition_error_types.id; -CREATE TABLE runtime_function_definitions ( +-- +-- Name: runtime_function_definition_error_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.runtime_function_definition_error_types_id_seq OWNED BY public.runtime_function_definition_error_types.id; + + +-- +-- Name: runtime_function_definitions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.runtime_function_definitions ( id bigint NOT NULL, runtime_id bigint NOT NULL, runtime_name text NOT NULL, @@ -708,16 +1284,31 @@ CREATE TABLE runtime_function_definitions ( CONSTRAINT check_fe8fff4f27 CHECK ((char_length(runtime_name) <= 50)) ); -CREATE SEQUENCE runtime_function_definitions_id_seq + +-- +-- Name: runtime_function_definitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.runtime_function_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE runtime_function_definitions_id_seq OWNED BY runtime_function_definitions.id; -CREATE TABLE runtime_parameter_definitions ( +-- +-- Name: runtime_function_definitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.runtime_function_definitions_id_seq OWNED BY public.runtime_function_definitions.id; + + +-- +-- Name: runtime_parameter_definitions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.runtime_parameter_definitions ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, runtime_name text NOT NULL, @@ -729,16 +1320,31 @@ CREATE TABLE runtime_parameter_definitions ( CONSTRAINT check_c1156ce358 CHECK ((char_length(runtime_name) <= 50)) ); -CREATE SEQUENCE runtime_parameter_definitions_id_seq + +-- +-- Name: runtime_parameter_definitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.runtime_parameter_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE runtime_parameter_definitions_id_seq OWNED BY runtime_parameter_definitions.id; -CREATE TABLE runtimes ( +-- +-- Name: runtime_parameter_definitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.runtime_parameter_definitions_id_seq OWNED BY public.runtime_parameter_definitions.id; + + +-- +-- Name: runtimes; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.runtimes ( id bigint NOT NULL, name text NOT NULL, description text DEFAULT ''::text NOT NULL, @@ -751,20 +1357,40 @@ CREATE TABLE runtimes ( CONSTRAINT check_f3c2ba8db3 CHECK ((char_length(description) <= 500)) ); -CREATE SEQUENCE runtimes_id_seq + +-- +-- Name: runtimes_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.runtimes_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE runtimes_id_seq OWNED BY runtimes.id; -CREATE TABLE schema_migrations ( +-- +-- Name: runtimes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.runtimes_id_seq OWNED BY public.runtimes.id; + + +-- +-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.schema_migrations ( version character varying NOT NULL ); -CREATE TABLE translations ( + +-- +-- Name: translations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.translations ( id bigint NOT NULL, code text NOT NULL, content text NOT NULL, @@ -775,16 +1401,31 @@ CREATE TABLE translations ( purpose text ); -CREATE SEQUENCE translations_id_seq + +-- +-- Name: translations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.translations_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE translations_id_seq OWNED BY translations.id; -CREATE TABLE user_identities ( +-- +-- Name: translations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.translations_id_seq OWNED BY public.translations.id; + + +-- +-- Name: user_identities; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_identities ( id bigint NOT NULL, user_id bigint NOT NULL, provider_id text NOT NULL, @@ -793,16 +1434,31 @@ CREATE TABLE user_identities ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE user_identities_id_seq + +-- +-- Name: user_identities_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.user_identities_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE user_identities_id_seq OWNED BY user_identities.id; -CREATE TABLE user_sessions ( +-- +-- Name: user_identities_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.user_identities_id_seq OWNED BY public.user_identities.id; + + +-- +-- Name: user_sessions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_sessions ( id bigint NOT NULL, user_id bigint NOT NULL, token text NOT NULL, @@ -811,16 +1467,31 @@ CREATE TABLE user_sessions ( updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE user_sessions_id_seq + +-- +-- Name: user_sessions_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.user_sessions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE user_sessions_id_seq OWNED BY user_sessions.id; -CREATE TABLE users ( +-- +-- Name: user_sessions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.user_sessions_id_seq OWNED BY public.user_sessions.id; + + +-- +-- Name: users; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.users ( id bigint NOT NULL, username text, email text, @@ -837,615 +1508,1895 @@ CREATE TABLE users ( CONSTRAINT check_d4bc21c175 CHECK ((char_length(firstname) <= 50)) ); -CREATE SEQUENCE users_id_seq + +-- +-- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.users_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE users_id_seq OWNED BY users.id; -ALTER TABLE ONLY active_storage_attachments ALTER COLUMN id SET DEFAULT nextval('active_storage_attachments_id_seq'::regclass); +-- +-- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id; + + +-- +-- Name: active_storage_attachments id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_attachments ALTER COLUMN id SET DEFAULT nextval('public.active_storage_attachments_id_seq'::regclass); + + +-- +-- Name: active_storage_blobs id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_blobs ALTER COLUMN id SET DEFAULT nextval('public.active_storage_blobs_id_seq'::regclass); + + +-- +-- Name: active_storage_variant_records id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_variant_records ALTER COLUMN id SET DEFAULT nextval('public.active_storage_variant_records_id_seq'::regclass); + + +-- +-- Name: application_settings id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.application_settings ALTER COLUMN id SET DEFAULT nextval('public.application_settings_id_seq'::regclass); + + +-- +-- Name: audit_events id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.audit_events ALTER COLUMN id SET DEFAULT nextval('public.audit_events_id_seq'::regclass); + + +-- +-- Name: backup_codes id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.backup_codes ALTER COLUMN id SET DEFAULT nextval('public.backup_codes_id_seq'::regclass); + + +-- +-- Name: data_type_identifiers id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.data_type_identifiers ALTER COLUMN id SET DEFAULT nextval('public.data_type_identifiers_id_seq'::regclass); + + +-- +-- Name: data_type_rules id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.data_type_rules ALTER COLUMN id SET DEFAULT nextval('public.data_type_rules_id_seq'::regclass); + + +-- +-- Name: data_types id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.data_types ALTER COLUMN id SET DEFAULT nextval('public.data_types_id_seq'::regclass); + + +-- +-- Name: flow_settings id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flow_settings ALTER COLUMN id SET DEFAULT nextval('public.flow_settings_id_seq'::regclass); + + +-- +-- Name: flow_type_settings id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flow_type_settings ALTER COLUMN id SET DEFAULT nextval('public.flow_type_settings_id_seq'::regclass); + + +-- +-- Name: flow_types id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flow_types ALTER COLUMN id SET DEFAULT nextval('public.flow_types_id_seq'::regclass); + + +-- +-- Name: flows id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flows ALTER COLUMN id SET DEFAULT nextval('public.flows_id_seq'::regclass); + + +-- +-- Name: function_definitions id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.function_definitions ALTER COLUMN id SET DEFAULT nextval('public.function_definitions_id_seq'::regclass); + + +-- +-- Name: function_generic_mappers id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.function_generic_mappers ALTER COLUMN id SET DEFAULT nextval('public.function_generic_mappers_id_seq'::regclass); + + +-- +-- Name: generic_combination_strategies id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generic_combination_strategies ALTER COLUMN id SET DEFAULT nextval('public.generic_combination_strategies_id_seq'::regclass); + -ALTER TABLE ONLY active_storage_blobs ALTER COLUMN id SET DEFAULT nextval('active_storage_blobs_id_seq'::regclass); +-- +-- Name: generic_mappers id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY active_storage_variant_records ALTER COLUMN id SET DEFAULT nextval('active_storage_variant_records_id_seq'::regclass); +ALTER TABLE ONLY public.generic_mappers ALTER COLUMN id SET DEFAULT nextval('public.generic_mappers_id_seq'::regclass); -ALTER TABLE ONLY application_settings ALTER COLUMN id SET DEFAULT nextval('application_settings_id_seq'::regclass); -ALTER TABLE ONLY audit_events ALTER COLUMN id SET DEFAULT nextval('audit_events_id_seq'::regclass); +-- +-- Name: generic_types id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY backup_codes ALTER COLUMN id SET DEFAULT nextval('backup_codes_id_seq'::regclass); +ALTER TABLE ONLY public.generic_types ALTER COLUMN id SET DEFAULT nextval('public.generic_types_id_seq'::regclass); -ALTER TABLE ONLY data_type_identifiers ALTER COLUMN id SET DEFAULT nextval('data_type_identifiers_id_seq'::regclass); -ALTER TABLE ONLY data_type_rules ALTER COLUMN id SET DEFAULT nextval('data_type_rules_id_seq'::regclass); +-- +-- Name: namespace_licenses id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY data_types ALTER COLUMN id SET DEFAULT nextval('data_types_id_seq'::regclass); +ALTER TABLE ONLY public.namespace_licenses ALTER COLUMN id SET DEFAULT nextval('public.namespace_licenses_id_seq'::regclass); -ALTER TABLE ONLY flow_settings ALTER COLUMN id SET DEFAULT nextval('flow_settings_id_seq'::regclass); -ALTER TABLE ONLY flow_type_settings ALTER COLUMN id SET DEFAULT nextval('flow_type_settings_id_seq'::regclass); +-- +-- Name: namespace_member_roles id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY flow_types ALTER COLUMN id SET DEFAULT nextval('flow_types_id_seq'::regclass); +ALTER TABLE ONLY public.namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('public.namespace_member_roles_id_seq'::regclass); -ALTER TABLE ONLY flows ALTER COLUMN id SET DEFAULT nextval('flows_id_seq'::regclass); -ALTER TABLE ONLY function_definitions ALTER COLUMN id SET DEFAULT nextval('function_definitions_id_seq'::regclass); +-- +-- Name: namespace_members id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY function_generic_mappers ALTER COLUMN id SET DEFAULT nextval('function_generic_mappers_id_seq'::regclass); +ALTER TABLE ONLY public.namespace_members ALTER COLUMN id SET DEFAULT nextval('public.namespace_members_id_seq'::regclass); -ALTER TABLE ONLY generic_mappers ALTER COLUMN id SET DEFAULT nextval('generic_mappers_id_seq'::regclass); -ALTER TABLE ONLY generic_types ALTER COLUMN id SET DEFAULT nextval('generic_types_id_seq'::regclass); +-- +-- Name: namespace_project_runtime_assignments id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY namespace_licenses ALTER COLUMN id SET DEFAULT nextval('namespace_licenses_id_seq'::regclass); +ALTER TABLE ONLY public.namespace_project_runtime_assignments ALTER COLUMN id SET DEFAULT nextval('public.namespace_project_runtime_assignments_id_seq'::regclass); -ALTER TABLE ONLY namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('namespace_member_roles_id_seq'::regclass); -ALTER TABLE ONLY namespace_members ALTER COLUMN id SET DEFAULT nextval('namespace_members_id_seq'::regclass); +-- +-- Name: namespace_projects id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY namespace_project_runtime_assignments ALTER COLUMN id SET DEFAULT nextval('namespace_project_runtime_assignments_id_seq'::regclass); +ALTER TABLE ONLY public.namespace_projects ALTER COLUMN id SET DEFAULT nextval('public.namespace_projects_id_seq'::regclass); -ALTER TABLE ONLY namespace_projects ALTER COLUMN id SET DEFAULT nextval('namespace_projects_id_seq'::regclass); -ALTER TABLE ONLY namespace_role_abilities ALTER COLUMN id SET DEFAULT nextval('namespace_role_abilities_id_seq'::regclass); +-- +-- Name: namespace_role_abilities id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY namespace_role_project_assignments ALTER COLUMN id SET DEFAULT nextval('namespace_role_project_assignments_id_seq'::regclass); +ALTER TABLE ONLY public.namespace_role_abilities ALTER COLUMN id SET DEFAULT nextval('public.namespace_role_abilities_id_seq'::regclass); -ALTER TABLE ONLY namespace_roles ALTER COLUMN id SET DEFAULT nextval('namespace_roles_id_seq'::regclass); -ALTER TABLE ONLY namespaces ALTER COLUMN id SET DEFAULT nextval('namespaces_id_seq'::regclass); +-- +-- Name: namespace_role_project_assignments id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY node_functions ALTER COLUMN id SET DEFAULT nextval('node_functions_id_seq'::regclass); +ALTER TABLE ONLY public.namespace_role_project_assignments ALTER COLUMN id SET DEFAULT nextval('public.namespace_role_project_assignments_id_seq'::regclass); -ALTER TABLE ONLY node_parameters ALTER COLUMN id SET DEFAULT nextval('node_parameters_id_seq'::regclass); -ALTER TABLE ONLY organizations ALTER COLUMN id SET DEFAULT nextval('organizations_id_seq'::regclass); +-- +-- Name: namespace_roles id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY parameter_definitions ALTER COLUMN id SET DEFAULT nextval('parameter_definitions_id_seq'::regclass); +ALTER TABLE ONLY public.namespace_roles ALTER COLUMN id SET DEFAULT nextval('public.namespace_roles_id_seq'::regclass); -ALTER TABLE ONLY reference_paths ALTER COLUMN id SET DEFAULT nextval('reference_paths_id_seq'::regclass); -ALTER TABLE ONLY reference_values ALTER COLUMN id SET DEFAULT nextval('reference_values_id_seq'::regclass); +-- +-- Name: namespaces id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY runtime_function_definition_error_types ALTER COLUMN id SET DEFAULT nextval('runtime_function_definition_error_types_id_seq'::regclass); +ALTER TABLE ONLY public.namespaces ALTER COLUMN id SET DEFAULT nextval('public.namespaces_id_seq'::regclass); -ALTER TABLE ONLY runtime_function_definitions ALTER COLUMN id SET DEFAULT nextval('runtime_function_definitions_id_seq'::regclass); -ALTER TABLE ONLY runtime_parameter_definitions ALTER COLUMN id SET DEFAULT nextval('runtime_parameter_definitions_id_seq'::regclass); +-- +-- Name: node_functions id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY runtimes ALTER COLUMN id SET DEFAULT nextval('runtimes_id_seq'::regclass); +ALTER TABLE ONLY public.node_functions ALTER COLUMN id SET DEFAULT nextval('public.node_functions_id_seq'::regclass); -ALTER TABLE ONLY translations ALTER COLUMN id SET DEFAULT nextval('translations_id_seq'::regclass); -ALTER TABLE ONLY user_identities ALTER COLUMN id SET DEFAULT nextval('user_identities_id_seq'::regclass); +-- +-- Name: node_parameters id; Type: DEFAULT; Schema: public; Owner: - +-- -ALTER TABLE ONLY user_sessions ALTER COLUMN id SET DEFAULT nextval('user_sessions_id_seq'::regclass); +ALTER TABLE ONLY public.node_parameters ALTER COLUMN id SET DEFAULT nextval('public.node_parameters_id_seq'::regclass); -ALTER TABLE ONLY users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass); -ALTER TABLE ONLY active_storage_attachments +-- +-- Name: organizations id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.organizations ALTER COLUMN id SET DEFAULT nextval('public.organizations_id_seq'::regclass); + + +-- +-- Name: parameter_definitions id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.parameter_definitions ALTER COLUMN id SET DEFAULT nextval('public.parameter_definitions_id_seq'::regclass); + + +-- +-- Name: reference_paths id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.reference_paths ALTER COLUMN id SET DEFAULT nextval('public.reference_paths_id_seq'::regclass); + + +-- +-- Name: reference_values id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.reference_values ALTER COLUMN id SET DEFAULT nextval('public.reference_values_id_seq'::regclass); + + +-- +-- Name: runtime_function_definition_error_types id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtime_function_definition_error_types ALTER COLUMN id SET DEFAULT nextval('public.runtime_function_definition_error_types_id_seq'::regclass); + + +-- +-- Name: runtime_function_definitions id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtime_function_definitions ALTER COLUMN id SET DEFAULT nextval('public.runtime_function_definitions_id_seq'::regclass); + + +-- +-- Name: runtime_parameter_definitions id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtime_parameter_definitions ALTER COLUMN id SET DEFAULT nextval('public.runtime_parameter_definitions_id_seq'::regclass); + + +-- +-- Name: runtimes id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtimes ALTER COLUMN id SET DEFAULT nextval('public.runtimes_id_seq'::regclass); + + +-- +-- Name: translations id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.translations ALTER COLUMN id SET DEFAULT nextval('public.translations_id_seq'::regclass); + + +-- +-- Name: user_identities id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_identities ALTER COLUMN id SET DEFAULT nextval('public.user_identities_id_seq'::regclass); + + +-- +-- Name: user_sessions id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_sessions ALTER COLUMN id SET DEFAULT nextval('public.user_sessions_id_seq'::regclass); + + +-- +-- Name: users id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.users ALTER COLUMN id SET DEFAULT nextval('public.users_id_seq'::regclass); + + +-- +-- Name: active_storage_attachments active_storage_attachments_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_attachments ADD CONSTRAINT active_storage_attachments_pkey PRIMARY KEY (id); -ALTER TABLE ONLY active_storage_blobs + +-- +-- Name: active_storage_blobs active_storage_blobs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_blobs ADD CONSTRAINT active_storage_blobs_pkey PRIMARY KEY (id); -ALTER TABLE ONLY active_storage_variant_records + +-- +-- Name: active_storage_variant_records active_storage_variant_records_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_variant_records ADD CONSTRAINT active_storage_variant_records_pkey PRIMARY KEY (id); -ALTER TABLE ONLY application_settings + +-- +-- Name: application_settings application_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.application_settings ADD CONSTRAINT application_settings_pkey PRIMARY KEY (id); -ALTER TABLE ONLY ar_internal_metadata + +-- +-- Name: ar_internal_metadata ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.ar_internal_metadata ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key); -ALTER TABLE ONLY audit_events + +-- +-- Name: audit_events audit_events_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.audit_events ADD CONSTRAINT audit_events_pkey PRIMARY KEY (id); -ALTER TABLE ONLY backup_codes + +-- +-- Name: backup_codes backup_codes_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.backup_codes ADD CONSTRAINT backup_codes_pkey PRIMARY KEY (id); -ALTER TABLE ONLY data_type_identifiers + +-- +-- Name: data_type_identifiers data_type_identifiers_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.data_type_identifiers ADD CONSTRAINT data_type_identifiers_pkey PRIMARY KEY (id); -ALTER TABLE ONLY data_type_rules + +-- +-- Name: data_type_rules data_type_rules_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.data_type_rules ADD CONSTRAINT data_type_rules_pkey PRIMARY KEY (id); -ALTER TABLE ONLY data_types + +-- +-- Name: data_types data_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.data_types ADD CONSTRAINT data_types_pkey PRIMARY KEY (id); -ALTER TABLE ONLY flow_settings + +-- +-- Name: flow_settings flow_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flow_settings ADD CONSTRAINT flow_settings_pkey PRIMARY KEY (id); -ALTER TABLE ONLY flow_type_settings + +-- +-- Name: flow_type_settings flow_type_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flow_type_settings ADD CONSTRAINT flow_type_settings_pkey PRIMARY KEY (id); -ALTER TABLE ONLY flow_types + +-- +-- Name: flow_types flow_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flow_types ADD CONSTRAINT flow_types_pkey PRIMARY KEY (id); -ALTER TABLE ONLY flows + +-- +-- Name: flows flows_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flows ADD CONSTRAINT flows_pkey PRIMARY KEY (id); -ALTER TABLE ONLY function_definitions + +-- +-- Name: function_definitions function_definitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.function_definitions ADD CONSTRAINT function_definitions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY function_generic_mappers + +-- +-- Name: function_generic_mappers function_generic_mappers_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.function_generic_mappers ADD CONSTRAINT function_generic_mappers_pkey PRIMARY KEY (id); -ALTER TABLE ONLY generic_mappers + +-- +-- Name: generic_combination_strategies generic_combination_strategies_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generic_combination_strategies + ADD CONSTRAINT generic_combination_strategies_pkey PRIMARY KEY (id); + + +-- +-- Name: generic_mappers generic_mappers_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generic_mappers ADD CONSTRAINT generic_mappers_pkey PRIMARY KEY (id); -ALTER TABLE ONLY generic_types + +-- +-- Name: generic_types generic_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generic_types ADD CONSTRAINT generic_types_pkey PRIMARY KEY (id); -ALTER TABLE ONLY good_job_batches + +-- +-- Name: good_job_batches good_job_batches_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.good_job_batches ADD CONSTRAINT good_job_batches_pkey PRIMARY KEY (id); -ALTER TABLE ONLY good_job_executions + +-- +-- Name: good_job_executions good_job_executions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.good_job_executions ADD CONSTRAINT good_job_executions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY good_job_processes + +-- +-- Name: good_job_processes good_job_processes_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.good_job_processes ADD CONSTRAINT good_job_processes_pkey PRIMARY KEY (id); -ALTER TABLE ONLY good_job_settings + +-- +-- Name: good_job_settings good_job_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.good_job_settings ADD CONSTRAINT good_job_settings_pkey PRIMARY KEY (id); -ALTER TABLE ONLY good_jobs + +-- +-- Name: good_jobs good_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.good_jobs ADD CONSTRAINT good_jobs_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_licenses + +-- +-- Name: namespace_licenses namespace_licenses_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_licenses ADD CONSTRAINT namespace_licenses_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_member_roles + +-- +-- Name: namespace_member_roles namespace_member_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_member_roles ADD CONSTRAINT namespace_member_roles_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_members + +-- +-- Name: namespace_members namespace_members_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_members ADD CONSTRAINT namespace_members_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_project_runtime_assignments + +-- +-- Name: namespace_project_runtime_assignments namespace_project_runtime_assignments_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_project_runtime_assignments ADD CONSTRAINT namespace_project_runtime_assignments_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_projects + +-- +-- Name: namespace_projects namespace_projects_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_projects ADD CONSTRAINT namespace_projects_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_role_abilities + +-- +-- Name: namespace_role_abilities namespace_role_abilities_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_role_abilities ADD CONSTRAINT namespace_role_abilities_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_role_project_assignments + +-- +-- Name: namespace_role_project_assignments namespace_role_project_assignments_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_role_project_assignments ADD CONSTRAINT namespace_role_project_assignments_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespace_roles + +-- +-- Name: namespace_roles namespace_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_roles ADD CONSTRAINT namespace_roles_pkey PRIMARY KEY (id); -ALTER TABLE ONLY namespaces + +-- +-- Name: namespaces namespaces_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespaces ADD CONSTRAINT namespaces_pkey PRIMARY KEY (id); -ALTER TABLE ONLY node_functions + +-- +-- Name: node_functions node_functions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.node_functions ADD CONSTRAINT node_functions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY node_parameters + +-- +-- Name: node_parameters node_parameters_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.node_parameters ADD CONSTRAINT node_parameters_pkey PRIMARY KEY (id); -ALTER TABLE ONLY organizations + +-- +-- Name: organizations organizations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.organizations ADD CONSTRAINT organizations_pkey PRIMARY KEY (id); -ALTER TABLE ONLY parameter_definitions + +-- +-- Name: parameter_definitions parameter_definitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.parameter_definitions ADD CONSTRAINT parameter_definitions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY reference_paths + +-- +-- Name: reference_paths reference_paths_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.reference_paths ADD CONSTRAINT reference_paths_pkey PRIMARY KEY (id); -ALTER TABLE ONLY reference_values + +-- +-- Name: reference_values reference_values_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.reference_values ADD CONSTRAINT reference_values_pkey PRIMARY KEY (id); -ALTER TABLE ONLY runtime_function_definition_error_types + +-- +-- Name: runtime_function_definition_error_types runtime_function_definition_error_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtime_function_definition_error_types ADD CONSTRAINT runtime_function_definition_error_types_pkey PRIMARY KEY (id); -ALTER TABLE ONLY runtime_function_definitions + +-- +-- Name: runtime_function_definitions runtime_function_definitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtime_function_definitions ADD CONSTRAINT runtime_function_definitions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY runtime_parameter_definitions + +-- +-- Name: runtime_parameter_definitions runtime_parameter_definitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtime_parameter_definitions ADD CONSTRAINT runtime_parameter_definitions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY runtimes + +-- +-- Name: runtimes runtimes_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtimes ADD CONSTRAINT runtimes_pkey PRIMARY KEY (id); -ALTER TABLE ONLY schema_migrations + +-- +-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.schema_migrations ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); -ALTER TABLE ONLY translations + +-- +-- Name: translations translations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.translations ADD CONSTRAINT translations_pkey PRIMARY KEY (id); -ALTER TABLE ONLY user_identities + +-- +-- Name: user_identities user_identities_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_identities ADD CONSTRAINT user_identities_pkey PRIMARY KEY (id); -ALTER TABLE ONLY user_sessions + +-- +-- Name: user_sessions user_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_sessions ADD CONSTRAINT user_sessions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY users + +-- +-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.users ADD CONSTRAINT users_pkey PRIMARY KEY (id); -CREATE UNIQUE INDEX idx_on_namespace_role_id_ability_a092da8841 ON namespace_role_abilities USING btree (namespace_role_id, ability); -CREATE UNIQUE INDEX idx_on_role_id_project_id_5d4b5917dc ON namespace_role_project_assignments USING btree (role_id, project_id); +-- +-- Name: idx_on_namespace_role_id_ability_a092da8841; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX idx_on_namespace_role_id_ability_a092da8841 ON public.namespace_role_abilities USING btree (namespace_role_id, ability); + + +-- +-- Name: idx_on_role_id_project_id_5d4b5917dc; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX idx_on_role_id_project_id_5d4b5917dc ON public.namespace_role_project_assignments USING btree (role_id, project_id); + + +-- +-- Name: idx_on_runtime_function_definition_id_data_type_id_b6aa8fe066; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_data_type_id_b6aa8fe066 ON public.runtime_function_definition_error_types USING btree (runtime_function_definition_id, data_type_id); + + +-- +-- Name: idx_on_runtime_function_definition_id_f0f8f95496; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON public.function_generic_mappers USING btree (runtime_function_definition_id); + + +-- +-- Name: idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON public.runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); + + +-- +-- Name: idx_on_runtime_id_namespace_project_id_bc3c86cc70; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON public.namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); + + +-- +-- Name: idx_on_runtime_id_runtime_name_de2ab1bfc0; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON public.runtime_function_definitions USING btree (runtime_id, runtime_name); + + +-- +-- Name: idx_on_runtime_parameter_definition_id_3cbdb30381; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON public.function_generic_mappers USING btree (runtime_parameter_definition_id); + + +-- +-- Name: index_active_storage_attachments_on_blob_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_active_storage_attachments_on_blob_id ON public.active_storage_attachments USING btree (blob_id); + + +-- +-- Name: index_active_storage_attachments_uniqueness; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON public.active_storage_attachments USING btree (record_type, record_id, name, blob_id); + + +-- +-- Name: index_active_storage_blobs_on_key; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_active_storage_blobs_on_key ON public.active_storage_blobs USING btree (key); + + +-- +-- Name: index_active_storage_variant_records_uniqueness; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_active_storage_variant_records_uniqueness ON public.active_storage_variant_records USING btree (blob_id, variation_digest); + + +-- +-- Name: index_application_settings_on_setting; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_application_settings_on_setting ON public.application_settings USING btree (setting); + + +-- +-- Name: index_audit_events_on_author_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_audit_events_on_author_id ON public.audit_events USING btree (author_id); + + +-- +-- Name: index_backup_codes_on_user_id_LOWER_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX "index_backup_codes_on_user_id_LOWER_token" ON public.backup_codes USING btree (user_id, lower(token)); + + +-- +-- Name: index_data_type_identifiers_on_data_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_data_type_identifiers_on_data_type_id ON public.data_type_identifiers USING btree (data_type_id); + + +-- +-- Name: index_data_type_identifiers_on_function_generic_mapper_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_data_type_identifiers_on_function_generic_mapper_id ON public.data_type_identifiers USING btree (function_generic_mapper_id); + + +-- +-- Name: index_data_type_identifiers_on_generic_mapper_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_data_type_identifiers_on_generic_mapper_id ON public.data_type_identifiers USING btree (generic_mapper_id); + + +-- +-- Name: index_data_type_identifiers_on_generic_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_data_type_identifiers_on_generic_type_id ON public.data_type_identifiers USING btree (generic_type_id); + + +-- +-- Name: index_data_type_identifiers_on_runtime_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_data_type_identifiers_on_runtime_id ON public.data_type_identifiers USING btree (runtime_id); + + +-- +-- Name: index_data_type_rules_on_data_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_data_type_rules_on_data_type_id ON public.data_type_rules USING btree (data_type_id); + + +-- +-- Name: index_data_types_on_flows_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_data_types_on_flows_id ON public.data_types USING btree (flows_id); + + +-- +-- Name: index_data_types_on_parent_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_data_types_on_parent_type_id ON public.data_types USING btree (parent_type_id); + + +-- +-- Name: index_data_types_on_runtime_id_and_identifier; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_data_types_on_runtime_id_and_identifier ON public.data_types USING btree (runtime_id, identifier); + + +-- +-- Name: index_flow_settings_on_flow_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flow_settings_on_flow_id ON public.flow_settings USING btree (flow_id); + + +-- +-- Name: index_flow_type_settings_on_data_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flow_type_settings_on_data_type_id ON public.flow_type_settings USING btree (data_type_id); + + +-- +-- Name: index_flow_type_settings_on_flow_type_id_and_identifier; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_flow_type_settings_on_flow_type_id_and_identifier ON public.flow_type_settings USING btree (flow_type_id, identifier); + + +-- +-- Name: index_flow_types_on_input_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flow_types_on_input_type_id ON public.flow_types USING btree (input_type_id); + + +-- +-- Name: index_flow_types_on_return_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flow_types_on_return_type_id ON public.flow_types USING btree (return_type_id); + + +-- +-- Name: index_flow_types_on_runtime_id_and_identifier; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_flow_types_on_runtime_id_and_identifier ON public.flow_types USING btree (runtime_id, identifier); + + +-- +-- Name: index_flows_on_flow_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flows_on_flow_type_id ON public.flows USING btree (flow_type_id); + + +-- +-- Name: index_flows_on_input_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flows_on_input_type_id ON public.flows USING btree (input_type_id); + + +-- +-- Name: index_flows_on_project_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flows_on_project_id ON public.flows USING btree (project_id); + + +-- +-- Name: index_flows_on_return_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flows_on_return_type_id ON public.flows USING btree (return_type_id); + + +-- +-- Name: index_flows_on_starting_node_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_flows_on_starting_node_id ON public.flows USING btree (starting_node_id); + + +-- +-- Name: index_function_definitions_on_return_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_function_definitions_on_return_type_id ON public.function_definitions USING btree (return_type_id); + + +-- +-- Name: index_function_definitions_on_runtime_function_definition_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON public.function_definitions USING btree (runtime_function_definition_id); + + +-- +-- Name: index_function_generic_mappers_on_runtime_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_function_generic_mappers_on_runtime_id ON public.function_generic_mappers USING btree (runtime_id); + + +-- +-- Name: index_generic_combination_strategies_on_generic_mapper_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_generic_combination_strategies_on_generic_mapper_id ON public.generic_combination_strategies USING btree (generic_mapper_id); + + +-- +-- Name: index_generic_mappers_on_generic_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_generic_mappers_on_generic_type_id ON public.generic_mappers USING btree (generic_type_id); + + +-- +-- Name: index_generic_mappers_on_runtime_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_generic_mappers_on_runtime_id ON public.generic_mappers USING btree (runtime_id); + + +-- +-- Name: index_generic_types_on_data_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_generic_types_on_data_type_id ON public.generic_types USING btree (data_type_id); + + +-- +-- Name: index_generic_types_on_runtime_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_generic_types_on_runtime_id ON public.generic_types USING btree (runtime_id); + + +-- +-- Name: index_good_job_executions_on_active_job_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON public.good_job_executions USING btree (active_job_id, created_at); + + +-- +-- Name: index_good_job_executions_on_process_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON public.good_job_executions USING btree (process_id, created_at); + + +-- +-- Name: index_good_job_jobs_for_candidate_lookup; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_job_jobs_for_candidate_lookup ON public.good_jobs USING btree (priority, created_at) WHERE (finished_at IS NULL); + + +-- +-- Name: index_good_job_settings_on_key; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_good_job_settings_on_key ON public.good_job_settings USING btree (key); + + +-- +-- Name: index_good_jobs_jobs_on_finished_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_jobs_on_finished_at ON public.good_jobs USING btree (finished_at) WHERE ((retried_good_job_id IS NULL) AND (finished_at IS NOT NULL)); + + +-- +-- Name: index_good_jobs_jobs_on_priority_created_at_when_unfinished; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_jobs_on_priority_created_at_when_unfinished ON public.good_jobs USING btree (priority DESC NULLS LAST, created_at) WHERE (finished_at IS NULL); + + +-- +-- Name: index_good_jobs_on_active_job_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_active_job_id_and_created_at ON public.good_jobs USING btree (active_job_id, created_at); + + +-- +-- Name: index_good_jobs_on_batch_callback_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_batch_callback_id ON public.good_jobs USING btree (batch_callback_id) WHERE (batch_callback_id IS NOT NULL); + + +-- +-- Name: index_good_jobs_on_batch_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_batch_id ON public.good_jobs USING btree (batch_id) WHERE (batch_id IS NOT NULL); + + +-- +-- Name: index_good_jobs_on_concurrency_key_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_concurrency_key_and_created_at ON public.good_jobs USING btree (concurrency_key, created_at); + + +-- +-- Name: index_good_jobs_on_concurrency_key_when_unfinished; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_concurrency_key_when_unfinished ON public.good_jobs USING btree (concurrency_key) WHERE (finished_at IS NULL); + + +-- +-- Name: index_good_jobs_on_cron_key_and_created_at_cond; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_cron_key_and_created_at_cond ON public.good_jobs USING btree (cron_key, created_at) WHERE (cron_key IS NOT NULL); + + +-- +-- Name: index_good_jobs_on_cron_key_and_cron_at_cond; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_good_jobs_on_cron_key_and_cron_at_cond ON public.good_jobs USING btree (cron_key, cron_at) WHERE (cron_key IS NOT NULL); + + +-- +-- Name: index_good_jobs_on_labels; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_labels ON public.good_jobs USING gin (labels) WHERE (labels IS NOT NULL); + + +-- +-- Name: index_good_jobs_on_locked_by_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_locked_by_id ON public.good_jobs USING btree (locked_by_id) WHERE (locked_by_id IS NOT NULL); + + +-- +-- Name: index_good_jobs_on_priority_scheduled_at_unfinished_unlocked; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_priority_scheduled_at_unfinished_unlocked ON public.good_jobs USING btree (priority, scheduled_at) WHERE ((finished_at IS NULL) AND (locked_by_id IS NULL)); + + +-- +-- Name: index_good_jobs_on_queue_name_and_scheduled_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_queue_name_and_scheduled_at ON public.good_jobs USING btree (queue_name, scheduled_at) WHERE (finished_at IS NULL); + + +-- +-- Name: index_good_jobs_on_scheduled_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_good_jobs_on_scheduled_at ON public.good_jobs USING btree (scheduled_at) WHERE (finished_at IS NULL); + + +-- +-- Name: index_namespace_licenses_on_namespace_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_namespace_licenses_on_namespace_id ON public.namespace_licenses USING btree (namespace_id); + + +-- +-- Name: index_namespace_member_roles_on_member_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_namespace_member_roles_on_member_id ON public.namespace_member_roles USING btree (member_id); + + +-- +-- Name: index_namespace_member_roles_on_role_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_namespace_member_roles_on_role_id ON public.namespace_member_roles USING btree (role_id); + + +-- +-- Name: index_namespace_members_on_namespace_id_and_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_namespace_members_on_namespace_id_and_user_id ON public.namespace_members USING btree (namespace_id, user_id); + + +-- +-- Name: index_namespace_members_on_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_namespace_members_on_user_id ON public.namespace_members USING btree (user_id); + + +-- +-- Name: index_namespace_projects_on_namespace_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_namespace_projects_on_namespace_id ON public.namespace_projects USING btree (namespace_id); + + +-- +-- Name: index_namespace_projects_on_primary_runtime_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_namespace_projects_on_primary_runtime_id ON public.namespace_projects USING btree (primary_runtime_id); + + +-- +-- Name: index_namespace_role_project_assignments_on_project_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_namespace_role_project_assignments_on_project_id ON public.namespace_role_project_assignments USING btree (project_id); + + +-- +-- Name: index_namespace_roles_on_namespace_id_LOWER_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON public.namespace_roles USING btree (namespace_id, lower(name)); + + +-- +-- Name: index_namespaces_on_parent_id_and_parent_type; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_namespaces_on_parent_id_and_parent_type ON public.namespaces USING btree (parent_id, parent_type); + + +-- +-- Name: index_node_functions_on_next_node_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_node_functions_on_next_node_id ON public.node_functions USING btree (next_node_id); + + +-- +-- Name: index_node_functions_on_runtime_function_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_node_functions_on_runtime_function_id ON public.node_functions USING btree (runtime_function_id); + + +-- +-- Name: index_node_parameters_on_function_value_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_node_parameters_on_function_value_id ON public.node_parameters USING btree (function_value_id); + + +-- +-- Name: index_node_parameters_on_node_function_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_node_parameters_on_node_function_id ON public.node_parameters USING btree (node_function_id); + + +-- +-- Name: index_node_parameters_on_reference_value_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_node_parameters_on_reference_value_id ON public.node_parameters USING btree (reference_value_id); + + +-- +-- Name: index_node_parameters_on_runtime_parameter_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_node_parameters_on_runtime_parameter_id ON public.node_parameters USING btree (runtime_parameter_id); + + +-- +-- Name: index_organizations_on_LOWER_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX "index_organizations_on_LOWER_name" ON public.organizations USING btree (lower(name)); + + +-- +-- Name: index_parameter_definitions_on_data_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_parameter_definitions_on_data_type_id ON public.parameter_definitions USING btree (data_type_id); + + +-- +-- Name: index_parameter_definitions_on_runtime_parameter_definition_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_parameter_definitions_on_runtime_parameter_definition_id ON public.parameter_definitions USING btree (runtime_parameter_definition_id); + + +-- +-- Name: index_reference_paths_on_reference_value_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_reference_paths_on_reference_value_id ON public.reference_paths USING btree (reference_value_id); + + +-- +-- Name: index_reference_values_on_data_type_identifier_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_reference_values_on_data_type_identifier_id ON public.reference_values USING btree (data_type_identifier_id); + + +-- +-- Name: index_runtime_function_definitions_on_return_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_runtime_function_definitions_on_return_type_id ON public.runtime_function_definitions USING btree (return_type_id); + + +-- +-- Name: index_runtime_parameter_definitions_on_data_type_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_runtime_parameter_definitions_on_data_type_id ON public.runtime_parameter_definitions USING btree (data_type_id); + + +-- +-- Name: index_runtimes_on_namespace_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_runtimes_on_namespace_id ON public.runtimes USING btree (namespace_id); + + +-- +-- Name: index_runtimes_on_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_runtimes_on_token ON public.runtimes USING btree (token); + + +-- +-- Name: index_translations_on_owner; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_translations_on_owner ON public.translations USING btree (owner_type, owner_id); + + +-- +-- Name: index_user_identities_on_provider_id_and_identifier; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_user_identities_on_provider_id_and_identifier ON public.user_identities USING btree (provider_id, identifier); + + +-- +-- Name: index_user_identities_on_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_user_identities_on_user_id ON public.user_identities USING btree (user_id); + + +-- +-- Name: index_user_identities_on_user_id_and_provider_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_user_identities_on_user_id_and_provider_id ON public.user_identities USING btree (user_id, provider_id); + + +-- +-- Name: index_user_sessions_on_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_user_sessions_on_token ON public.user_sessions USING btree (token); + + +-- +-- Name: index_user_sessions_on_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_user_sessions_on_user_id ON public.user_sessions USING btree (user_id); + + +-- +-- Name: index_users_on_LOWER_email; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX "index_users_on_LOWER_email" ON public.users USING btree (lower(email)); + + +-- +-- Name: index_users_on_LOWER_username; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX "index_users_on_LOWER_username" ON public.users USING btree (lower(username)); + + +-- +-- Name: index_users_on_totp_secret; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_users_on_totp_secret ON public.users USING btree (totp_secret) WHERE (totp_secret IS NOT NULL); + + +-- +-- Name: flow_types fk_rails_01f5c9215f; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.flow_types + ADD CONSTRAINT fk_rails_01f5c9215f FOREIGN KEY (input_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; + + +-- +-- Name: data_type_identifiers fk_rails_01f5d14544; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.data_type_identifiers + ADD CONSTRAINT fk_rails_01f5d14544 FOREIGN KEY (generic_mapper_id) REFERENCES public.generic_mappers(id) ON DELETE RESTRICT; + + +-- +-- Name: runtime_function_definition_error_types fk_rails_070c5bfcf0; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtime_function_definition_error_types + ADD CONSTRAINT fk_rails_070c5bfcf0 FOREIGN KEY (runtime_function_definition_id) REFERENCES public.runtime_function_definitions(id) ON DELETE CASCADE; + + +-- +-- Name: function_definitions fk_rails_0c2eb746ef; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.function_definitions + ADD CONSTRAINT fk_rails_0c2eb746ef FOREIGN KEY (return_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; + + +-- +-- Name: node_parameters fk_rails_0d79310cfa; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.node_parameters + ADD CONSTRAINT fk_rails_0d79310cfa FOREIGN KEY (node_function_id) REFERENCES public.node_functions(id) ON DELETE CASCADE; + + +-- +-- Name: node_parameters fk_rails_0ff4fd0049; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.node_parameters + ADD CONSTRAINT fk_rails_0ff4fd0049 FOREIGN KEY (runtime_parameter_id) REFERENCES public.runtime_parameter_definitions(id) ON DELETE CASCADE; + + +-- +-- Name: data_types fk_rails_118c914ed0; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.data_types + ADD CONSTRAINT fk_rails_118c914ed0 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; + + +-- +-- Name: generic_combination_strategies fk_rails_1f88a2577e; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generic_combination_strategies + ADD CONSTRAINT fk_rails_1f88a2577e FOREIGN KEY (generic_mapper_id) REFERENCES public.generic_mappers(id) ON DELETE CASCADE; + + +-- +-- Name: namespace_roles fk_rails_205092c9cb; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_roles + ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; + + +-- +-- Name: generic_types fk_rails_20f4bf6b34; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generic_types + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; + + +-- +-- Name: runtime_parameter_definitions fk_rails_260318ad67; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.runtime_parameter_definitions + ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES public.runtime_function_definitions(id) ON DELETE CASCADE; + + +-- +-- Name: function_generic_mappers fk_rails_26b6470eba; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.function_generic_mappers + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES public.runtime_parameter_definitions(id) ON DELETE RESTRICT; + + +-- +-- Name: generic_types fk_rails_275446d9e6; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generic_types + ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE CASCADE; + + +-- +-- Name: namespace_licenses fk_rails_38f693332d; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.namespace_licenses + ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; + + +-- +-- Name: parameter_definitions fk_rails_3b02763f84; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.parameter_definitions + ADD CONSTRAINT fk_rails_3b02763f84 FOREIGN KEY (runtime_parameter_definition_id) REFERENCES public.runtime_parameter_definitions(id) ON DELETE CASCADE; + + +-- +-- Name: runtime_function_definition_error_types fk_rails_408d037751; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_data_type_id_b6aa8fe066 ON runtime_function_definition_error_types USING btree (runtime_function_definition_id, data_type_id); +ALTER TABLE ONLY public.runtime_function_definition_error_types + ADD CONSTRAINT fk_rails_408d037751 FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; -CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON function_generic_mappers USING btree (runtime_function_definition_id); -CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); +-- +-- Name: data_type_identifiers fk_rails_40d8496abb; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); +ALTER TABLE ONLY public.data_type_identifiers + ADD CONSTRAINT fk_rails_40d8496abb FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; -CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON runtime_function_definitions USING btree (runtime_id, runtime_name); -CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON function_generic_mappers USING btree (runtime_parameter_definition_id); +-- +-- Name: data_types fk_rails_4434ad0b90; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_active_storage_attachments_on_blob_id ON active_storage_attachments USING btree (blob_id); +ALTER TABLE ONLY public.data_types + ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; -CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON active_storage_attachments USING btree (record_type, record_id, name, blob_id); -CREATE UNIQUE INDEX index_active_storage_blobs_on_key ON active_storage_blobs USING btree (key); +-- +-- Name: function_generic_mappers fk_rails_4593a9a9b6; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE UNIQUE INDEX index_active_storage_variant_records_uniqueness ON active_storage_variant_records USING btree (blob_id, variation_digest); +ALTER TABLE ONLY public.function_generic_mappers + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; -CREATE UNIQUE INDEX index_application_settings_on_setting ON application_settings USING btree (setting); -CREATE INDEX index_audit_events_on_author_id ON audit_events USING btree (author_id); +-- +-- Name: function_definitions fk_rails_48f4bbe3b6; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE UNIQUE INDEX "index_backup_codes_on_user_id_LOWER_token" ON backup_codes USING btree (user_id, lower(token)); +ALTER TABLE ONLY public.function_definitions + ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES public.runtime_function_definitions(id) ON DELETE CASCADE; -CREATE INDEX index_data_type_identifiers_on_data_type_id ON data_type_identifiers USING btree (data_type_id); -CREATE INDEX index_data_type_identifiers_on_generic_type_id ON data_type_identifiers USING btree (generic_type_id); +-- +-- Name: data_types fk_rails_490081f598; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_data_type_identifiers_on_runtime_id ON data_type_identifiers USING btree (runtime_id); +ALTER TABLE ONLY public.data_types + ADD CONSTRAINT fk_rails_490081f598 FOREIGN KEY (flows_id) REFERENCES public.flows(id) ON DELETE RESTRICT; -CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id); -CREATE INDEX index_data_types_on_flows_id ON data_types USING btree (flows_id); +-- +-- Name: runtime_function_definitions fk_rails_5161ff47e6; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (parent_type_id); +ALTER TABLE ONLY public.runtime_function_definitions + ADD CONSTRAINT fk_rails_5161ff47e6 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; -CREATE UNIQUE INDEX index_data_types_on_runtime_id_and_identifier ON data_types USING btree (runtime_id, identifier); -CREATE INDEX index_flow_settings_on_flow_id ON flow_settings USING btree (flow_id); +-- +-- Name: backup_codes fk_rails_556c1feac3; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_flow_type_settings_on_data_type_id ON flow_type_settings USING btree (data_type_id); +ALTER TABLE ONLY public.backup_codes + ADD CONSTRAINT fk_rails_556c1feac3 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; -CREATE UNIQUE INDEX index_flow_type_settings_on_flow_type_id_and_identifier ON flow_type_settings USING btree (flow_type_id, identifier); -CREATE INDEX index_flow_types_on_input_type_id ON flow_types USING btree (input_type_id); +-- +-- Name: namespace_members fk_rails_567f152a62; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_flow_types_on_return_type_id ON flow_types USING btree (return_type_id); +ALTER TABLE ONLY public.namespace_members + ADD CONSTRAINT fk_rails_567f152a62 FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; -CREATE UNIQUE INDEX index_flow_types_on_runtime_id_and_identifier ON flow_types USING btree (runtime_id, identifier); -CREATE INDEX index_flows_on_flow_type_id ON flows USING btree (flow_type_id); +-- +-- Name: namespace_member_roles fk_rails_585a684166; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_flows_on_input_type_id ON flows USING btree (input_type_id); +ALTER TABLE ONLY public.namespace_member_roles + ADD CONSTRAINT fk_rails_585a684166 FOREIGN KEY (role_id) REFERENCES public.namespace_roles(id) ON DELETE CASCADE; -CREATE INDEX index_flows_on_project_id ON flows USING btree (project_id); -CREATE INDEX index_flows_on_return_type_id ON flows USING btree (return_type_id); +-- +-- Name: namespace_role_project_assignments fk_rails_623f8a5b72; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_flows_on_starting_node_id ON flows USING btree (starting_node_id); +ALTER TABLE ONLY public.namespace_role_project_assignments + ADD CONSTRAINT fk_rails_623f8a5b72 FOREIGN KEY (role_id) REFERENCES public.namespace_roles(id); -CREATE INDEX index_function_definitions_on_return_type_id ON function_definitions USING btree (return_type_id); -CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); +-- +-- Name: node_parameters fk_rails_646d4dbfbc; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); +ALTER TABLE ONLY public.node_parameters + ADD CONSTRAINT fk_rails_646d4dbfbc FOREIGN KEY (reference_value_id) REFERENCES public.reference_values(id) ON DELETE RESTRICT; -CREATE INDEX index_function_generic_mappers_on_source_id ON function_generic_mappers USING btree (source_id); -CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); +-- +-- Name: data_type_identifiers fk_rails_65151da1fb; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); +ALTER TABLE ONLY public.data_type_identifiers + ADD CONSTRAINT fk_rails_65151da1fb FOREIGN KEY (generic_type_id) REFERENCES public.generic_types(id) ON DELETE CASCADE; -CREATE INDEX index_generic_mappers_on_source_id ON generic_mappers USING btree (source_id); -CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); +-- +-- Name: user_identities fk_rails_684b0e1ce0; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); +ALTER TABLE ONLY public.user_identities + ADD CONSTRAINT fk_rails_684b0e1ce0 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; -CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON good_job_executions USING btree (active_job_id, created_at); -CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON good_job_executions USING btree (process_id, created_at); +-- +-- Name: flow_types fk_rails_687d671458; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_good_job_jobs_for_candidate_lookup ON good_jobs USING btree (priority, created_at) WHERE (finished_at IS NULL); +ALTER TABLE ONLY public.flow_types + ADD CONSTRAINT fk_rails_687d671458 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; -CREATE UNIQUE INDEX index_good_job_settings_on_key ON good_job_settings USING btree (key); -CREATE INDEX index_good_jobs_jobs_on_finished_at ON good_jobs USING btree (finished_at) WHERE ((retried_good_job_id IS NULL) AND (finished_at IS NOT NULL)); +-- +-- Name: namespace_role_project_assignments fk_rails_69066bda8f; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_good_jobs_jobs_on_priority_created_at_when_unfinished ON good_jobs USING btree (priority DESC NULLS LAST, created_at) WHERE (finished_at IS NULL); +ALTER TABLE ONLY public.namespace_role_project_assignments + ADD CONSTRAINT fk_rails_69066bda8f FOREIGN KEY (project_id) REFERENCES public.namespace_projects(id); -CREATE INDEX index_good_jobs_on_active_job_id_and_created_at ON good_jobs USING btree (active_job_id, created_at); -CREATE INDEX index_good_jobs_on_batch_callback_id ON good_jobs USING btree (batch_callback_id) WHERE (batch_callback_id IS NOT NULL); +-- +-- Name: namespace_member_roles fk_rails_6c0d5a04c4; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_good_jobs_on_batch_id ON good_jobs USING btree (batch_id) WHERE (batch_id IS NOT NULL); +ALTER TABLE ONLY public.namespace_member_roles + ADD CONSTRAINT fk_rails_6c0d5a04c4 FOREIGN KEY (member_id) REFERENCES public.namespace_members(id) ON DELETE CASCADE; -CREATE INDEX index_good_jobs_on_concurrency_key_and_created_at ON good_jobs USING btree (concurrency_key, created_at); -CREATE INDEX index_good_jobs_on_concurrency_key_when_unfinished ON good_jobs USING btree (concurrency_key) WHERE (finished_at IS NULL); +-- +-- Name: namespace_role_abilities fk_rails_6f3304b078; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_good_jobs_on_cron_key_and_created_at_cond ON good_jobs USING btree (cron_key, created_at) WHERE (cron_key IS NOT NULL); +ALTER TABLE ONLY public.namespace_role_abilities + ADD CONSTRAINT fk_rails_6f3304b078 FOREIGN KEY (namespace_role_id) REFERENCES public.namespace_roles(id) ON DELETE CASCADE; -CREATE UNIQUE INDEX index_good_jobs_on_cron_key_and_cron_at_cond ON good_jobs USING btree (cron_key, cron_at) WHERE (cron_key IS NOT NULL); -CREATE INDEX index_good_jobs_on_labels ON good_jobs USING gin (labels) WHERE (labels IS NOT NULL); +-- +-- Name: runtime_function_definitions fk_rails_73ca8569ea; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_good_jobs_on_locked_by_id ON good_jobs USING btree (locked_by_id) WHERE (locked_by_id IS NOT NULL); +ALTER TABLE ONLY public.runtime_function_definitions + ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; -CREATE INDEX index_good_jobs_on_priority_scheduled_at_unfinished_unlocked ON good_jobs USING btree (priority, scheduled_at) WHERE ((finished_at IS NULL) AND (locked_by_id IS NULL)); -CREATE INDEX index_good_jobs_on_queue_name_and_scheduled_at ON good_jobs USING btree (queue_name, scheduled_at) WHERE (finished_at IS NULL); +-- +-- Name: node_parameters fk_rails_74b7800b37; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_good_jobs_on_scheduled_at ON good_jobs USING btree (scheduled_at) WHERE (finished_at IS NULL); +ALTER TABLE ONLY public.node_parameters + ADD CONSTRAINT fk_rails_74b7800b37 FOREIGN KEY (function_value_id) REFERENCES public.node_functions(id) ON DELETE RESTRICT; -CREATE INDEX index_namespace_licenses_on_namespace_id ON namespace_licenses USING btree (namespace_id); -CREATE INDEX index_namespace_member_roles_on_member_id ON namespace_member_roles USING btree (member_id); +-- +-- Name: data_type_rules fk_rails_7759633ff8; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_namespace_member_roles_on_role_id ON namespace_member_roles USING btree (role_id); +ALTER TABLE ONLY public.data_type_rules + ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE CASCADE; -CREATE UNIQUE INDEX index_namespace_members_on_namespace_id_and_user_id ON namespace_members USING btree (namespace_id, user_id); -CREATE INDEX index_namespace_members_on_user_id ON namespace_members USING btree (user_id); +-- +-- Name: namespace_projects fk_rails_79012c5895; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_namespace_projects_on_namespace_id ON namespace_projects USING btree (namespace_id); +ALTER TABLE ONLY public.namespace_projects + ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; -CREATE INDEX index_namespace_projects_on_primary_runtime_id ON namespace_projects USING btree (primary_runtime_id); -CREATE INDEX index_namespace_role_project_assignments_on_project_id ON namespace_role_project_assignments USING btree (project_id); +-- +-- Name: flows fk_rails_7de9ce6578; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON namespace_roles USING btree (namespace_id, lower(name)); +ALTER TABLE ONLY public.flows + ADD CONSTRAINT fk_rails_7de9ce6578 FOREIGN KEY (starting_node_id) REFERENCES public.node_functions(id) ON DELETE RESTRICT; -CREATE UNIQUE INDEX index_namespaces_on_parent_id_and_parent_type ON namespaces USING btree (parent_id, parent_type); -CREATE INDEX index_node_functions_on_next_node_id ON node_functions USING btree (next_node_id); +-- +-- Name: node_functions fk_rails_8953e1d86a; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_node_functions_on_runtime_function_id ON node_functions USING btree (runtime_function_id); +ALTER TABLE ONLY public.node_functions + ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES public.runtime_function_definitions(id) ON DELETE RESTRICT; -CREATE INDEX index_node_parameters_on_function_value_id ON node_parameters USING btree (function_value_id); -CREATE INDEX index_node_parameters_on_node_function_id ON node_parameters USING btree (node_function_id); +-- +-- Name: data_type_identifiers fk_rails_8d8385e8ec; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_node_parameters_on_reference_value_id ON node_parameters USING btree (reference_value_id); +ALTER TABLE ONLY public.data_type_identifiers + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; -CREATE INDEX index_node_parameters_on_runtime_parameter_id ON node_parameters USING btree (runtime_parameter_id); -CREATE UNIQUE INDEX "index_organizations_on_LOWER_name" ON organizations USING btree (lower(name)); +-- +-- Name: flows fk_rails_8f97500cd4; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_parameter_definitions_on_data_type_id ON parameter_definitions USING btree (data_type_id); +ALTER TABLE ONLY public.flows + ADD CONSTRAINT fk_rails_8f97500cd4 FOREIGN KEY (return_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; -CREATE INDEX index_parameter_definitions_on_runtime_parameter_definition_id ON parameter_definitions USING btree (runtime_parameter_definition_id); -CREATE INDEX index_reference_paths_on_reference_value_id ON reference_paths USING btree (reference_value_id); +-- +-- Name: reference_paths fk_rails_92e51047ea; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_reference_values_on_data_type_identifier_id ON reference_values USING btree (data_type_identifier_id); +ALTER TABLE ONLY public.reference_paths + ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES public.reference_values(id) ON DELETE RESTRICT; -CREATE INDEX index_runtime_function_definitions_on_return_type_id ON runtime_function_definitions USING btree (return_type_id); -CREATE INDEX index_runtime_parameter_definitions_on_data_type_id ON runtime_parameter_definitions USING btree (data_type_id); +-- +-- Name: active_storage_variant_records fk_rails_993965df05; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE INDEX index_runtimes_on_namespace_id ON runtimes USING btree (namespace_id); +ALTER TABLE ONLY public.active_storage_variant_records + ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id); -CREATE UNIQUE INDEX index_runtimes_on_token ON runtimes USING btree (token); -CREATE INDEX index_translations_on_owner ON translations USING btree (owner_type, owner_id); +-- +-- Name: function_generic_mappers fk_rails_9f59fae6ab; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE UNIQUE INDEX index_user_identities_on_provider_id_and_identifier ON user_identities USING btree (provider_id, identifier); +ALTER TABLE ONLY public.function_generic_mappers + ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES public.runtime_function_definitions(id) ON DELETE RESTRICT; -CREATE INDEX index_user_identities_on_user_id ON user_identities USING btree (user_id); -CREATE UNIQUE INDEX index_user_identities_on_user_id_and_provider_id ON user_identities USING btree (user_id, provider_id); +-- +-- Name: user_sessions fk_rails_9fa262d742; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE UNIQUE INDEX index_user_sessions_on_token ON user_sessions USING btree (token); +ALTER TABLE ONLY public.user_sessions + ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; -CREATE INDEX index_user_sessions_on_user_id ON user_sessions USING btree (user_id); -CREATE UNIQUE INDEX "index_users_on_LOWER_email" ON users USING btree (lower(email)); +-- +-- Name: namespace_members fk_rails_a0a760b9b4; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -CREATE UNIQUE INDEX "index_users_on_LOWER_username" ON users USING btree (lower(username)); +ALTER TABLE ONLY public.namespace_members + ADD CONSTRAINT fk_rails_a0a760b9b4 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; -CREATE UNIQUE INDEX index_users_on_totp_secret ON users USING btree (totp_secret) WHERE (totp_secret IS NOT NULL); -ALTER TABLE ONLY flow_types - ADD CONSTRAINT fk_rails_01f5c9215f FOREIGN KEY (input_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +-- +-- Name: flow_type_settings fk_rails_a1471d011d; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY runtime_function_definition_error_types - ADD CONSTRAINT fk_rails_070c5bfcf0 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.flow_type_settings + ADD CONSTRAINT fk_rails_a1471d011d FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY function_definitions - ADD CONSTRAINT fk_rails_0c2eb746ef FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY node_parameters - ADD CONSTRAINT fk_rails_0d79310cfa FOREIGN KEY (node_function_id) REFERENCES node_functions(id) ON DELETE CASCADE; +-- +-- Name: flows fk_rails_ab927e0ecb; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY node_parameters - ADD CONSTRAINT fk_rails_0ff4fd0049 FOREIGN KEY (runtime_parameter_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.flows + ADD CONSTRAINT fk_rails_ab927e0ecb FOREIGN KEY (project_id) REFERENCES public.namespace_projects(id) ON DELETE CASCADE; -ALTER TABLE ONLY data_types - ADD CONSTRAINT fk_rails_118c914ed0 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY namespace_roles - ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +-- +-- Name: reference_values fk_rails_bb34a5d62c; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.reference_values + ADD CONSTRAINT fk_rails_bb34a5d62c FOREIGN KEY (data_type_identifier_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY runtime_parameter_definitions - ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; +-- +-- Name: flows fk_rails_bb587eff6a; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.flows + ADD CONSTRAINT fk_rails_bb587eff6a FOREIGN KEY (input_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_2adace81b8 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY namespace_licenses - ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +-- +-- Name: flow_types fk_rails_bead35b1a6; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY parameter_definitions - ADD CONSTRAINT fk_rails_3b02763f84 FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.flow_types + ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY runtime_function_definition_error_types - ADD CONSTRAINT fk_rails_408d037751 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_40d8496abb FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +-- +-- Name: namespace_project_runtime_assignments fk_rails_c019e5b233; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY data_types - ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY public.namespace_project_runtime_assignments + ADD CONSTRAINT fk_rails_c019e5b233 FOREIGN KEY (namespace_project_id) REFERENCES public.namespace_projects(id) ON DELETE CASCADE; -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY function_definitions - ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; +-- +-- Name: active_storage_attachments fk_rails_c3b3935057; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY data_types - ADD CONSTRAINT fk_rails_490081f598 FOREIGN KEY (flows_id) REFERENCES flows(id) ON DELETE RESTRICT; +ALTER TABLE ONLY public.active_storage_attachments + ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id); -ALTER TABLE ONLY runtime_function_definitions - ADD CONSTRAINT fk_rails_5161ff47e6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY backup_codes - ADD CONSTRAINT fk_rails_556c1feac3 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; +-- +-- Name: namespace_project_runtime_assignments fk_rails_c640af2146; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY namespace_members - ADD CONSTRAINT fk_rails_567f152a62 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.namespace_project_runtime_assignments + ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY namespace_member_roles - ADD CONSTRAINT fk_rails_585a684166 FOREIGN KEY (role_id) REFERENCES namespace_roles(id) ON DELETE CASCADE; -ALTER TABLE ONLY namespace_role_project_assignments - ADD CONSTRAINT fk_rails_623f8a5b72 FOREIGN KEY (role_id) REFERENCES namespace_roles(id); +-- +-- Name: generic_mappers fk_rails_c7984c8a7a; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY node_parameters - ADD CONSTRAINT fk_rails_646d4dbfbc FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; +ALTER TABLE ONLY public.generic_mappers + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_65151da1fb FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY user_identities - ADD CONSTRAINT fk_rails_684b0e1ce0 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; +-- +-- Name: parameter_definitions fk_rails_ca0a397b6f; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY flow_types - ADD CONSTRAINT fk_rails_687d671458 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.parameter_definitions + ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY namespace_role_project_assignments - ADD CONSTRAINT fk_rails_69066bda8f FOREIGN KEY (project_id) REFERENCES namespace_projects(id); -ALTER TABLE ONLY namespace_member_roles - ADD CONSTRAINT fk_rails_6c0d5a04c4 FOREIGN KEY (member_id) REFERENCES namespace_members(id) ON DELETE CASCADE; +-- +-- Name: data_type_identifiers fk_rails_d08626f743; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY namespace_role_abilities - ADD CONSTRAINT fk_rails_6f3304b078 FOREIGN KEY (namespace_role_id) REFERENCES namespace_roles(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.data_type_identifiers + ADD CONSTRAINT fk_rails_d08626f743 FOREIGN KEY (function_generic_mapper_id) REFERENCES public.function_generic_mappers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY runtime_function_definitions - ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY node_parameters - ADD CONSTRAINT fk_rails_74b7800b37 FOREIGN KEY (function_value_id) REFERENCES node_functions(id) ON DELETE RESTRICT; +-- +-- Name: namespace_projects fk_rails_d4f50e2f00; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY data_type_rules - ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.namespace_projects + ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; -ALTER TABLE ONLY namespace_projects - ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY flows - ADD CONSTRAINT fk_rails_7de9ce6578 FOREIGN KEY (starting_node_id) REFERENCES node_functions(id) ON DELETE RESTRICT; +-- +-- Name: flows fk_rails_d9ad50fe4b; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY node_functions - ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; +ALTER TABLE ONLY public.flows + ADD CONSTRAINT fk_rails_d9ad50fe4b FOREIGN KEY (flow_type_id) REFERENCES public.flow_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY flows - ADD CONSTRAINT fk_rails_8f97500cd4 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +-- +-- Name: flow_settings fk_rails_da3b2fb3c5; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY reference_paths - ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; +ALTER TABLE ONLY public.flow_settings + ADD CONSTRAINT fk_rails_da3b2fb3c5 FOREIGN KEY (flow_id) REFERENCES public.flows(id) ON DELETE CASCADE; -ALTER TABLE ONLY active_storage_variant_records - ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; +-- +-- Name: generic_mappers fk_rails_e0d918961b; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY user_sessions - ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.generic_mappers + ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES public.generic_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY namespace_members - ADD CONSTRAINT fk_rails_a0a760b9b4 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; -ALTER TABLE ONLY flow_type_settings - ADD CONSTRAINT fk_rails_a1471d011d FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +-- +-- Name: runtime_parameter_definitions fk_rails_e64f825793; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY flows - ADD CONSTRAINT fk_rails_ab927e0ecb FOREIGN KEY (project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.runtime_parameter_definitions + ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY reference_values - ADD CONSTRAINT fk_rails_bb34a5d62c FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY flows - ADD CONSTRAINT fk_rails_bb587eff6a FOREIGN KEY (input_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +-- +-- Name: runtimes fk_rails_eeb42116cc; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY function_generic_mappers - ADD CONSTRAINT fk_rails_be1833ba72 FOREIGN KEY (source_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY public.runtimes + ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id); -ALTER TABLE ONLY flow_types - ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY namespace_project_runtime_assignments - ADD CONSTRAINT fk_rails_c019e5b233 FOREIGN KEY (namespace_project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; +-- +-- Name: audit_events fk_rails_f64374fc56; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY active_storage_attachments - ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); +ALTER TABLE ONLY public.audit_events + ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES public.users(id) ON DELETE SET NULL; -ALTER TABLE ONLY namespace_project_runtime_assignments - ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +-- +-- Name: flow_type_settings fk_rails_f6af7d8edf; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY parameter_definitions - ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY public.flow_type_settings + ADD CONSTRAINT fk_rails_f6af7d8edf FOREIGN KEY (flow_type_id) REFERENCES public.flow_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY namespace_projects - ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; -ALTER TABLE ONLY flows - ADD CONSTRAINT fk_rails_d9ad50fe4b FOREIGN KEY (flow_type_id) REFERENCES flow_types(id) ON DELETE CASCADE; +-- +-- Name: node_functions fk_rails_fbc91a3407; Type: FK CONSTRAINT; Schema: public; Owner: - +-- -ALTER TABLE ONLY flow_settings - ADD CONSTRAINT fk_rails_da3b2fb3c5 FOREIGN KEY (flow_id) REFERENCES flows(id) ON DELETE CASCADE; +ALTER TABLE ONLY public.node_functions + ADD CONSTRAINT fk_rails_fbc91a3407 FOREIGN KEY (next_node_id) REFERENCES public.node_functions(id) ON DELETE RESTRICT; -ALTER TABLE ONLY generic_mappers - ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY runtime_parameter_definitions - ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +-- +-- PostgreSQL database dump complete +-- -ALTER TABLE ONLY runtimes - ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); +SET search_path TO "$user", public; -ALTER TABLE ONLY audit_events - ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; -ALTER TABLE ONLY flow_type_settings - ADD CONSTRAINT fk_rails_f6af7d8edf FOREIGN KEY (flow_type_id) REFERENCES flow_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY node_functions - ADD CONSTRAINT fk_rails_fbc91a3407 FOREIGN KEY (next_node_id) REFERENCES node_functions(id) ON DELETE RESTRICT; diff --git a/docs/graphql/enum/datatyperulesdatatyperulevariant.md b/docs/graphql/enum/datatyperulesdatatyperulevariant.md new file mode 100644 index 00000000..e601a8e5 --- /dev/null +++ b/docs/graphql/enum/datatyperulesdatatyperulevariant.md @@ -0,0 +1,15 @@ +--- +title: DataTypeRulesDataTypeRuleVariant +--- + +The type of rule that can be applied to a data type. + +| Value | Description | +|-------|-------------| +| `CONTAINS_KEY` | The rule checks if a key is present in the data type. | +| `CONTAINS_TYPE` | The rule checks if a specific type is present in the data type. | +| `INPUT_TYPE` | The rule checks if the data type matches a specific input type. | +| `ITEM_OF_COLLECTION` | The rule checks if an item is part of a collection in the data type. | +| `NUMBER_RANGE` | The rule checks if a number falls within a specified range. | +| `REGEX` | The rule checks if a string matches a specified regular expression. | +| `RETURN_TYPE` | The rule checks if the data type matches a specific return type. | diff --git a/docs/graphql/enum/datatypevariant.md b/docs/graphql/enum/datatypevariant.md index e489a053..4e332832 100644 --- a/docs/graphql/enum/datatypevariant.md +++ b/docs/graphql/enum/datatypevariant.md @@ -8,8 +8,8 @@ Represent all available types of a datatype |-------|-------------| | `ARRAY` | Represents an array | | `DATA_TYPE` | Represents an data type containing a data type | -| `FUNCTION` | Represents a function | -| `GENERIC` | Represents a generic | +| `ERROR` | Represents a error | +| `NODE` | Represents a node | | `OBJECT` | Represents an object | | `PRIMITIVE` | Represents a primitive datatype | | `TYPE` | Represents a type | diff --git a/docs/graphql/input_object/genericmapperinput.md b/docs/graphql/input_object/genericmapperinput.md index 3a9bb9b8..f20982b8 100644 --- a/docs/graphql/input_object/genericmapperinput.md +++ b/docs/graphql/input_object/genericmapperinput.md @@ -8,5 +8,5 @@ Input type for generic mappers | Name | Type | Description | |------|------|-------------| -| `source` | [`DataTypeIdentifierInput!`](../input_object/datatypeidentifierinput.md) | The source data type identifier for the mapper | +| `sources` | [`[DataTypeIdentifierInput!]!`](../input_object/datatypeidentifierinput.md) | The source data type identifier for the mapper | | `target` | [`String!`](../scalar/string.md) | The target data type identifier for the mapper | diff --git a/docs/graphql/object/containskeyconfig.md b/docs/graphql/object/containskeyconfig.md new file mode 100644 index 00000000..05dfbdff --- /dev/null +++ b/docs/graphql/object/containskeyconfig.md @@ -0,0 +1,13 @@ +--- +title: ContainsKeyConfig +--- + +Represents a rule that can be applied to a data type. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `dataTypeIdentifier` | [`DataTypeIdentifier!`](../union/datatypeidentifier.md) | The identifier of the data type this rule belongs to | +| `key` | [`String!`](../scalar/string.md) | The key of the rule | + diff --git a/docs/graphql/object/containstypeconfig.md b/docs/graphql/object/containstypeconfig.md new file mode 100644 index 00000000..fab08875 --- /dev/null +++ b/docs/graphql/object/containstypeconfig.md @@ -0,0 +1,12 @@ +--- +title: ContainsTypeConfig +--- + +Represents a rule that can be applied to a data type. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `dataTypeIdentifier` | [`DataTypeIdentifier!`](../union/datatypeidentifier.md) | The identifier of the data type this rule belongs to | + diff --git a/docs/graphql/object/datatype.md b/docs/graphql/object/datatype.md index 41ea8a68..8f2c9647 100644 --- a/docs/graphql/object/datatype.md +++ b/docs/graphql/object/datatype.md @@ -9,9 +9,13 @@ Represents a DataType | Name | Type | Description | |------|------|-------------| | `createdAt` | [`Time!`](../scalar/time.md) | Time when this DataType was created | +| `genericKeys` | [`[String!]`](../scalar/string.md) | Generic keys of the datatype | | `id` | [`DataTypeID!`](../scalar/datatypeid.md) | Global ID of this DataType | | `identifier` | [`String!`](../scalar/string.md) | The identifier scoped to the namespace | +| `name` | [`TranslationConnection!`](../object/translationconnection.md) | Names of the flow type setting | | `namespace` | [`Namespace`](../object/namespace.md) | The namespace where this datatype belongs to | +| `parent` | [`DataTypeIdentifier`](../union/datatypeidentifier.md) | The parent datatype | +| `rules` | [`DataTypeRuleConnection!`](../object/datatyperuleconnection.md) | Rules of the datatype | | `updatedAt` | [`Time!`](../scalar/time.md) | Time when this DataType was last updated | | `variant` | [`DataTypeVariant!`](../enum/datatypevariant.md) | The type of the datatype | diff --git a/docs/graphql/object/datatyperule.md b/docs/graphql/object/datatyperule.md new file mode 100644 index 00000000..7a89668a --- /dev/null +++ b/docs/graphql/object/datatyperule.md @@ -0,0 +1,15 @@ +--- +title: DataTypeRule +--- + +Represents a rule that can be applied to a data type. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `config` | [`Config!`](../union/config.md) | The configuration of the rule | +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this DataTypeRule was created | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this DataTypeRule was last updated | +| `variant` | [`DataTypeRulesDataTypeRuleVariant!`](../enum/datatyperulesdatatyperulevariant.md) | The type of the rule | + diff --git a/docs/graphql/object/datatyperuleconnection.md b/docs/graphql/object/datatyperuleconnection.md new file mode 100644 index 00000000..ef4ae1f1 --- /dev/null +++ b/docs/graphql/object/datatyperuleconnection.md @@ -0,0 +1,15 @@ +--- +title: DataTypeRuleConnection +--- + +The connection type for DataTypeRule. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `count` | [`Int!`](../scalar/int.md) | Total count of collection. | +| `edges` | [`[DataTypeRuleEdge]`](../object/datatyperuleedge.md) | A list of edges. | +| `nodes` | [`[DataTypeRule]`](../object/datatyperule.md) | A list of nodes. | +| `pageInfo` | [`PageInfo!`](../object/pageinfo.md) | Information to aid in pagination. | + diff --git a/docs/graphql/object/datatyperuleedge.md b/docs/graphql/object/datatyperuleedge.md new file mode 100644 index 00000000..7a191f2f --- /dev/null +++ b/docs/graphql/object/datatyperuleedge.md @@ -0,0 +1,13 @@ +--- +title: DataTypeRuleEdge +--- + +An edge in a connection. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `cursor` | [`String!`](../scalar/string.md) | A cursor for use in pagination. | +| `node` | [`DataTypeRule`](../object/datatyperule.md) | The item at the end of the edge. | + diff --git a/docs/graphql/object/itemofcollectionconfig.md b/docs/graphql/object/itemofcollectionconfig.md new file mode 100644 index 00000000..2de160c2 --- /dev/null +++ b/docs/graphql/object/itemofcollectionconfig.md @@ -0,0 +1,12 @@ +--- +title: ItemOfCollectionConfig +--- + +Represents a rule that can be applied to a data type. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `items` | [`[JSON!]`](../scalar/json.md) | The items that can be configured for this rule. | + diff --git a/docs/graphql/object/numberrangeconfig.md b/docs/graphql/object/numberrangeconfig.md new file mode 100644 index 00000000..a4c1bf28 --- /dev/null +++ b/docs/graphql/object/numberrangeconfig.md @@ -0,0 +1,14 @@ +--- +title: NumberRangeConfig +--- + +Represents a rule that can be applied to a data type. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `from` | [`Int!`](../scalar/int.md) | The minimum value of the range | +| `steps` | [`Int`](../scalar/int.md) | The step value for the range, if applicable | +| `to` | [`Int!`](../scalar/int.md) | The maximum value of the range | + diff --git a/docs/graphql/object/regexconfig.md b/docs/graphql/object/regexconfig.md new file mode 100644 index 00000000..c482e8e6 --- /dev/null +++ b/docs/graphql/object/regexconfig.md @@ -0,0 +1,12 @@ +--- +title: RegexConfig +--- + +Represents a rule that can be applied to a data type. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `pattern` | [`String!`](../scalar/string.md) | The regex pattern to match against the data type value. | + diff --git a/docs/graphql/union/config.md b/docs/graphql/union/config.md new file mode 100644 index 00000000..815cec37 --- /dev/null +++ b/docs/graphql/union/config.md @@ -0,0 +1,13 @@ +--- +title: Config +--- + +Represents a rule that can be applied to a data type. + +## Possible types + +- [`ContainsKeyConfig`](../object/containskeyconfig.md) +- [`ContainsTypeConfig`](../object/containstypeconfig.md) +- [`ItemOfCollectionConfig`](../object/itemofcollectionconfig.md) +- [`NumberRangeConfig`](../object/numberrangeconfig.md) +- [`RegexConfig`](../object/regexconfig.md) diff --git a/spec/factories/generic_combination_strategies.rb b/spec/factories/generic_combination_strategies.rb new file mode 100644 index 00000000..c59759ed --- /dev/null +++ b/spec/factories/generic_combination_strategies.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :generic_combination_strategy do + type { 1 } + generic_mapper { nil } + end +end diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index 36a7fdc9..ba3ea1e7 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -4,6 +4,7 @@ factory :generic_mapper do runtime target { nil } - source { nil } + sources { nil } + generic_combination_strategies { [] } end end diff --git a/spec/graphql/types/data_type_type_spec.rb b/spec/graphql/types/data_type_type_spec.rb index 87f7bc76..6f726624 100644 --- a/spec/graphql/types/data_type_type_spec.rb +++ b/spec/graphql/types/data_type_type_spec.rb @@ -9,6 +9,10 @@ identifier variant id + rules + name + parent + genericKeys createdAt updatedAt ] diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index a2270dcd..01dd84c3 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -8,8 +8,9 @@ it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to have_many(:generic_mappers).inverse_of(:source) } - it { is_expected.to have_many(:function_generic_mappers).inverse_of(:source) } + it { is_expected.to belong_to(:generic_mapper).optional.inverse_of(:sources) } + it { is_expected.to belong_to(:function_generic_mapper).optional.inverse_of(:sources) } + it { is_expected.to have_many(:child_types).class_name('DataType').inverse_of(:parent_type) } end describe 'validations' do diff --git a/spec/models/data_type_spec.rb b/spec/models/data_type_spec.rb index 4f400b21..083373b0 100644 --- a/spec/models/data_type_spec.rb +++ b/spec/models/data_type_spec.rb @@ -6,9 +6,8 @@ subject { create(:data_type) } describe 'associations' do - it { is_expected.to belong_to(:parent_type).class_name('DataType').inverse_of(:child_types).optional } + it { is_expected.to belong_to(:parent_type).class_name('DataTypeIdentifier').inverse_of(:child_types).optional } it { is_expected.to belong_to(:runtime).inverse_of(:data_types) } - it { is_expected.to have_many(:child_types).class_name('DataType').inverse_of(:parent_type) } it { is_expected.to have_many(:names).class_name('Translation') } it { is_expected.to have_many(:rules).class_name('DataTypeRule').inverse_of(:data_type) } end @@ -18,9 +17,9 @@ it 'detects recursions' do dt1 = create(:data_type) - dt2 = create(:data_type, parent_type: dt1) + dt2 = create(:data_type, parent_type: create(:data_type_identifier, data_type: dt1)) - dt1.parent_type = dt2 + dt1.parent_type = create(:data_type_identifier, data_type: dt2) expect(dt1).not_to be_valid expect(dt1.errors.added?(:parent_type, :recursion)).to be(true) @@ -28,11 +27,11 @@ it 'detects recursions over multiple levels' do dt1 = create(:data_type) - dt2 = create(:data_type, parent_type: dt1) - dt3 = create(:data_type, parent_type: dt2) - dt4 = create(:data_type, parent_type: dt3) + dt2 = create(:data_type, parent_type: create(:data_type_identifier, data_type: dt1)) + dt3 = create(:data_type, parent_type: create(:data_type_identifier, data_type: dt2)) + dt4 = create(:data_type, parent_type: create(:data_type_identifier, data_type: dt3)) - dt1.parent_type = dt4 + dt1.parent_type = create(:data_type_identifier, data_type: dt4) expect(dt1.valid?).to be(false) expect(dt1.errors.added?(:parent_type, :recursion)).to be(true) @@ -40,7 +39,7 @@ it 'detects direct recursions' do dt1 = create(:data_type) - dt1.parent_type = dt1 + dt1.parent_type = create(:data_type_identifier, data_type: dt1) expect(dt1.valid?).to be(false) expect(dt1.errors.added?(:parent_type, :recursion)).to be(true) diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index 6dd7b9b6..4c3aa23e 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -4,7 +4,7 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do - it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier').inverse_of(:function_generic_mappers) } + it { is_expected.to have_many(:sources).class_name('DataTypeIdentifier').inverse_of(:function_generic_mapper) } it { is_expected.to belong_to(:runtime_parameter_definition).optional } it { diff --git a/spec/models/generic_combination_strategy_spec.rb b/spec/models/generic_combination_strategy_spec.rb new file mode 100644 index 00000000..0d9b7eac --- /dev/null +++ b/spec/models/generic_combination_strategy_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe GenericCombinationStrategy do + describe 'associations' do + it { is_expected.to belong_to(:generic_mapper) } + end + + describe 'enums' do + it 'defines the correct enum values' do + expect(described_class.types).to eq({ + 'and' => 1, + 'or' => 2, + }) + end + end +end diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index 843a3649..b2481b8f 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -7,6 +7,11 @@ describe 'associations' do it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to belong_to(:source).class_name('DataTypeIdentifier') } + it { is_expected.to have_many(:sources).class_name('DataTypeIdentifier').inverse_of(:generic_mapper) } + + it { + is_expected.to have_many(:generic_combination_strategies) + .class_name('GenericCombinationStrategy').inverse_of(:generic_mapper) + } end end diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 8aada144..06dcb862 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -39,14 +39,15 @@ return_type_identifier: { generic_type: { data_type_identifier: return_type.generic_type.data_type.identifier, - generic_mappers: [{ source: { generic_key: 'T' }, target: 'V' }], + generic_mappers: [{ source: [{ generic_key: 'T' }], target: 'V', generic_combinations: [] }], }, }, generic_mappers: [ { - source: { generic_key: 'X' }, + source: [{ generic_key: 'X' }], target: 'Y', parameter_id: 'some_id', + generic_combinations: [], } ], error_type_identifiers: [error_type.identifier], @@ -80,7 +81,7 @@ expect(stub.update(message, authorization(runtime)).success).to be(true) expect(GenericMapper.count).to eq(1) - expect(GenericMapper.last.source.generic_key).to eq('T') + expect(GenericMapper.last.sources.first.generic_key).to eq('T') expect(GenericMapper.last.target).to eq('V') expect(GenericType.count).to eq(1) @@ -116,7 +117,7 @@ expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) expect(FunctionGenericMapper.count).to eq(1) - expect(FunctionGenericMapper.last.source.generic_key).to eq('X') + expect(FunctionGenericMapper.last.sources.first.generic_key).to eq('X') expect(FunctionGenericMapper.last.target).to eq('Y') expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end diff --git a/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb index a34ecf04..6ea43f73 100644 --- a/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb @@ -51,14 +51,22 @@ context 'when parent type is set' do let(:parent_data_type) { create(:data_type, runtime: runtime) } - let(:data_type) { create(:data_type, runtime: runtime, parent_type: parent_data_type) } + let(:data_type) do + create(:data_type, runtime: runtime, parent_type: create(:data_type_identifier, + runtime: runtime, + data_type: parent_data_type)) + end it { expect(service_response).to be_nil } end context 'when parent type is set and invalid' do let(:parent_data_type) { create(:data_type) } - let(:data_type) { create(:data_type, runtime: runtime, parent_type: parent_data_type) } + let(:data_type) do + create(:data_type, runtime: runtime, parent_type: create(:data_type_identifier, + runtime: runtime, + data_type: parent_data_type)) + end it { expect(service_response.payload).to eq(:runtime_mismatch) } end diff --git a/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb new file mode 100644 index 00000000..3f118045 --- /dev/null +++ b/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'rails_helper' + +Rspec.describe Namespaces::Projects::Flows::Validation::NodeFunction::GenericMapperValidationService do + subject(:service_response) do + described_class.new(create_authentication(current_user), flow, parameter, generic_mapper).execute + end + + include_context 'with mocked services' + + let(:mocked_service_expectations) do + { + Namespaces::Projects::Flows::Validation::DataType::DataTypeIdentifierValidationService => 1, + } + end + + let(:current_user) { create(:user) } + let(:runtime) { create(:runtime) } + let(:namespace_project) { create(:namespace_project, primary_runtime: runtime) } + let(:flow) { create(:flow, project: namespace_project, starting_node: node) } + + let(:parameter) do + create(:node_parameter, + runtime_parameter: + create(:runtime_parameter_definition, + data_type: create(:data_type_identifier, + generic_type: create(:generic_type, + data_type: create(:data_type), + generic_mappers: [generic_mapper], + runtime: runtime))), + literal_value: nil, + function_value: create(:node_function)) + end + let(:node) do + create(:node_function, + runtime_function: create(:runtime_function_definition, + generic_keys: ['T'], + runtime: runtime), + node_parameters: [ + parameter + ]) + end + let(:data_type_identifier) do + create(:data_type_identifier, generic_key: 'T', runtime: runtime) + end + let(:generic_mapper) do + create(:generic_mapper, sources: [data_type_identifier], target: 'T') + end + + context 'when generic mapper points to a existing generic_key' do + it { expect(service_response).to be_nil } + end +end diff --git a/spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb index 5206b6e5..e0d7f5f2 100644 --- a/spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb @@ -63,12 +63,12 @@ tertiary_level: tertiary_level) end - context 'with horizontal reference' do + context 'with secondary level' do let(:secondary_level) { 0 } it { expect(service_response).to be_nil } - context 'with horizontal reference out of bounds' do + context 'with secondary level out of bounds' do let(:secondary_level) { 2 } it { expect(service_response).to be_error } From 360e366c59e7b22f160cc1a690372998ac8051ff Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Sat, 31 May 2025 01:01:10 +0200 Subject: [PATCH 40/54] Add Zone.Identifier to .gitignore to prevent unwanted file tracking --- .gitignore | 1 + .../DataTypeContainsKeyRuleConfig.json:Zone.Identifier | 0 .../DataTypeContainsTypeRuleConfig.json:Zone.Identifier | 0 app/models/json_schemas/DataTypeIdentifier.json:Zone.Identifier | 0 .../DataTypeItemOfCollectionRuleConfig.json:Zone.Identifier | 0 .../DataTypeNumberRangeRuleConfig.json:Zone.Identifier | 0 .../json_schemas/DataTypeRegexRuleConfig.json:Zone.Identifier | 0 7 files changed, 1 insertion(+) delete mode 100644 app/models/json_schemas/DataTypeContainsKeyRuleConfig.json:Zone.Identifier delete mode 100644 app/models/json_schemas/DataTypeContainsTypeRuleConfig.json:Zone.Identifier delete mode 100644 app/models/json_schemas/DataTypeIdentifier.json:Zone.Identifier delete mode 100644 app/models/json_schemas/DataTypeItemOfCollectionRuleConfig.json:Zone.Identifier delete mode 100644 app/models/json_schemas/DataTypeNumberRangeRuleConfig.json:Zone.Identifier delete mode 100644 app/models/json_schemas/DataTypeRegexRuleConfig.json:Zone.Identifier diff --git a/.gitignore b/.gitignore index 6e3d8f37..c95bcedc 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ *.njsproj *.sln *.sw? +**/*Zone.Identifier ################ ## diff --git a/app/models/json_schemas/DataTypeContainsKeyRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeContainsKeyRuleConfig.json:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/app/models/json_schemas/DataTypeContainsTypeRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeContainsTypeRuleConfig.json:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/app/models/json_schemas/DataTypeIdentifier.json:Zone.Identifier b/app/models/json_schemas/DataTypeIdentifier.json:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/app/models/json_schemas/DataTypeItemOfCollectionRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeItemOfCollectionRuleConfig.json:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/app/models/json_schemas/DataTypeNumberRangeRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeNumberRangeRuleConfig.json:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 diff --git a/app/models/json_schemas/DataTypeRegexRuleConfig.json:Zone.Identifier b/app/models/json_schemas/DataTypeRegexRuleConfig.json:Zone.Identifier deleted file mode 100644 index e69de29b..00000000 From a09d8b264983c655f8a864df0cfbc58c432ac335 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Sat, 31 May 2025 01:33:19 +0200 Subject: [PATCH 41/54] Refactor generic mapper associations and update Gemfile for local path, enhance validation services --- Gemfile | 2 +- Gemfile.lock | 10 +- app/models/data_type_identifier.rb | 4 +- app/models/function_definition.rb | 3 + app/models/function_generic_mapper.rb | 4 +- app/models/generic_combination_strategy.rb | 3 +- app/models/generic_mapper.rb | 2 +- .../projects/flows/create_service.rb | 2 +- .../generic_mapper_validation_service.rb | 6 +- .../runtimes/data_types/update_service.rb | 63 +- .../update_service.rb | 10 +- ...4_create_generic_combination_strategies.rb | 6 +- db/structure.sql | 2820 +++-------------- spec/factories/generic_mappers.rb | 2 +- spec/models/data_type_identifier_spec.rb | 4 +- spec/models/function_definition_spec.rb | 5 + spec/models/function_generic_mapper_spec.rb | 2 +- .../generic_combination_strategy_spec.rb | 3 +- spec/models/generic_mapper_spec.rb | 2 +- .../sagittarius/data_type_service_spec.rb | 6 +- ...untime_function_definition_service_spec.rb | 4 +- .../generic_mapper_validation_service_spec.rb | 2 +- 22 files changed, 559 insertions(+), 2406 deletions(-) diff --git a/Gemfile b/Gemfile index 704d9b81..3eca0b2e 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.29' +gem 'tucana', '0.0.0', path: '../tucana/build/ruby' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index e8e27776..ac19d5d5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,9 @@ +PATH + remote: ../tucana/build/ruby + specs: + tucana (0.0.0) + grpc (~> 1.64) + GEM remote: https://rubygems.org/ specs: @@ -362,8 +368,6 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) - tucana (0.0.29) - grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.6.0) @@ -416,7 +420,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.29) + tucana (= 0.0.0)! tzinfo-data RUBY VERSION diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb index 526813a5..670a80bf 100644 --- a/app/models/data_type_identifier.rb +++ b/app/models/data_type_identifier.rb @@ -4,9 +4,9 @@ class DataTypeIdentifier < ApplicationRecord belongs_to :data_type, optional: true, inverse_of: :data_type_identifiers belongs_to :generic_type, optional: true, inverse_of: :data_type_identifiers belongs_to :runtime, inverse_of: :data_type_identifiers - belongs_to :generic_mapper, class_name: 'GenericMapper', optional: true, inverse_of: :sources + belongs_to :generic_mapper, class_name: 'GenericMapper', optional: true, inverse_of: :source belongs_to :function_generic_mapper, class_name: 'FunctionGenericMapper', - optional: true, inverse_of: :sources + optional: true, inverse_of: :source has_many :child_types, class_name: 'DataType', inverse_of: :parent_type diff --git a/app/models/function_definition.rb b/app/models/function_definition.rb index 389961a7..5d58eb93 100644 --- a/app/models/function_definition.rb +++ b/app/models/function_definition.rb @@ -4,6 +4,9 @@ class FunctionDefinition < ApplicationRecord belongs_to :runtime_function_definition belongs_to :return_type, class_name: 'DataTypeIdentifier', optional: true + has_many :generic_combination_strategies, + class_name: 'GenericCombinationStrategy', inverse_of: :function_generic_mapper + has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :documentations, -> { by_purpose(:documentation) }, class_name: 'Translation', as: :owner, inverse_of: :owner diff --git a/app/models/function_generic_mapper.rb b/app/models/function_generic_mapper.rb index a8c9644d..f1373315 100644 --- a/app/models/function_generic_mapper.rb +++ b/app/models/function_generic_mapper.rb @@ -6,7 +6,9 @@ class FunctionGenericMapper < ApplicationRecord belongs_to :runtime_parameter_definition, class_name: 'RuntimeParameterDefinition', optional: true, inverse_of: :function_generic_mappers - has_many :sources, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mapper + has_many :source, class_name: 'DataTypeIdentifier', inverse_of: :function_generic_mapper + has_many :generic_combination_strategies, + class_name: 'GenericCombinationStrategy', inverse_of: :function_generic_mapper validates :target, presence: true end diff --git a/app/models/generic_combination_strategy.rb b/app/models/generic_combination_strategy.rb index 66c58542..092e5dcb 100644 --- a/app/models/generic_combination_strategy.rb +++ b/app/models/generic_combination_strategy.rb @@ -6,7 +6,8 @@ class GenericCombinationStrategy < ApplicationRecord or: 2, }.with_indifferent_access - belongs_to :generic_mapper + belongs_to :generic_mapper, optional: true, inverse_of: :generic_combination_strategies + belongs_to :function_generic_mapper, optional: true, inverse_of: :generic_combination_strategies enum :type, TYPES, prefix: :type end diff --git a/app/models/generic_mapper.rb b/app/models/generic_mapper.rb index cb7fbf5c..1597dd69 100644 --- a/app/models/generic_mapper.rb +++ b/app/models/generic_mapper.rb @@ -5,7 +5,7 @@ class GenericMapper < ApplicationRecord belongs_to :runtime, inverse_of: :generic_mappers belongs_to :runtime_parameter_definition, optional: true, inverse_of: :generic_mappers - has_many :sources, class_name: 'DataTypeIdentifier', inverse_of: :generic_mapper + has_many :source, class_name: 'DataTypeIdentifier', inverse_of: :generic_mapper has_many :generic_combination_strategies, class_name: 'GenericCombinationStrategy', inverse_of: :generic_mapper validates :target, presence: true diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb index 313a1495..471cdd09 100644 --- a/app/services/namespaces/projects/flows/create_service.rb +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -134,7 +134,7 @@ def get_data_type_identifier(identifier) mappers = identifier.generic_type.mappers.map do |mapper| GenericMapper.create( generic_mapper_id: mapper.generic_mapper_id, - sources: mapper.sources, + source: mapper.source, target: mapper.target ) end diff --git a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb index 0e14b645..7955cb7c 100644 --- a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb +++ b/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb @@ -35,7 +35,11 @@ def execute ) end - generic_mapper.sources.each do |source| + generic_mapper.generic_combination_strategies.each do |_strategy| + # TODO: idk + end + + generic_mapper.source.each do |source| Namespaces::Projects::Flows::Validation::DataType::DataTypeIdentifierValidationService.new( current_authentication, flow, diff --git a/app/services/runtimes/data_types/update_service.rb b/app/services/runtimes/data_types/update_service.rb index c159e0b2..c9e61cd9 100644 --- a/app/services/runtimes/data_types/update_service.rb +++ b/app/services/runtimes/data_types/update_service.rb @@ -32,14 +32,14 @@ def execute def sort_data_types(data_types) # types without parent are already "in order" because they don't have a dependency - sorted_types = data_types.reject { |dt| dt.parent_type_identifier.present? } + sorted_types = data_types.reject { |dt| dt.parent_type.present? } unsorted_types = data_types - sorted_types unsorted_types.size.times do # find the next datatype that doesn't have a dependency on an unsorted type next_datatype = unsorted_types.find do |to_sort| unsorted_types.none? do |to_search| - to_sort.parent_type_identifier == to_search.identifier + to_sort.parent_type&.data_type_identifier == to_search.identifier end end sorted_types << next_datatype @@ -49,20 +49,69 @@ def sort_data_types(data_types) sorted_types + unsorted_types # any unsorted types also need to be processed. They might still fail validations end - def update_datatype(data_type, _t) + def update_datatype(data_type, t) db_object = DataType.find_or_initialize_by(runtime: current_runtime, identifier: data_type.identifier) db_object.removed_at = nil db_object.variant = data_type.variant.to_s.downcase - if data_type.parent_type_identifier.present? - # db_object.parent_type = find_datatype(data_type.parent_type_identifier, t) - # TODO: wait for parenttype get properly introduced in grpc - end + db_object.parent_type = find_data_type_identifier(data_type.parent_type, t) if data_type.parent_type.present? db_object.rules = update_rules(data_type.rules, db_object) db_object.names = update_translations(data_type.name, db_object.names) db_object.generic_keys = data_type.generic_keys.to_a db_object.save end + def find_data_type_identifier(identifier, t) + if identifier.data_type_identifier.present? + return create_data_type_identifier(t, data_type_id: find_datatype(identifier.data_type_identifier, t).id) + end + + if identifier.generic_type.present? + data_type = find_datatype(identifier.generic_type.data_type_identifier, t) + + generic_type = GenericType.find_by( + runtime_id: current_runtime.id, + data_type: data_type + ) + if generic_type.nil? + generic_type = GenericType.create( + runtime_id: current_runtime.id, + data_type: data_type + ) + end + + if generic_type.nil? + t.rollback_and_return! ServiceResponse.error( + message: "Could not find generic type with identifier #{identifier.generic_type.data_type_identifier}", + payload: :no_generic_type_for_identifier + ) + end + + generic_type.assign_attributes(generic_mappers: update_mappers(identifier.generic_type.generic_mappers, nil, + t)) + + return create_data_type_identifier(t, generic_type_id: generic_type.id) + end + return create_data_type_identifier(t, generic_key: identifier.generic_key) if identifier.generic_key.present? + + raise ArgumentError, "Invalid identifier: #{identifier.inspect}" + end + + def create_data_type_identifier(t, **kwargs) + data_type_identifier = DataTypeIdentifier.find_by(runtime_id: current_runtime.id, **kwargs) + if data_type_identifier.nil? + data_type_identifier = DataTypeIdentifier.create_or_find_by(runtime_id: current_runtime.id, **kwargs) + end + + if data_type_identifier.nil? + t.rollback_and_return! ServiceResponse.error( + message: "Could not find datatype identifier with #{kwargs}", + payload: :no_datatype_identifier_for_generic_key + ) + end + + data_type_identifier + end + def find_datatype(identifier, t) data_type = DataType.find_or_initialize_by(runtime: current_runtime, identifier: identifier) diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 713197e9..80b15125 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -74,7 +74,7 @@ def update_mappers(generic_mappers, runtime_function_definition, t) if generic_mapper.is_a? Tucana::Shared::GenericMapper mapper = GenericMapper.create_or_find_by(runtime: current_runtime, target: generic_mapper.target, - sources: generic_mapper.sources.map do |source| + source: generic_mapper.source.map do |source| find_data_type_identifier(source, generic_mappers, t) end) end @@ -82,7 +82,7 @@ def update_mappers(generic_mappers, runtime_function_definition, t) mapper = FunctionGenericMapper.create_or_find_by( runtime_id: current_runtime.id, runtime_function_definition: runtime_function_definition, - sources: generic_mapper.sources.map { |source| find_data_type_identifier(source, generic_mappers, t) }, + source: generic_mapper.source.map { |source| find_data_type_identifier(source, generic_mappers, t) }, target: generic_mapper.target, parameter_id: generic_mapper.parameter_id ) @@ -98,16 +98,12 @@ def update_mappers(generic_mappers, runtime_function_definition, t) end end - def find_data_type_identifier(identifier, generic_mappers, t) + def find_data_type_identifier(identifier, _generic_mappers, t) if identifier.data_type_identifier.present? return create_data_type_identifier(t, data_type_id: find_data_type(identifier.data_type_identifier, t).id) end if identifier.generic_type.present? - arr = generic_mappers.to_a - identifier.generic_type.generic_mappers.each do |generic_mapper| - arr << generic_mapper - end data_type = find_data_type(identifier.generic_type.data_type_identifier, t) generic_type = GenericType.find_by( diff --git a/db/migrate/20250530213244_create_generic_combination_strategies.rb b/db/migrate/20250530213244_create_generic_combination_strategies.rb index 9ff39137..1655ab92 100644 --- a/db/migrate/20250530213244_create_generic_combination_strategies.rb +++ b/db/migrate/20250530213244_create_generic_combination_strategies.rb @@ -4,10 +4,14 @@ class CreateGenericCombinationStrategies < Code0::ZeroTrack::Database::Migration def change create_table :generic_combination_strategies do |t| t.integer :type - t.references :generic_mapper, null: false, foreign_key: { + t.references :generic_mapper, null: true, foreign_key: { to_table: :generic_mappers, on_delete: :cascade, } + t.references :function_generic_mapper, null: true, foreign_key: { + to_table: :function_generic_mappers, + on_delete: :cascade, + } t.timestamps_with_timezone end diff --git a/db/structure.sql b/db/structure.sql index 2a1d6703..6f005916 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1,23 +1,4 @@ -SET statement_timeout = 0; -SET lock_timeout = 0; -SET idle_in_transaction_session_timeout = 0; -SET client_encoding = 'UTF8'; -SET standard_conforming_strings = on; -SELECT pg_catalog.set_config('search_path', '', false); -SET check_function_bodies = false; -SET xmloption = content; -SET client_min_messages = warning; -SET row_security = off; - -SET default_tablespace = ''; - -SET default_table_access_method = heap; - --- --- Name: active_storage_attachments; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.active_storage_attachments ( +CREATE TABLE active_storage_attachments ( id bigint NOT NULL, name character varying NOT NULL, record_type character varying NOT NULL, @@ -27,31 +8,16 @@ CREATE TABLE public.active_storage_attachments ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: active_storage_attachments_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.active_storage_attachments_id_seq +CREATE SEQUENCE active_storage_attachments_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE active_storage_attachments_id_seq OWNED BY active_storage_attachments.id; --- --- Name: active_storage_attachments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.active_storage_attachments_id_seq OWNED BY public.active_storage_attachments.id; - - --- --- Name: active_storage_blobs; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.active_storage_blobs ( +CREATE TABLE active_storage_blobs ( id bigint NOT NULL, key character varying NOT NULL, filename character varying NOT NULL, @@ -64,31 +30,16 @@ CREATE TABLE public.active_storage_blobs ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: active_storage_blobs_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.active_storage_blobs_id_seq +CREATE SEQUENCE active_storage_blobs_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE active_storage_blobs_id_seq OWNED BY active_storage_blobs.id; --- --- Name: active_storage_blobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.active_storage_blobs_id_seq OWNED BY public.active_storage_blobs.id; - - --- --- Name: active_storage_variant_records; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.active_storage_variant_records ( +CREATE TABLE active_storage_variant_records ( id bigint NOT NULL, blob_id bigint NOT NULL, variation_digest character varying NOT NULL, @@ -96,31 +47,16 @@ CREATE TABLE public.active_storage_variant_records ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: active_storage_variant_records_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.active_storage_variant_records_id_seq +CREATE SEQUENCE active_storage_variant_records_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE active_storage_variant_records_id_seq OWNED BY active_storage_variant_records.id; --- --- Name: active_storage_variant_records_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.active_storage_variant_records_id_seq OWNED BY public.active_storage_variant_records.id; - - --- --- Name: application_settings; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.application_settings ( +CREATE TABLE application_settings ( id bigint NOT NULL, setting integer NOT NULL, value jsonb NOT NULL, @@ -128,43 +64,23 @@ CREATE TABLE public.application_settings ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: application_settings_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.application_settings_id_seq +CREATE SEQUENCE application_settings_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE application_settings_id_seq OWNED BY application_settings.id; --- --- Name: application_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.application_settings_id_seq OWNED BY public.application_settings.id; - - --- --- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.ar_internal_metadata ( +CREATE TABLE ar_internal_metadata ( key character varying NOT NULL, value character varying, created_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL ); - --- --- Name: audit_events; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.audit_events ( +CREATE TABLE audit_events ( id bigint NOT NULL, author_id bigint NOT NULL, entity_id integer NOT NULL, @@ -178,31 +94,16 @@ CREATE TABLE public.audit_events ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: audit_events_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.audit_events_id_seq +CREATE SEQUENCE audit_events_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE audit_events_id_seq OWNED BY audit_events.id; --- --- Name: audit_events_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.audit_events_id_seq OWNED BY public.audit_events.id; - - --- --- Name: backup_codes; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.backup_codes ( +CREATE TABLE backup_codes ( id bigint NOT NULL, token text NOT NULL, user_id bigint NOT NULL, @@ -211,31 +112,16 @@ CREATE TABLE public.backup_codes ( CONSTRAINT check_458fe46218 CHECK ((char_length(token) <= 10)) ); - --- --- Name: backup_codes_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.backup_codes_id_seq +CREATE SEQUENCE backup_codes_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE backup_codes_id_seq OWNED BY backup_codes.id; --- --- Name: backup_codes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.backup_codes_id_seq OWNED BY public.backup_codes.id; - - --- --- Name: data_type_identifiers; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.data_type_identifiers ( +CREATE TABLE data_type_identifiers ( id bigint NOT NULL, generic_key text, data_type_id bigint, @@ -248,31 +134,16 @@ CREATE TABLE public.data_type_identifiers ( CONSTRAINT check_480d44acbd CHECK ((num_nonnulls(generic_key, data_type_id, generic_type_id) = 1)) ); - --- --- Name: data_type_identifiers_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.data_type_identifiers_id_seq +CREATE SEQUENCE data_type_identifiers_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE data_type_identifiers_id_seq OWNED BY data_type_identifiers.id; --- --- Name: data_type_identifiers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.data_type_identifiers_id_seq OWNED BY public.data_type_identifiers.id; - - --- --- Name: data_type_rules; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.data_type_rules ( +CREATE TABLE data_type_rules ( id bigint NOT NULL, data_type_id bigint NOT NULL, variant integer NOT NULL, @@ -281,31 +152,16 @@ CREATE TABLE public.data_type_rules ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: data_type_rules_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.data_type_rules_id_seq +CREATE SEQUENCE data_type_rules_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE data_type_rules_id_seq OWNED BY data_type_rules.id; --- --- Name: data_type_rules_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.data_type_rules_id_seq OWNED BY public.data_type_rules.id; - - --- --- Name: data_types; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.data_types ( +CREATE TABLE data_types ( id bigint NOT NULL, identifier text NOT NULL, variant integer NOT NULL, @@ -319,31 +175,16 @@ CREATE TABLE public.data_types ( CONSTRAINT check_3a7198812e CHECK ((char_length(identifier) <= 50)) ); - --- --- Name: data_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.data_types_id_seq +CREATE SEQUENCE data_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE data_types_id_seq OWNED BY data_types.id; --- --- Name: data_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.data_types_id_seq OWNED BY public.data_types.id; - - --- --- Name: flow_settings; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.flow_settings ( +CREATE TABLE flow_settings ( id bigint NOT NULL, flow_id bigint, flow_setting_id text NOT NULL, @@ -352,31 +193,16 @@ CREATE TABLE public.flow_settings ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: flow_settings_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.flow_settings_id_seq +CREATE SEQUENCE flow_settings_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE flow_settings_id_seq OWNED BY flow_settings.id; --- --- Name: flow_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.flow_settings_id_seq OWNED BY public.flow_settings.id; - - --- --- Name: flow_type_settings; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.flow_type_settings ( +CREATE TABLE flow_type_settings ( id bigint NOT NULL, flow_type_id bigint NOT NULL, identifier text NOT NULL, @@ -387,31 +213,16 @@ CREATE TABLE public.flow_type_settings ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: flow_type_settings_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.flow_type_settings_id_seq +CREATE SEQUENCE flow_type_settings_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE flow_type_settings_id_seq OWNED BY flow_type_settings.id; --- --- Name: flow_type_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.flow_type_settings_id_seq OWNED BY public.flow_type_settings.id; - - --- --- Name: flow_types; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.flow_types ( +CREATE TABLE flow_types ( id bigint NOT NULL, runtime_id bigint NOT NULL, identifier text NOT NULL, @@ -423,31 +234,16 @@ CREATE TABLE public.flow_types ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: flow_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.flow_types_id_seq +CREATE SEQUENCE flow_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE flow_types_id_seq OWNED BY flow_types.id; --- --- Name: flow_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.flow_types_id_seq OWNED BY public.flow_types.id; - - --- --- Name: flows; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.flows ( +CREATE TABLE flows ( id bigint NOT NULL, project_id bigint NOT NULL, flow_type_id bigint NOT NULL, @@ -458,31 +254,16 @@ CREATE TABLE public.flows ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: flows_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.flows_id_seq +CREATE SEQUENCE flows_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE flows_id_seq OWNED BY flows.id; --- --- Name: flows_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.flows_id_seq OWNED BY public.flows.id; - - --- --- Name: function_definitions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.function_definitions ( +CREATE TABLE function_definitions ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, @@ -490,31 +271,16 @@ CREATE TABLE public.function_definitions ( return_type_id bigint ); - --- --- Name: function_definitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.function_definitions_id_seq +CREATE SEQUENCE function_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; --- --- Name: function_definitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.function_definitions_id_seq OWNED BY public.function_definitions.id; - - --- --- Name: function_generic_mappers; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.function_generic_mappers ( +CREATE TABLE function_generic_mappers ( id bigint NOT NULL, target text NOT NULL, parameter_id text, @@ -525,63 +291,34 @@ CREATE TABLE public.function_generic_mappers ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: function_generic_mappers_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.function_generic_mappers_id_seq +CREATE SEQUENCE function_generic_mappers_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers.id; --- --- Name: function_generic_mappers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.function_generic_mappers_id_seq OWNED BY public.function_generic_mappers.id; - - --- --- Name: generic_combination_strategies; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.generic_combination_strategies ( +CREATE TABLE generic_combination_strategies ( id bigint NOT NULL, type integer, - generic_mapper_id bigint NOT NULL, + generic_mapper_id bigint, + function_generic_mapper_id bigint, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); - --- --- Name: generic_combination_strategies_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.generic_combination_strategies_id_seq +CREATE SEQUENCE generic_combination_strategies_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE generic_combination_strategies_id_seq OWNED BY generic_combination_strategies.id; --- --- Name: generic_combination_strategies_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.generic_combination_strategies_id_seq OWNED BY public.generic_combination_strategies.id; - - --- --- Name: generic_mappers; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.generic_mappers ( +CREATE TABLE generic_mappers ( id bigint NOT NULL, runtime_id bigint NOT NULL, target text NOT NULL, @@ -590,31 +327,16 @@ CREATE TABLE public.generic_mappers ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: generic_mappers_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.generic_mappers_id_seq +CREATE SEQUENCE generic_mappers_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; --- --- Name: generic_mappers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.generic_mappers_id_seq OWNED BY public.generic_mappers.id; - - --- --- Name: generic_types; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.generic_types ( +CREATE TABLE generic_types ( id bigint NOT NULL, runtime_id bigint NOT NULL, data_type_id bigint NOT NULL, @@ -622,31 +344,16 @@ CREATE TABLE public.generic_types ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: generic_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.generic_types_id_seq +CREATE SEQUENCE generic_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE generic_types_id_seq OWNED BY generic_types.id; --- --- Name: generic_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.generic_types_id_seq OWNED BY public.generic_types.id; - - --- --- Name: good_job_batches; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.good_job_batches ( +CREATE TABLE good_job_batches ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -663,12 +370,7 @@ CREATE TABLE public.good_job_batches ( jobs_finished_at timestamp with time zone ); - --- --- Name: good_job_executions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.good_job_executions ( +CREATE TABLE good_job_executions ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -685,12 +387,7 @@ CREATE TABLE public.good_job_executions ( duration interval ); - --- --- Name: good_job_processes; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.good_job_processes ( +CREATE TABLE good_job_processes ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -698,12 +395,7 @@ CREATE TABLE public.good_job_processes ( lock_type smallint ); - --- --- Name: good_job_settings; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.good_job_settings ( +CREATE TABLE good_job_settings ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, @@ -711,12 +403,7 @@ CREATE TABLE public.good_job_settings ( value jsonb ); - --- --- Name: good_jobs; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.good_jobs ( +CREATE TABLE good_jobs ( id uuid DEFAULT gen_random_uuid() NOT NULL, queue_name text, priority integer, @@ -743,12 +430,7 @@ CREATE TABLE public.good_jobs ( locked_at timestamp with time zone ); - --- --- Name: namespace_licenses; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespace_licenses ( +CREATE TABLE namespace_licenses ( id bigint NOT NULL, data text NOT NULL, created_at timestamp with time zone NOT NULL, @@ -756,31 +438,16 @@ CREATE TABLE public.namespace_licenses ( namespace_id bigint NOT NULL ); - --- --- Name: namespace_licenses_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespace_licenses_id_seq +CREATE SEQUENCE namespace_licenses_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespace_licenses_id_seq OWNED BY namespace_licenses.id; --- --- Name: namespace_licenses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespace_licenses_id_seq OWNED BY public.namespace_licenses.id; - - --- --- Name: namespace_member_roles; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespace_member_roles ( +CREATE TABLE namespace_member_roles ( id bigint NOT NULL, role_id bigint NOT NULL, member_id bigint NOT NULL, @@ -788,31 +455,16 @@ CREATE TABLE public.namespace_member_roles ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: namespace_member_roles_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespace_member_roles_id_seq +CREATE SEQUENCE namespace_member_roles_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespace_member_roles_id_seq OWNED BY namespace_member_roles.id; --- --- Name: namespace_member_roles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespace_member_roles_id_seq OWNED BY public.namespace_member_roles.id; - - --- --- Name: namespace_members; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespace_members ( +CREATE TABLE namespace_members ( id bigint NOT NULL, user_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, @@ -820,31 +472,16 @@ CREATE TABLE public.namespace_members ( namespace_id bigint NOT NULL ); - --- --- Name: namespace_members_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespace_members_id_seq +CREATE SEQUENCE namespace_members_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespace_members_id_seq OWNED BY namespace_members.id; --- --- Name: namespace_members_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespace_members_id_seq OWNED BY public.namespace_members.id; - - --- --- Name: namespace_project_runtime_assignments; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespace_project_runtime_assignments ( +CREATE TABLE namespace_project_runtime_assignments ( id bigint NOT NULL, runtime_id bigint NOT NULL, namespace_project_id bigint NOT NULL, @@ -852,31 +489,16 @@ CREATE TABLE public.namespace_project_runtime_assignments ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: namespace_project_runtime_assignments_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespace_project_runtime_assignments_id_seq +CREATE SEQUENCE namespace_project_runtime_assignments_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespace_project_runtime_assignments_id_seq OWNED BY namespace_project_runtime_assignments.id; --- --- Name: namespace_project_runtime_assignments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespace_project_runtime_assignments_id_seq OWNED BY public.namespace_project_runtime_assignments.id; - - --- --- Name: namespace_projects; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespace_projects ( +CREATE TABLE namespace_projects ( id bigint NOT NULL, name text NOT NULL, description text DEFAULT ''::text NOT NULL, @@ -888,31 +510,16 @@ CREATE TABLE public.namespace_projects ( CONSTRAINT check_a77bf7c685 CHECK ((char_length(description) <= 500)) ); - --- --- Name: namespace_projects_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespace_projects_id_seq +CREATE SEQUENCE namespace_projects_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespace_projects_id_seq OWNED BY namespace_projects.id; --- --- Name: namespace_projects_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespace_projects_id_seq OWNED BY public.namespace_projects.id; - - --- --- Name: namespace_role_abilities; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespace_role_abilities ( +CREATE TABLE namespace_role_abilities ( id bigint NOT NULL, ability integer NOT NULL, created_at timestamp with time zone NOT NULL, @@ -920,31 +527,16 @@ CREATE TABLE public.namespace_role_abilities ( namespace_role_id bigint NOT NULL ); - --- --- Name: namespace_role_abilities_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespace_role_abilities_id_seq +CREATE SEQUENCE namespace_role_abilities_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespace_role_abilities_id_seq OWNED BY namespace_role_abilities.id; --- --- Name: namespace_role_abilities_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespace_role_abilities_id_seq OWNED BY public.namespace_role_abilities.id; - - --- --- Name: namespace_role_project_assignments; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespace_role_project_assignments ( +CREATE TABLE namespace_role_project_assignments ( id bigint NOT NULL, role_id bigint NOT NULL, project_id bigint NOT NULL, @@ -952,31 +544,16 @@ CREATE TABLE public.namespace_role_project_assignments ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: namespace_role_project_assignments_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespace_role_project_assignments_id_seq +CREATE SEQUENCE namespace_role_project_assignments_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespace_role_project_assignments_id_seq OWNED BY namespace_role_project_assignments.id; --- --- Name: namespace_role_project_assignments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespace_role_project_assignments_id_seq OWNED BY public.namespace_role_project_assignments.id; - - --- --- Name: namespace_roles; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespace_roles ( +CREATE TABLE namespace_roles ( id bigint NOT NULL, name text NOT NULL, created_at timestamp with time zone NOT NULL, @@ -984,31 +561,16 @@ CREATE TABLE public.namespace_roles ( namespace_id bigint NOT NULL ); - --- --- Name: namespace_roles_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespace_roles_id_seq +CREATE SEQUENCE namespace_roles_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespace_roles_id_seq OWNED BY namespace_roles.id; --- --- Name: namespace_roles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespace_roles_id_seq OWNED BY public.namespace_roles.id; - - --- --- Name: namespaces; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.namespaces ( +CREATE TABLE namespaces ( id bigint NOT NULL, parent_type character varying NOT NULL, parent_id bigint NOT NULL, @@ -1016,31 +578,16 @@ CREATE TABLE public.namespaces ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: namespaces_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.namespaces_id_seq +CREATE SEQUENCE namespaces_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE namespaces_id_seq OWNED BY namespaces.id; --- --- Name: namespaces_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.namespaces_id_seq OWNED BY public.namespaces.id; - - --- --- Name: node_functions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.node_functions ( +CREATE TABLE node_functions ( id bigint NOT NULL, runtime_function_id bigint NOT NULL, next_node_id bigint, @@ -1048,31 +595,16 @@ CREATE TABLE public.node_functions ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: node_functions_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.node_functions_id_seq +CREATE SEQUENCE node_functions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE node_functions_id_seq OWNED BY node_functions.id; --- --- Name: node_functions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.node_functions_id_seq OWNED BY public.node_functions.id; - - --- --- Name: node_parameters; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.node_parameters ( +CREATE TABLE node_parameters ( id bigint NOT NULL, runtime_parameter_id bigint NOT NULL, node_function_id bigint NOT NULL, @@ -1084,31 +616,16 @@ CREATE TABLE public.node_parameters ( CONSTRAINT check_fdac0ea550 CHECK ((num_nonnulls(literal_value, reference_value_id, function_value_id) = 1)) ); - --- --- Name: node_parameters_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.node_parameters_id_seq +CREATE SEQUENCE node_parameters_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE node_parameters_id_seq OWNED BY node_parameters.id; --- --- Name: node_parameters_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.node_parameters_id_seq OWNED BY public.node_parameters.id; - - --- --- Name: organizations; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.organizations ( +CREATE TABLE organizations ( id bigint NOT NULL, name text NOT NULL, created_at timestamp with time zone NOT NULL, @@ -1116,31 +633,16 @@ CREATE TABLE public.organizations ( CONSTRAINT check_d130d769e0 CHECK ((char_length(name) <= 50)) ); - --- --- Name: organizations_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.organizations_id_seq +CREATE SEQUENCE organizations_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE organizations_id_seq OWNED BY organizations.id; --- --- Name: organizations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.organizations_id_seq OWNED BY public.organizations.id; - - --- --- Name: parameter_definitions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.parameter_definitions ( +CREATE TABLE parameter_definitions ( id bigint NOT NULL, runtime_parameter_definition_id bigint NOT NULL, default_value jsonb, @@ -1149,31 +651,16 @@ CREATE TABLE public.parameter_definitions ( data_type_id bigint ); - --- --- Name: parameter_definitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.parameter_definitions_id_seq +CREATE SEQUENCE parameter_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE parameter_definitions_id_seq OWNED BY parameter_definitions.id; --- --- Name: parameter_definitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.parameter_definitions_id_seq OWNED BY public.parameter_definitions.id; - - --- --- Name: reference_paths; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.reference_paths ( +CREATE TABLE reference_paths ( id bigint NOT NULL, path text, array_index integer, @@ -1182,31 +669,16 @@ CREATE TABLE public.reference_paths ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: reference_paths_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.reference_paths_id_seq +CREATE SEQUENCE reference_paths_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE reference_paths_id_seq OWNED BY reference_paths.id; --- --- Name: reference_paths_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.reference_paths_id_seq OWNED BY public.reference_paths.id; - - --- --- Name: reference_values; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.reference_values ( +CREATE TABLE reference_values ( id bigint NOT NULL, data_type_identifier_id bigint NOT NULL, primary_level integer NOT NULL, @@ -1216,31 +688,16 @@ CREATE TABLE public.reference_values ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: reference_values_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.reference_values_id_seq +CREATE SEQUENCE reference_values_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE reference_values_id_seq OWNED BY reference_values.id; --- --- Name: reference_values_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.reference_values_id_seq OWNED BY public.reference_values.id; - - --- --- Name: runtime_function_definition_error_types; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.runtime_function_definition_error_types ( +CREATE TABLE runtime_function_definition_error_types ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, data_type_id bigint NOT NULL, @@ -1248,31 +705,16 @@ CREATE TABLE public.runtime_function_definition_error_types ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: runtime_function_definition_error_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.runtime_function_definition_error_types_id_seq +CREATE SEQUENCE runtime_function_definition_error_types_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE runtime_function_definition_error_types_id_seq OWNED BY runtime_function_definition_error_types.id; --- --- Name: runtime_function_definition_error_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.runtime_function_definition_error_types_id_seq OWNED BY public.runtime_function_definition_error_types.id; - - --- --- Name: runtime_function_definitions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.runtime_function_definitions ( +CREATE TABLE runtime_function_definitions ( id bigint NOT NULL, runtime_id bigint NOT NULL, runtime_name text NOT NULL, @@ -1284,31 +726,16 @@ CREATE TABLE public.runtime_function_definitions ( CONSTRAINT check_fe8fff4f27 CHECK ((char_length(runtime_name) <= 50)) ); - --- --- Name: runtime_function_definitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.runtime_function_definitions_id_seq +CREATE SEQUENCE runtime_function_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE runtime_function_definitions_id_seq OWNED BY runtime_function_definitions.id; --- --- Name: runtime_function_definitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.runtime_function_definitions_id_seq OWNED BY public.runtime_function_definitions.id; - - --- --- Name: runtime_parameter_definitions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.runtime_parameter_definitions ( +CREATE TABLE runtime_parameter_definitions ( id bigint NOT NULL, runtime_function_definition_id bigint NOT NULL, runtime_name text NOT NULL, @@ -1320,31 +747,16 @@ CREATE TABLE public.runtime_parameter_definitions ( CONSTRAINT check_c1156ce358 CHECK ((char_length(runtime_name) <= 50)) ); - --- --- Name: runtime_parameter_definitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.runtime_parameter_definitions_id_seq +CREATE SEQUENCE runtime_parameter_definitions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE runtime_parameter_definitions_id_seq OWNED BY runtime_parameter_definitions.id; --- --- Name: runtime_parameter_definitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.runtime_parameter_definitions_id_seq OWNED BY public.runtime_parameter_definitions.id; - - --- --- Name: runtimes; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.runtimes ( +CREATE TABLE runtimes ( id bigint NOT NULL, name text NOT NULL, description text DEFAULT ''::text NOT NULL, @@ -1357,40 +769,20 @@ CREATE TABLE public.runtimes ( CONSTRAINT check_f3c2ba8db3 CHECK ((char_length(description) <= 500)) ); - --- --- Name: runtimes_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.runtimes_id_seq +CREATE SEQUENCE runtimes_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE runtimes_id_seq OWNED BY runtimes.id; --- --- Name: runtimes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.runtimes_id_seq OWNED BY public.runtimes.id; - - --- --- Name: schema_migrations; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.schema_migrations ( +CREATE TABLE schema_migrations ( version character varying NOT NULL ); - --- --- Name: translations; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.translations ( +CREATE TABLE translations ( id bigint NOT NULL, code text NOT NULL, content text NOT NULL, @@ -1401,31 +793,16 @@ CREATE TABLE public.translations ( purpose text ); - --- --- Name: translations_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.translations_id_seq +CREATE SEQUENCE translations_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE translations_id_seq OWNED BY translations.id; --- --- Name: translations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.translations_id_seq OWNED BY public.translations.id; - - --- --- Name: user_identities; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.user_identities ( +CREATE TABLE user_identities ( id bigint NOT NULL, user_id bigint NOT NULL, provider_id text NOT NULL, @@ -1434,31 +811,16 @@ CREATE TABLE public.user_identities ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: user_identities_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.user_identities_id_seq +CREATE SEQUENCE user_identities_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE user_identities_id_seq OWNED BY user_identities.id; --- --- Name: user_identities_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.user_identities_id_seq OWNED BY public.user_identities.id; - - --- --- Name: user_sessions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.user_sessions ( +CREATE TABLE user_sessions ( id bigint NOT NULL, user_id bigint NOT NULL, token text NOT NULL, @@ -1467,31 +829,16 @@ CREATE TABLE public.user_sessions ( updated_at timestamp with time zone NOT NULL ); - --- --- Name: user_sessions_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.user_sessions_id_seq +CREATE SEQUENCE user_sessions_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE user_sessions_id_seq OWNED BY user_sessions.id; --- --- Name: user_sessions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.user_sessions_id_seq OWNED BY public.user_sessions.id; - - --- --- Name: users; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.users ( +CREATE TABLE users ( id bigint NOT NULL, username text, email text, @@ -1508,1895 +855,630 @@ CREATE TABLE public.users ( CONSTRAINT check_d4bc21c175 CHECK ((char_length(firstname) <= 50)) ); - --- --- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.users_id_seq +CREATE SEQUENCE users_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE users_id_seq OWNED BY users.id; --- --- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id; - - --- --- Name: active_storage_attachments id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.active_storage_attachments ALTER COLUMN id SET DEFAULT nextval('public.active_storage_attachments_id_seq'::regclass); - - --- --- Name: active_storage_blobs id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.active_storage_blobs ALTER COLUMN id SET DEFAULT nextval('public.active_storage_blobs_id_seq'::regclass); - - --- --- Name: active_storage_variant_records id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.active_storage_variant_records ALTER COLUMN id SET DEFAULT nextval('public.active_storage_variant_records_id_seq'::regclass); - - --- --- Name: application_settings id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.application_settings ALTER COLUMN id SET DEFAULT nextval('public.application_settings_id_seq'::regclass); - - --- --- Name: audit_events id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.audit_events ALTER COLUMN id SET DEFAULT nextval('public.audit_events_id_seq'::regclass); - - --- --- Name: backup_codes id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.backup_codes ALTER COLUMN id SET DEFAULT nextval('public.backup_codes_id_seq'::regclass); - - --- --- Name: data_type_identifiers id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.data_type_identifiers ALTER COLUMN id SET DEFAULT nextval('public.data_type_identifiers_id_seq'::regclass); - - --- --- Name: data_type_rules id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.data_type_rules ALTER COLUMN id SET DEFAULT nextval('public.data_type_rules_id_seq'::regclass); - - --- --- Name: data_types id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.data_types ALTER COLUMN id SET DEFAULT nextval('public.data_types_id_seq'::regclass); - - --- --- Name: flow_settings id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flow_settings ALTER COLUMN id SET DEFAULT nextval('public.flow_settings_id_seq'::regclass); - - --- --- Name: flow_type_settings id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flow_type_settings ALTER COLUMN id SET DEFAULT nextval('public.flow_type_settings_id_seq'::regclass); - - --- --- Name: flow_types id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flow_types ALTER COLUMN id SET DEFAULT nextval('public.flow_types_id_seq'::regclass); - - --- --- Name: flows id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flows ALTER COLUMN id SET DEFAULT nextval('public.flows_id_seq'::regclass); - - --- --- Name: function_definitions id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.function_definitions ALTER COLUMN id SET DEFAULT nextval('public.function_definitions_id_seq'::regclass); - - --- --- Name: function_generic_mappers id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.function_generic_mappers ALTER COLUMN id SET DEFAULT nextval('public.function_generic_mappers_id_seq'::regclass); - - --- --- Name: generic_combination_strategies id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_combination_strategies ALTER COLUMN id SET DEFAULT nextval('public.generic_combination_strategies_id_seq'::regclass); - - --- --- Name: generic_mappers id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_mappers ALTER COLUMN id SET DEFAULT nextval('public.generic_mappers_id_seq'::regclass); - - --- --- Name: generic_types id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_types ALTER COLUMN id SET DEFAULT nextval('public.generic_types_id_seq'::regclass); - - --- --- Name: namespace_licenses id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_licenses ALTER COLUMN id SET DEFAULT nextval('public.namespace_licenses_id_seq'::regclass); - - --- --- Name: namespace_member_roles id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('public.namespace_member_roles_id_seq'::regclass); - +ALTER TABLE ONLY active_storage_attachments ALTER COLUMN id SET DEFAULT nextval('active_storage_attachments_id_seq'::regclass); --- --- Name: namespace_members id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY active_storage_blobs ALTER COLUMN id SET DEFAULT nextval('active_storage_blobs_id_seq'::regclass); -ALTER TABLE ONLY public.namespace_members ALTER COLUMN id SET DEFAULT nextval('public.namespace_members_id_seq'::regclass); +ALTER TABLE ONLY active_storage_variant_records ALTER COLUMN id SET DEFAULT nextval('active_storage_variant_records_id_seq'::regclass); +ALTER TABLE ONLY application_settings ALTER COLUMN id SET DEFAULT nextval('application_settings_id_seq'::regclass); --- --- Name: namespace_project_runtime_assignments id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY audit_events ALTER COLUMN id SET DEFAULT nextval('audit_events_id_seq'::regclass); -ALTER TABLE ONLY public.namespace_project_runtime_assignments ALTER COLUMN id SET DEFAULT nextval('public.namespace_project_runtime_assignments_id_seq'::regclass); +ALTER TABLE ONLY backup_codes ALTER COLUMN id SET DEFAULT nextval('backup_codes_id_seq'::regclass); +ALTER TABLE ONLY data_type_identifiers ALTER COLUMN id SET DEFAULT nextval('data_type_identifiers_id_seq'::regclass); --- --- Name: namespace_projects id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY data_type_rules ALTER COLUMN id SET DEFAULT nextval('data_type_rules_id_seq'::regclass); -ALTER TABLE ONLY public.namespace_projects ALTER COLUMN id SET DEFAULT nextval('public.namespace_projects_id_seq'::regclass); +ALTER TABLE ONLY data_types ALTER COLUMN id SET DEFAULT nextval('data_types_id_seq'::regclass); +ALTER TABLE ONLY flow_settings ALTER COLUMN id SET DEFAULT nextval('flow_settings_id_seq'::regclass); --- --- Name: namespace_role_abilities id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY flow_type_settings ALTER COLUMN id SET DEFAULT nextval('flow_type_settings_id_seq'::regclass); -ALTER TABLE ONLY public.namespace_role_abilities ALTER COLUMN id SET DEFAULT nextval('public.namespace_role_abilities_id_seq'::regclass); +ALTER TABLE ONLY flow_types ALTER COLUMN id SET DEFAULT nextval('flow_types_id_seq'::regclass); +ALTER TABLE ONLY flows ALTER COLUMN id SET DEFAULT nextval('flows_id_seq'::regclass); --- --- Name: namespace_role_project_assignments id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY function_definitions ALTER COLUMN id SET DEFAULT nextval('function_definitions_id_seq'::regclass); -ALTER TABLE ONLY public.namespace_role_project_assignments ALTER COLUMN id SET DEFAULT nextval('public.namespace_role_project_assignments_id_seq'::regclass); +ALTER TABLE ONLY function_generic_mappers ALTER COLUMN id SET DEFAULT nextval('function_generic_mappers_id_seq'::regclass); +ALTER TABLE ONLY generic_combination_strategies ALTER COLUMN id SET DEFAULT nextval('generic_combination_strategies_id_seq'::regclass); --- --- Name: namespace_roles id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY generic_mappers ALTER COLUMN id SET DEFAULT nextval('generic_mappers_id_seq'::regclass); -ALTER TABLE ONLY public.namespace_roles ALTER COLUMN id SET DEFAULT nextval('public.namespace_roles_id_seq'::regclass); +ALTER TABLE ONLY generic_types ALTER COLUMN id SET DEFAULT nextval('generic_types_id_seq'::regclass); +ALTER TABLE ONLY namespace_licenses ALTER COLUMN id SET DEFAULT nextval('namespace_licenses_id_seq'::regclass); --- --- Name: namespaces id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY namespace_member_roles ALTER COLUMN id SET DEFAULT nextval('namespace_member_roles_id_seq'::regclass); -ALTER TABLE ONLY public.namespaces ALTER COLUMN id SET DEFAULT nextval('public.namespaces_id_seq'::regclass); +ALTER TABLE ONLY namespace_members ALTER COLUMN id SET DEFAULT nextval('namespace_members_id_seq'::regclass); +ALTER TABLE ONLY namespace_project_runtime_assignments ALTER COLUMN id SET DEFAULT nextval('namespace_project_runtime_assignments_id_seq'::regclass); --- --- Name: node_functions id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY namespace_projects ALTER COLUMN id SET DEFAULT nextval('namespace_projects_id_seq'::regclass); -ALTER TABLE ONLY public.node_functions ALTER COLUMN id SET DEFAULT nextval('public.node_functions_id_seq'::regclass); +ALTER TABLE ONLY namespace_role_abilities ALTER COLUMN id SET DEFAULT nextval('namespace_role_abilities_id_seq'::regclass); +ALTER TABLE ONLY namespace_role_project_assignments ALTER COLUMN id SET DEFAULT nextval('namespace_role_project_assignments_id_seq'::regclass); --- --- Name: node_parameters id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY namespace_roles ALTER COLUMN id SET DEFAULT nextval('namespace_roles_id_seq'::regclass); -ALTER TABLE ONLY public.node_parameters ALTER COLUMN id SET DEFAULT nextval('public.node_parameters_id_seq'::regclass); +ALTER TABLE ONLY namespaces ALTER COLUMN id SET DEFAULT nextval('namespaces_id_seq'::regclass); +ALTER TABLE ONLY node_functions ALTER COLUMN id SET DEFAULT nextval('node_functions_id_seq'::regclass); --- --- Name: organizations id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY node_parameters ALTER COLUMN id SET DEFAULT nextval('node_parameters_id_seq'::regclass); -ALTER TABLE ONLY public.organizations ALTER COLUMN id SET DEFAULT nextval('public.organizations_id_seq'::regclass); +ALTER TABLE ONLY organizations ALTER COLUMN id SET DEFAULT nextval('organizations_id_seq'::regclass); +ALTER TABLE ONLY parameter_definitions ALTER COLUMN id SET DEFAULT nextval('parameter_definitions_id_seq'::regclass); --- --- Name: parameter_definitions id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY reference_paths ALTER COLUMN id SET DEFAULT nextval('reference_paths_id_seq'::regclass); -ALTER TABLE ONLY public.parameter_definitions ALTER COLUMN id SET DEFAULT nextval('public.parameter_definitions_id_seq'::regclass); +ALTER TABLE ONLY reference_values ALTER COLUMN id SET DEFAULT nextval('reference_values_id_seq'::regclass); +ALTER TABLE ONLY runtime_function_definition_error_types ALTER COLUMN id SET DEFAULT nextval('runtime_function_definition_error_types_id_seq'::regclass); --- --- Name: reference_paths id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY runtime_function_definitions ALTER COLUMN id SET DEFAULT nextval('runtime_function_definitions_id_seq'::regclass); -ALTER TABLE ONLY public.reference_paths ALTER COLUMN id SET DEFAULT nextval('public.reference_paths_id_seq'::regclass); +ALTER TABLE ONLY runtime_parameter_definitions ALTER COLUMN id SET DEFAULT nextval('runtime_parameter_definitions_id_seq'::regclass); +ALTER TABLE ONLY runtimes ALTER COLUMN id SET DEFAULT nextval('runtimes_id_seq'::regclass); --- --- Name: reference_values id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY translations ALTER COLUMN id SET DEFAULT nextval('translations_id_seq'::regclass); -ALTER TABLE ONLY public.reference_values ALTER COLUMN id SET DEFAULT nextval('public.reference_values_id_seq'::regclass); +ALTER TABLE ONLY user_identities ALTER COLUMN id SET DEFAULT nextval('user_identities_id_seq'::regclass); +ALTER TABLE ONLY user_sessions ALTER COLUMN id SET DEFAULT nextval('user_sessions_id_seq'::regclass); --- --- Name: runtime_function_definition_error_types id; Type: DEFAULT; Schema: public; Owner: - --- +ALTER TABLE ONLY users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass); -ALTER TABLE ONLY public.runtime_function_definition_error_types ALTER COLUMN id SET DEFAULT nextval('public.runtime_function_definition_error_types_id_seq'::regclass); - - --- --- Name: runtime_function_definitions id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtime_function_definitions ALTER COLUMN id SET DEFAULT nextval('public.runtime_function_definitions_id_seq'::regclass); - - --- --- Name: runtime_parameter_definitions id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtime_parameter_definitions ALTER COLUMN id SET DEFAULT nextval('public.runtime_parameter_definitions_id_seq'::regclass); - - --- --- Name: runtimes id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtimes ALTER COLUMN id SET DEFAULT nextval('public.runtimes_id_seq'::regclass); - - --- --- Name: translations id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.translations ALTER COLUMN id SET DEFAULT nextval('public.translations_id_seq'::regclass); - - --- --- Name: user_identities id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.user_identities ALTER COLUMN id SET DEFAULT nextval('public.user_identities_id_seq'::regclass); - - --- --- Name: user_sessions id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.user_sessions ALTER COLUMN id SET DEFAULT nextval('public.user_sessions_id_seq'::regclass); - - --- --- Name: users id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.users ALTER COLUMN id SET DEFAULT nextval('public.users_id_seq'::regclass); - - --- --- Name: active_storage_attachments active_storage_attachments_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.active_storage_attachments +ALTER TABLE ONLY active_storage_attachments ADD CONSTRAINT active_storage_attachments_pkey PRIMARY KEY (id); - --- --- Name: active_storage_blobs active_storage_blobs_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.active_storage_blobs +ALTER TABLE ONLY active_storage_blobs ADD CONSTRAINT active_storage_blobs_pkey PRIMARY KEY (id); - --- --- Name: active_storage_variant_records active_storage_variant_records_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.active_storage_variant_records +ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT active_storage_variant_records_pkey PRIMARY KEY (id); - --- --- Name: application_settings application_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.application_settings +ALTER TABLE ONLY application_settings ADD CONSTRAINT application_settings_pkey PRIMARY KEY (id); - --- --- Name: ar_internal_metadata ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.ar_internal_metadata +ALTER TABLE ONLY ar_internal_metadata ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key); - --- --- Name: audit_events audit_events_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.audit_events +ALTER TABLE ONLY audit_events ADD CONSTRAINT audit_events_pkey PRIMARY KEY (id); - --- --- Name: backup_codes backup_codes_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.backup_codes +ALTER TABLE ONLY backup_codes ADD CONSTRAINT backup_codes_pkey PRIMARY KEY (id); - --- --- Name: data_type_identifiers data_type_identifiers_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.data_type_identifiers +ALTER TABLE ONLY data_type_identifiers ADD CONSTRAINT data_type_identifiers_pkey PRIMARY KEY (id); - --- --- Name: data_type_rules data_type_rules_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.data_type_rules +ALTER TABLE ONLY data_type_rules ADD CONSTRAINT data_type_rules_pkey PRIMARY KEY (id); - --- --- Name: data_types data_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.data_types +ALTER TABLE ONLY data_types ADD CONSTRAINT data_types_pkey PRIMARY KEY (id); - --- --- Name: flow_settings flow_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flow_settings +ALTER TABLE ONLY flow_settings ADD CONSTRAINT flow_settings_pkey PRIMARY KEY (id); - --- --- Name: flow_type_settings flow_type_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flow_type_settings +ALTER TABLE ONLY flow_type_settings ADD CONSTRAINT flow_type_settings_pkey PRIMARY KEY (id); - --- --- Name: flow_types flow_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flow_types +ALTER TABLE ONLY flow_types ADD CONSTRAINT flow_types_pkey PRIMARY KEY (id); - --- --- Name: flows flows_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flows +ALTER TABLE ONLY flows ADD CONSTRAINT flows_pkey PRIMARY KEY (id); - --- --- Name: function_definitions function_definitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.function_definitions +ALTER TABLE ONLY function_definitions ADD CONSTRAINT function_definitions_pkey PRIMARY KEY (id); - --- --- Name: function_generic_mappers function_generic_mappers_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.function_generic_mappers +ALTER TABLE ONLY function_generic_mappers ADD CONSTRAINT function_generic_mappers_pkey PRIMARY KEY (id); - --- --- Name: generic_combination_strategies generic_combination_strategies_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_combination_strategies +ALTER TABLE ONLY generic_combination_strategies ADD CONSTRAINT generic_combination_strategies_pkey PRIMARY KEY (id); - --- --- Name: generic_mappers generic_mappers_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_mappers +ALTER TABLE ONLY generic_mappers ADD CONSTRAINT generic_mappers_pkey PRIMARY KEY (id); - --- --- Name: generic_types generic_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_types +ALTER TABLE ONLY generic_types ADD CONSTRAINT generic_types_pkey PRIMARY KEY (id); - --- --- Name: good_job_batches good_job_batches_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.good_job_batches +ALTER TABLE ONLY good_job_batches ADD CONSTRAINT good_job_batches_pkey PRIMARY KEY (id); - --- --- Name: good_job_executions good_job_executions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.good_job_executions +ALTER TABLE ONLY good_job_executions ADD CONSTRAINT good_job_executions_pkey PRIMARY KEY (id); - --- --- Name: good_job_processes good_job_processes_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.good_job_processes +ALTER TABLE ONLY good_job_processes ADD CONSTRAINT good_job_processes_pkey PRIMARY KEY (id); - --- --- Name: good_job_settings good_job_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.good_job_settings +ALTER TABLE ONLY good_job_settings ADD CONSTRAINT good_job_settings_pkey PRIMARY KEY (id); - --- --- Name: good_jobs good_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.good_jobs +ALTER TABLE ONLY good_jobs ADD CONSTRAINT good_jobs_pkey PRIMARY KEY (id); - --- --- Name: namespace_licenses namespace_licenses_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_licenses +ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT namespace_licenses_pkey PRIMARY KEY (id); - --- --- Name: namespace_member_roles namespace_member_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_member_roles +ALTER TABLE ONLY namespace_member_roles ADD CONSTRAINT namespace_member_roles_pkey PRIMARY KEY (id); - --- --- Name: namespace_members namespace_members_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_members +ALTER TABLE ONLY namespace_members ADD CONSTRAINT namespace_members_pkey PRIMARY KEY (id); - --- --- Name: namespace_project_runtime_assignments namespace_project_runtime_assignments_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_project_runtime_assignments +ALTER TABLE ONLY namespace_project_runtime_assignments ADD CONSTRAINT namespace_project_runtime_assignments_pkey PRIMARY KEY (id); - --- --- Name: namespace_projects namespace_projects_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_projects +ALTER TABLE ONLY namespace_projects ADD CONSTRAINT namespace_projects_pkey PRIMARY KEY (id); - --- --- Name: namespace_role_abilities namespace_role_abilities_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_role_abilities +ALTER TABLE ONLY namespace_role_abilities ADD CONSTRAINT namespace_role_abilities_pkey PRIMARY KEY (id); - --- --- Name: namespace_role_project_assignments namespace_role_project_assignments_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_role_project_assignments +ALTER TABLE ONLY namespace_role_project_assignments ADD CONSTRAINT namespace_role_project_assignments_pkey PRIMARY KEY (id); - --- --- Name: namespace_roles namespace_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_roles +ALTER TABLE ONLY namespace_roles ADD CONSTRAINT namespace_roles_pkey PRIMARY KEY (id); - --- --- Name: namespaces namespaces_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespaces +ALTER TABLE ONLY namespaces ADD CONSTRAINT namespaces_pkey PRIMARY KEY (id); - --- --- Name: node_functions node_functions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.node_functions +ALTER TABLE ONLY node_functions ADD CONSTRAINT node_functions_pkey PRIMARY KEY (id); - --- --- Name: node_parameters node_parameters_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.node_parameters +ALTER TABLE ONLY node_parameters ADD CONSTRAINT node_parameters_pkey PRIMARY KEY (id); - --- --- Name: organizations organizations_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.organizations +ALTER TABLE ONLY organizations ADD CONSTRAINT organizations_pkey PRIMARY KEY (id); - --- --- Name: parameter_definitions parameter_definitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.parameter_definitions +ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT parameter_definitions_pkey PRIMARY KEY (id); - --- --- Name: reference_paths reference_paths_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.reference_paths +ALTER TABLE ONLY reference_paths ADD CONSTRAINT reference_paths_pkey PRIMARY KEY (id); - --- --- Name: reference_values reference_values_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.reference_values +ALTER TABLE ONLY reference_values ADD CONSTRAINT reference_values_pkey PRIMARY KEY (id); - --- --- Name: runtime_function_definition_error_types runtime_function_definition_error_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtime_function_definition_error_types +ALTER TABLE ONLY runtime_function_definition_error_types ADD CONSTRAINT runtime_function_definition_error_types_pkey PRIMARY KEY (id); - --- --- Name: runtime_function_definitions runtime_function_definitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtime_function_definitions +ALTER TABLE ONLY runtime_function_definitions ADD CONSTRAINT runtime_function_definitions_pkey PRIMARY KEY (id); - --- --- Name: runtime_parameter_definitions runtime_parameter_definitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtime_parameter_definitions +ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT runtime_parameter_definitions_pkey PRIMARY KEY (id); - --- --- Name: runtimes runtimes_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtimes +ALTER TABLE ONLY runtimes ADD CONSTRAINT runtimes_pkey PRIMARY KEY (id); - --- --- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.schema_migrations +ALTER TABLE ONLY schema_migrations ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); - --- --- Name: translations translations_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.translations +ALTER TABLE ONLY translations ADD CONSTRAINT translations_pkey PRIMARY KEY (id); - --- --- Name: user_identities user_identities_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.user_identities +ALTER TABLE ONLY user_identities ADD CONSTRAINT user_identities_pkey PRIMARY KEY (id); - --- --- Name: user_sessions user_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.user_sessions +ALTER TABLE ONLY user_sessions ADD CONSTRAINT user_sessions_pkey PRIMARY KEY (id); - --- --- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.users +ALTER TABLE ONLY users ADD CONSTRAINT users_pkey PRIMARY KEY (id); +CREATE INDEX idx_on_function_generic_mapper_id_87df21b450 ON generic_combination_strategies USING btree (function_generic_mapper_id); --- --- Name: idx_on_namespace_role_id_ability_a092da8841; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX idx_on_namespace_role_id_ability_a092da8841 ON public.namespace_role_abilities USING btree (namespace_role_id, ability); - - --- --- Name: idx_on_role_id_project_id_5d4b5917dc; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX idx_on_role_id_project_id_5d4b5917dc ON public.namespace_role_project_assignments USING btree (role_id, project_id); - - --- --- Name: idx_on_runtime_function_definition_id_data_type_id_b6aa8fe066; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_data_type_id_b6aa8fe066 ON public.runtime_function_definition_error_types USING btree (runtime_function_definition_id, data_type_id); - - --- --- Name: idx_on_runtime_function_definition_id_f0f8f95496; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON public.function_generic_mappers USING btree (runtime_function_definition_id); - - --- --- Name: idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON public.runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); - - --- --- Name: idx_on_runtime_id_namespace_project_id_bc3c86cc70; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON public.namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); - - --- --- Name: idx_on_runtime_id_runtime_name_de2ab1bfc0; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON public.runtime_function_definitions USING btree (runtime_id, runtime_name); - - --- --- Name: idx_on_runtime_parameter_definition_id_3cbdb30381; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON public.function_generic_mappers USING btree (runtime_parameter_definition_id); - - --- --- Name: index_active_storage_attachments_on_blob_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_active_storage_attachments_on_blob_id ON public.active_storage_attachments USING btree (blob_id); - - --- --- Name: index_active_storage_attachments_uniqueness; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON public.active_storage_attachments USING btree (record_type, record_id, name, blob_id); - - --- --- Name: index_active_storage_blobs_on_key; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_active_storage_blobs_on_key ON public.active_storage_blobs USING btree (key); - - --- --- Name: index_active_storage_variant_records_uniqueness; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_active_storage_variant_records_uniqueness ON public.active_storage_variant_records USING btree (blob_id, variation_digest); - - --- --- Name: index_application_settings_on_setting; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_application_settings_on_setting ON public.application_settings USING btree (setting); - - --- --- Name: index_audit_events_on_author_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_audit_events_on_author_id ON public.audit_events USING btree (author_id); - - --- --- Name: index_backup_codes_on_user_id_LOWER_token; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "index_backup_codes_on_user_id_LOWER_token" ON public.backup_codes USING btree (user_id, lower(token)); - - --- --- Name: index_data_type_identifiers_on_data_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_data_type_identifiers_on_data_type_id ON public.data_type_identifiers USING btree (data_type_id); - - --- --- Name: index_data_type_identifiers_on_function_generic_mapper_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_data_type_identifiers_on_function_generic_mapper_id ON public.data_type_identifiers USING btree (function_generic_mapper_id); - - --- --- Name: index_data_type_identifiers_on_generic_mapper_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_data_type_identifiers_on_generic_mapper_id ON public.data_type_identifiers USING btree (generic_mapper_id); - - --- --- Name: index_data_type_identifiers_on_generic_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_data_type_identifiers_on_generic_type_id ON public.data_type_identifiers USING btree (generic_type_id); - - --- --- Name: index_data_type_identifiers_on_runtime_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_data_type_identifiers_on_runtime_id ON public.data_type_identifiers USING btree (runtime_id); - - --- --- Name: index_data_type_rules_on_data_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_data_type_rules_on_data_type_id ON public.data_type_rules USING btree (data_type_id); - - --- --- Name: index_data_types_on_flows_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_data_types_on_flows_id ON public.data_types USING btree (flows_id); - - --- --- Name: index_data_types_on_parent_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_data_types_on_parent_type_id ON public.data_types USING btree (parent_type_id); - - --- --- Name: index_data_types_on_runtime_id_and_identifier; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_data_types_on_runtime_id_and_identifier ON public.data_types USING btree (runtime_id, identifier); - - --- --- Name: index_flow_settings_on_flow_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flow_settings_on_flow_id ON public.flow_settings USING btree (flow_id); - - --- --- Name: index_flow_type_settings_on_data_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flow_type_settings_on_data_type_id ON public.flow_type_settings USING btree (data_type_id); - - --- --- Name: index_flow_type_settings_on_flow_type_id_and_identifier; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_flow_type_settings_on_flow_type_id_and_identifier ON public.flow_type_settings USING btree (flow_type_id, identifier); - - --- --- Name: index_flow_types_on_input_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flow_types_on_input_type_id ON public.flow_types USING btree (input_type_id); - - --- --- Name: index_flow_types_on_return_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flow_types_on_return_type_id ON public.flow_types USING btree (return_type_id); - - --- --- Name: index_flow_types_on_runtime_id_and_identifier; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_flow_types_on_runtime_id_and_identifier ON public.flow_types USING btree (runtime_id, identifier); - - --- --- Name: index_flows_on_flow_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flows_on_flow_type_id ON public.flows USING btree (flow_type_id); - - --- --- Name: index_flows_on_input_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flows_on_input_type_id ON public.flows USING btree (input_type_id); - - --- --- Name: index_flows_on_project_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flows_on_project_id ON public.flows USING btree (project_id); - - --- --- Name: index_flows_on_return_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flows_on_return_type_id ON public.flows USING btree (return_type_id); - - --- --- Name: index_flows_on_starting_node_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_flows_on_starting_node_id ON public.flows USING btree (starting_node_id); - - --- --- Name: index_function_definitions_on_return_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_function_definitions_on_return_type_id ON public.function_definitions USING btree (return_type_id); - - --- --- Name: index_function_definitions_on_runtime_function_definition_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON public.function_definitions USING btree (runtime_function_definition_id); - - --- --- Name: index_function_generic_mappers_on_runtime_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_function_generic_mappers_on_runtime_id ON public.function_generic_mappers USING btree (runtime_id); - - --- --- Name: index_generic_combination_strategies_on_generic_mapper_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_generic_combination_strategies_on_generic_mapper_id ON public.generic_combination_strategies USING btree (generic_mapper_id); - - --- --- Name: index_generic_mappers_on_generic_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_generic_mappers_on_generic_type_id ON public.generic_mappers USING btree (generic_type_id); - - --- --- Name: index_generic_mappers_on_runtime_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_generic_mappers_on_runtime_id ON public.generic_mappers USING btree (runtime_id); - - --- --- Name: index_generic_types_on_data_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_generic_types_on_data_type_id ON public.generic_types USING btree (data_type_id); - - --- --- Name: index_generic_types_on_runtime_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_generic_types_on_runtime_id ON public.generic_types USING btree (runtime_id); - - --- --- Name: index_good_job_executions_on_active_job_id_and_created_at; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON public.good_job_executions USING btree (active_job_id, created_at); - - --- --- Name: index_good_job_executions_on_process_id_and_created_at; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON public.good_job_executions USING btree (process_id, created_at); - - --- --- Name: index_good_job_jobs_for_candidate_lookup; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_job_jobs_for_candidate_lookup ON public.good_jobs USING btree (priority, created_at) WHERE (finished_at IS NULL); - - --- --- Name: index_good_job_settings_on_key; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_good_job_settings_on_key ON public.good_job_settings USING btree (key); - - --- --- Name: index_good_jobs_jobs_on_finished_at; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_jobs_on_finished_at ON public.good_jobs USING btree (finished_at) WHERE ((retried_good_job_id IS NULL) AND (finished_at IS NOT NULL)); - - --- --- Name: index_good_jobs_jobs_on_priority_created_at_when_unfinished; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_jobs_on_priority_created_at_when_unfinished ON public.good_jobs USING btree (priority DESC NULLS LAST, created_at) WHERE (finished_at IS NULL); - - --- --- Name: index_good_jobs_on_active_job_id_and_created_at; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_active_job_id_and_created_at ON public.good_jobs USING btree (active_job_id, created_at); - - --- --- Name: index_good_jobs_on_batch_callback_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_batch_callback_id ON public.good_jobs USING btree (batch_callback_id) WHERE (batch_callback_id IS NOT NULL); - - --- --- Name: index_good_jobs_on_batch_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_batch_id ON public.good_jobs USING btree (batch_id) WHERE (batch_id IS NOT NULL); - - --- --- Name: index_good_jobs_on_concurrency_key_and_created_at; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_concurrency_key_and_created_at ON public.good_jobs USING btree (concurrency_key, created_at); - - --- --- Name: index_good_jobs_on_concurrency_key_when_unfinished; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_concurrency_key_when_unfinished ON public.good_jobs USING btree (concurrency_key) WHERE (finished_at IS NULL); - - --- --- Name: index_good_jobs_on_cron_key_and_created_at_cond; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_cron_key_and_created_at_cond ON public.good_jobs USING btree (cron_key, created_at) WHERE (cron_key IS NOT NULL); - - --- --- Name: index_good_jobs_on_cron_key_and_cron_at_cond; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_good_jobs_on_cron_key_and_cron_at_cond ON public.good_jobs USING btree (cron_key, cron_at) WHERE (cron_key IS NOT NULL); - - --- --- Name: index_good_jobs_on_labels; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_labels ON public.good_jobs USING gin (labels) WHERE (labels IS NOT NULL); - - --- --- Name: index_good_jobs_on_locked_by_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_locked_by_id ON public.good_jobs USING btree (locked_by_id) WHERE (locked_by_id IS NOT NULL); - - --- --- Name: index_good_jobs_on_priority_scheduled_at_unfinished_unlocked; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_priority_scheduled_at_unfinished_unlocked ON public.good_jobs USING btree (priority, scheduled_at) WHERE ((finished_at IS NULL) AND (locked_by_id IS NULL)); - - --- --- Name: index_good_jobs_on_queue_name_and_scheduled_at; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_queue_name_and_scheduled_at ON public.good_jobs USING btree (queue_name, scheduled_at) WHERE (finished_at IS NULL); - - --- --- Name: index_good_jobs_on_scheduled_at; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_good_jobs_on_scheduled_at ON public.good_jobs USING btree (scheduled_at) WHERE (finished_at IS NULL); - - --- --- Name: index_namespace_licenses_on_namespace_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_namespace_licenses_on_namespace_id ON public.namespace_licenses USING btree (namespace_id); - - --- --- Name: index_namespace_member_roles_on_member_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_namespace_member_roles_on_member_id ON public.namespace_member_roles USING btree (member_id); - - --- --- Name: index_namespace_member_roles_on_role_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_namespace_member_roles_on_role_id ON public.namespace_member_roles USING btree (role_id); - - --- --- Name: index_namespace_members_on_namespace_id_and_user_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_namespace_members_on_namespace_id_and_user_id ON public.namespace_members USING btree (namespace_id, user_id); - - --- --- Name: index_namespace_members_on_user_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_namespace_members_on_user_id ON public.namespace_members USING btree (user_id); - - --- --- Name: index_namespace_projects_on_namespace_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_namespace_projects_on_namespace_id ON public.namespace_projects USING btree (namespace_id); - - --- --- Name: index_namespace_projects_on_primary_runtime_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_namespace_projects_on_primary_runtime_id ON public.namespace_projects USING btree (primary_runtime_id); - - --- --- Name: index_namespace_role_project_assignments_on_project_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_namespace_role_project_assignments_on_project_id ON public.namespace_role_project_assignments USING btree (project_id); - - --- --- Name: index_namespace_roles_on_namespace_id_LOWER_name; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON public.namespace_roles USING btree (namespace_id, lower(name)); - - --- --- Name: index_namespaces_on_parent_id_and_parent_type; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_namespaces_on_parent_id_and_parent_type ON public.namespaces USING btree (parent_id, parent_type); - - --- --- Name: index_node_functions_on_next_node_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_node_functions_on_next_node_id ON public.node_functions USING btree (next_node_id); - - --- --- Name: index_node_functions_on_runtime_function_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_node_functions_on_runtime_function_id ON public.node_functions USING btree (runtime_function_id); - - --- --- Name: index_node_parameters_on_function_value_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_node_parameters_on_function_value_id ON public.node_parameters USING btree (function_value_id); - - --- --- Name: index_node_parameters_on_node_function_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_node_parameters_on_node_function_id ON public.node_parameters USING btree (node_function_id); - - --- --- Name: index_node_parameters_on_reference_value_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_node_parameters_on_reference_value_id ON public.node_parameters USING btree (reference_value_id); - - --- --- Name: index_node_parameters_on_runtime_parameter_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_node_parameters_on_runtime_parameter_id ON public.node_parameters USING btree (runtime_parameter_id); - - --- --- Name: index_organizations_on_LOWER_name; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "index_organizations_on_LOWER_name" ON public.organizations USING btree (lower(name)); - - --- --- Name: index_parameter_definitions_on_data_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_parameter_definitions_on_data_type_id ON public.parameter_definitions USING btree (data_type_id); - - --- --- Name: index_parameter_definitions_on_runtime_parameter_definition_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_parameter_definitions_on_runtime_parameter_definition_id ON public.parameter_definitions USING btree (runtime_parameter_definition_id); - - --- --- Name: index_reference_paths_on_reference_value_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_reference_paths_on_reference_value_id ON public.reference_paths USING btree (reference_value_id); - - --- --- Name: index_reference_values_on_data_type_identifier_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_reference_values_on_data_type_identifier_id ON public.reference_values USING btree (data_type_identifier_id); - - --- --- Name: index_runtime_function_definitions_on_return_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_runtime_function_definitions_on_return_type_id ON public.runtime_function_definitions USING btree (return_type_id); - - --- --- Name: index_runtime_parameter_definitions_on_data_type_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_runtime_parameter_definitions_on_data_type_id ON public.runtime_parameter_definitions USING btree (data_type_id); - - --- --- Name: index_runtimes_on_namespace_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_runtimes_on_namespace_id ON public.runtimes USING btree (namespace_id); - - --- --- Name: index_runtimes_on_token; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_runtimes_on_token ON public.runtimes USING btree (token); - - --- --- Name: index_translations_on_owner; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_translations_on_owner ON public.translations USING btree (owner_type, owner_id); - - --- --- Name: index_user_identities_on_provider_id_and_identifier; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_user_identities_on_provider_id_and_identifier ON public.user_identities USING btree (provider_id, identifier); - - --- --- Name: index_user_identities_on_user_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_user_identities_on_user_id ON public.user_identities USING btree (user_id); - - --- --- Name: index_user_identities_on_user_id_and_provider_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_user_identities_on_user_id_and_provider_id ON public.user_identities USING btree (user_id, provider_id); - - --- --- Name: index_user_sessions_on_token; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_user_sessions_on_token ON public.user_sessions USING btree (token); - - --- --- Name: index_user_sessions_on_user_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_user_sessions_on_user_id ON public.user_sessions USING btree (user_id); - - --- --- Name: index_users_on_LOWER_email; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "index_users_on_LOWER_email" ON public.users USING btree (lower(email)); - - --- --- Name: index_users_on_LOWER_username; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "index_users_on_LOWER_username" ON public.users USING btree (lower(username)); - - --- --- Name: index_users_on_totp_secret; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_users_on_totp_secret ON public.users USING btree (totp_secret) WHERE (totp_secret IS NOT NULL); - - --- --- Name: flow_types fk_rails_01f5c9215f; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.flow_types - ADD CONSTRAINT fk_rails_01f5c9215f FOREIGN KEY (input_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; - - --- --- Name: data_type_identifiers fk_rails_01f5d14544; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.data_type_identifiers - ADD CONSTRAINT fk_rails_01f5d14544 FOREIGN KEY (generic_mapper_id) REFERENCES public.generic_mappers(id) ON DELETE RESTRICT; - - --- --- Name: runtime_function_definition_error_types fk_rails_070c5bfcf0; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtime_function_definition_error_types - ADD CONSTRAINT fk_rails_070c5bfcf0 FOREIGN KEY (runtime_function_definition_id) REFERENCES public.runtime_function_definitions(id) ON DELETE CASCADE; - - --- --- Name: function_definitions fk_rails_0c2eb746ef; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.function_definitions - ADD CONSTRAINT fk_rails_0c2eb746ef FOREIGN KEY (return_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; - - --- --- Name: node_parameters fk_rails_0d79310cfa; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.node_parameters - ADD CONSTRAINT fk_rails_0d79310cfa FOREIGN KEY (node_function_id) REFERENCES public.node_functions(id) ON DELETE CASCADE; - - --- --- Name: node_parameters fk_rails_0ff4fd0049; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.node_parameters - ADD CONSTRAINT fk_rails_0ff4fd0049 FOREIGN KEY (runtime_parameter_id) REFERENCES public.runtime_parameter_definitions(id) ON DELETE CASCADE; - - --- --- Name: data_types fk_rails_118c914ed0; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.data_types - ADD CONSTRAINT fk_rails_118c914ed0 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; - - --- --- Name: generic_combination_strategies fk_rails_1f88a2577e; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_combination_strategies - ADD CONSTRAINT fk_rails_1f88a2577e FOREIGN KEY (generic_mapper_id) REFERENCES public.generic_mappers(id) ON DELETE CASCADE; - - --- --- Name: namespace_roles fk_rails_205092c9cb; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_roles - ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; - - --- --- Name: generic_types fk_rails_20f4bf6b34; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; - - --- --- Name: runtime_parameter_definitions fk_rails_260318ad67; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.runtime_parameter_definitions - ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES public.runtime_function_definitions(id) ON DELETE CASCADE; - - --- --- Name: function_generic_mappers fk_rails_26b6470eba; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.function_generic_mappers - ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES public.runtime_parameter_definitions(id) ON DELETE RESTRICT; - - --- --- Name: generic_types fk_rails_275446d9e6; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.generic_types - ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE CASCADE; - - --- --- Name: namespace_licenses fk_rails_38f693332d; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.namespace_licenses - ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; - +CREATE UNIQUE INDEX idx_on_namespace_role_id_ability_a092da8841 ON namespace_role_abilities USING btree (namespace_role_id, ability); --- --- Name: parameter_definitions fk_rails_3b02763f84; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX idx_on_role_id_project_id_5d4b5917dc ON namespace_role_project_assignments USING btree (role_id, project_id); -ALTER TABLE ONLY public.parameter_definitions - ADD CONSTRAINT fk_rails_3b02763f84 FOREIGN KEY (runtime_parameter_definition_id) REFERENCES public.runtime_parameter_definitions(id) ON DELETE CASCADE; +CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_data_type_id_b6aa8fe066 ON runtime_function_definition_error_types USING btree (runtime_function_definition_id, data_type_id); +CREATE INDEX idx_on_runtime_function_definition_id_f0f8f95496 ON function_generic_mappers USING btree (runtime_function_definition_id); --- --- Name: runtime_function_definition_error_types fk_rails_408d037751; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_runtime_name_abb3bb31bc ON runtime_parameter_definitions USING btree (runtime_function_definition_id, runtime_name); -ALTER TABLE ONLY public.runtime_function_definition_error_types - ADD CONSTRAINT fk_rails_408d037751 FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; +CREATE UNIQUE INDEX idx_on_runtime_id_namespace_project_id_bc3c86cc70 ON namespace_project_runtime_assignments USING btree (runtime_id, namespace_project_id); +CREATE UNIQUE INDEX idx_on_runtime_id_runtime_name_de2ab1bfc0 ON runtime_function_definitions USING btree (runtime_id, runtime_name); --- --- Name: data_type_identifiers fk_rails_40d8496abb; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX idx_on_runtime_parameter_definition_id_3cbdb30381 ON function_generic_mappers USING btree (runtime_parameter_definition_id); -ALTER TABLE ONLY public.data_type_identifiers - ADD CONSTRAINT fk_rails_40d8496abb FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; +CREATE INDEX index_active_storage_attachments_on_blob_id ON active_storage_attachments USING btree (blob_id); +CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON active_storage_attachments USING btree (record_type, record_id, name, blob_id); --- --- Name: data_types fk_rails_4434ad0b90; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX index_active_storage_blobs_on_key ON active_storage_blobs USING btree (key); -ALTER TABLE ONLY public.data_types - ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; +CREATE UNIQUE INDEX index_active_storage_variant_records_uniqueness ON active_storage_variant_records USING btree (blob_id, variation_digest); +CREATE UNIQUE INDEX index_application_settings_on_setting ON application_settings USING btree (setting); --- --- Name: function_generic_mappers fk_rails_4593a9a9b6; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_audit_events_on_author_id ON audit_events USING btree (author_id); -ALTER TABLE ONLY public.function_generic_mappers - ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; +CREATE UNIQUE INDEX "index_backup_codes_on_user_id_LOWER_token" ON backup_codes USING btree (user_id, lower(token)); +CREATE INDEX index_data_type_identifiers_on_data_type_id ON data_type_identifiers USING btree (data_type_id); --- --- Name: function_definitions fk_rails_48f4bbe3b6; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_data_type_identifiers_on_function_generic_mapper_id ON data_type_identifiers USING btree (function_generic_mapper_id); -ALTER TABLE ONLY public.function_definitions - ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES public.runtime_function_definitions(id) ON DELETE CASCADE; +CREATE INDEX index_data_type_identifiers_on_generic_mapper_id ON data_type_identifiers USING btree (generic_mapper_id); +CREATE INDEX index_data_type_identifiers_on_generic_type_id ON data_type_identifiers USING btree (generic_type_id); --- --- Name: data_types fk_rails_490081f598; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_data_type_identifiers_on_runtime_id ON data_type_identifiers USING btree (runtime_id); -ALTER TABLE ONLY public.data_types - ADD CONSTRAINT fk_rails_490081f598 FOREIGN KEY (flows_id) REFERENCES public.flows(id) ON DELETE RESTRICT; +CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id); +CREATE INDEX index_data_types_on_flows_id ON data_types USING btree (flows_id); --- --- Name: runtime_function_definitions fk_rails_5161ff47e6; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (parent_type_id); -ALTER TABLE ONLY public.runtime_function_definitions - ADD CONSTRAINT fk_rails_5161ff47e6 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; +CREATE UNIQUE INDEX index_data_types_on_runtime_id_and_identifier ON data_types USING btree (runtime_id, identifier); +CREATE INDEX index_flow_settings_on_flow_id ON flow_settings USING btree (flow_id); --- --- Name: backup_codes fk_rails_556c1feac3; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_flow_type_settings_on_data_type_id ON flow_type_settings USING btree (data_type_id); -ALTER TABLE ONLY public.backup_codes - ADD CONSTRAINT fk_rails_556c1feac3 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; +CREATE UNIQUE INDEX index_flow_type_settings_on_flow_type_id_and_identifier ON flow_type_settings USING btree (flow_type_id, identifier); +CREATE INDEX index_flow_types_on_input_type_id ON flow_types USING btree (input_type_id); --- --- Name: namespace_members fk_rails_567f152a62; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_flow_types_on_return_type_id ON flow_types USING btree (return_type_id); -ALTER TABLE ONLY public.namespace_members - ADD CONSTRAINT fk_rails_567f152a62 FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; +CREATE UNIQUE INDEX index_flow_types_on_runtime_id_and_identifier ON flow_types USING btree (runtime_id, identifier); +CREATE INDEX index_flows_on_flow_type_id ON flows USING btree (flow_type_id); --- --- Name: namespace_member_roles fk_rails_585a684166; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_flows_on_input_type_id ON flows USING btree (input_type_id); -ALTER TABLE ONLY public.namespace_member_roles - ADD CONSTRAINT fk_rails_585a684166 FOREIGN KEY (role_id) REFERENCES public.namespace_roles(id) ON DELETE CASCADE; +CREATE INDEX index_flows_on_project_id ON flows USING btree (project_id); +CREATE INDEX index_flows_on_return_type_id ON flows USING btree (return_type_id); --- --- Name: namespace_role_project_assignments fk_rails_623f8a5b72; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_flows_on_starting_node_id ON flows USING btree (starting_node_id); -ALTER TABLE ONLY public.namespace_role_project_assignments - ADD CONSTRAINT fk_rails_623f8a5b72 FOREIGN KEY (role_id) REFERENCES public.namespace_roles(id); +CREATE INDEX index_function_definitions_on_return_type_id ON function_definitions USING btree (return_type_id); +CREATE INDEX index_function_definitions_on_runtime_function_definition_id ON function_definitions USING btree (runtime_function_definition_id); --- --- Name: node_parameters fk_rails_646d4dbfbc; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_function_generic_mappers_on_runtime_id ON function_generic_mappers USING btree (runtime_id); -ALTER TABLE ONLY public.node_parameters - ADD CONSTRAINT fk_rails_646d4dbfbc FOREIGN KEY (reference_value_id) REFERENCES public.reference_values(id) ON DELETE RESTRICT; +CREATE INDEX index_generic_combination_strategies_on_generic_mapper_id ON generic_combination_strategies USING btree (generic_mapper_id); +CREATE INDEX index_generic_mappers_on_generic_type_id ON generic_mappers USING btree (generic_type_id); --- --- Name: data_type_identifiers fk_rails_65151da1fb; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); -ALTER TABLE ONLY public.data_type_identifiers - ADD CONSTRAINT fk_rails_65151da1fb FOREIGN KEY (generic_type_id) REFERENCES public.generic_types(id) ON DELETE CASCADE; +CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); +CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); --- --- Name: user_identities fk_rails_684b0e1ce0; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON good_job_executions USING btree (active_job_id, created_at); -ALTER TABLE ONLY public.user_identities - ADD CONSTRAINT fk_rails_684b0e1ce0 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; +CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON good_job_executions USING btree (process_id, created_at); +CREATE INDEX index_good_job_jobs_for_candidate_lookup ON good_jobs USING btree (priority, created_at) WHERE (finished_at IS NULL); --- --- Name: flow_types fk_rails_687d671458; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX index_good_job_settings_on_key ON good_job_settings USING btree (key); -ALTER TABLE ONLY public.flow_types - ADD CONSTRAINT fk_rails_687d671458 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; +CREATE INDEX index_good_jobs_jobs_on_finished_at ON good_jobs USING btree (finished_at) WHERE ((retried_good_job_id IS NULL) AND (finished_at IS NOT NULL)); +CREATE INDEX index_good_jobs_jobs_on_priority_created_at_when_unfinished ON good_jobs USING btree (priority DESC NULLS LAST, created_at) WHERE (finished_at IS NULL); --- --- Name: namespace_role_project_assignments fk_rails_69066bda8f; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_good_jobs_on_active_job_id_and_created_at ON good_jobs USING btree (active_job_id, created_at); -ALTER TABLE ONLY public.namespace_role_project_assignments - ADD CONSTRAINT fk_rails_69066bda8f FOREIGN KEY (project_id) REFERENCES public.namespace_projects(id); +CREATE INDEX index_good_jobs_on_batch_callback_id ON good_jobs USING btree (batch_callback_id) WHERE (batch_callback_id IS NOT NULL); +CREATE INDEX index_good_jobs_on_batch_id ON good_jobs USING btree (batch_id) WHERE (batch_id IS NOT NULL); --- --- Name: namespace_member_roles fk_rails_6c0d5a04c4; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_good_jobs_on_concurrency_key_and_created_at ON good_jobs USING btree (concurrency_key, created_at); -ALTER TABLE ONLY public.namespace_member_roles - ADD CONSTRAINT fk_rails_6c0d5a04c4 FOREIGN KEY (member_id) REFERENCES public.namespace_members(id) ON DELETE CASCADE; +CREATE INDEX index_good_jobs_on_concurrency_key_when_unfinished ON good_jobs USING btree (concurrency_key) WHERE (finished_at IS NULL); +CREATE INDEX index_good_jobs_on_cron_key_and_created_at_cond ON good_jobs USING btree (cron_key, created_at) WHERE (cron_key IS NOT NULL); --- --- Name: namespace_role_abilities fk_rails_6f3304b078; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX index_good_jobs_on_cron_key_and_cron_at_cond ON good_jobs USING btree (cron_key, cron_at) WHERE (cron_key IS NOT NULL); -ALTER TABLE ONLY public.namespace_role_abilities - ADD CONSTRAINT fk_rails_6f3304b078 FOREIGN KEY (namespace_role_id) REFERENCES public.namespace_roles(id) ON DELETE CASCADE; +CREATE INDEX index_good_jobs_on_labels ON good_jobs USING gin (labels) WHERE (labels IS NOT NULL); +CREATE INDEX index_good_jobs_on_locked_by_id ON good_jobs USING btree (locked_by_id) WHERE (locked_by_id IS NOT NULL); --- --- Name: runtime_function_definitions fk_rails_73ca8569ea; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_good_jobs_on_priority_scheduled_at_unfinished_unlocked ON good_jobs USING btree (priority, scheduled_at) WHERE ((finished_at IS NULL) AND (locked_by_id IS NULL)); -ALTER TABLE ONLY public.runtime_function_definitions - ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; +CREATE INDEX index_good_jobs_on_queue_name_and_scheduled_at ON good_jobs USING btree (queue_name, scheduled_at) WHERE (finished_at IS NULL); +CREATE INDEX index_good_jobs_on_scheduled_at ON good_jobs USING btree (scheduled_at) WHERE (finished_at IS NULL); --- --- Name: node_parameters fk_rails_74b7800b37; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_namespace_licenses_on_namespace_id ON namespace_licenses USING btree (namespace_id); -ALTER TABLE ONLY public.node_parameters - ADD CONSTRAINT fk_rails_74b7800b37 FOREIGN KEY (function_value_id) REFERENCES public.node_functions(id) ON DELETE RESTRICT; +CREATE INDEX index_namespace_member_roles_on_member_id ON namespace_member_roles USING btree (member_id); +CREATE INDEX index_namespace_member_roles_on_role_id ON namespace_member_roles USING btree (role_id); --- --- Name: data_type_rules fk_rails_7759633ff8; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX index_namespace_members_on_namespace_id_and_user_id ON namespace_members USING btree (namespace_id, user_id); -ALTER TABLE ONLY public.data_type_rules - ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE CASCADE; +CREATE INDEX index_namespace_members_on_user_id ON namespace_members USING btree (user_id); +CREATE INDEX index_namespace_projects_on_namespace_id ON namespace_projects USING btree (namespace_id); --- --- Name: namespace_projects fk_rails_79012c5895; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_namespace_projects_on_primary_runtime_id ON namespace_projects USING btree (primary_runtime_id); -ALTER TABLE ONLY public.namespace_projects - ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; +CREATE INDEX index_namespace_role_project_assignments_on_project_id ON namespace_role_project_assignments USING btree (project_id); +CREATE UNIQUE INDEX "index_namespace_roles_on_namespace_id_LOWER_name" ON namespace_roles USING btree (namespace_id, lower(name)); --- --- Name: flows fk_rails_7de9ce6578; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX index_namespaces_on_parent_id_and_parent_type ON namespaces USING btree (parent_id, parent_type); -ALTER TABLE ONLY public.flows - ADD CONSTRAINT fk_rails_7de9ce6578 FOREIGN KEY (starting_node_id) REFERENCES public.node_functions(id) ON DELETE RESTRICT; +CREATE INDEX index_node_functions_on_next_node_id ON node_functions USING btree (next_node_id); +CREATE INDEX index_node_functions_on_runtime_function_id ON node_functions USING btree (runtime_function_id); --- --- Name: node_functions fk_rails_8953e1d86a; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_node_parameters_on_function_value_id ON node_parameters USING btree (function_value_id); -ALTER TABLE ONLY public.node_functions - ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES public.runtime_function_definitions(id) ON DELETE RESTRICT; +CREATE INDEX index_node_parameters_on_node_function_id ON node_parameters USING btree (node_function_id); +CREATE INDEX index_node_parameters_on_reference_value_id ON node_parameters USING btree (reference_value_id); --- --- Name: data_type_identifiers fk_rails_8d8385e8ec; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_node_parameters_on_runtime_parameter_id ON node_parameters USING btree (runtime_parameter_id); -ALTER TABLE ONLY public.data_type_identifiers - ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; +CREATE UNIQUE INDEX "index_organizations_on_LOWER_name" ON organizations USING btree (lower(name)); +CREATE INDEX index_parameter_definitions_on_data_type_id ON parameter_definitions USING btree (data_type_id); --- --- Name: flows fk_rails_8f97500cd4; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_parameter_definitions_on_runtime_parameter_definition_id ON parameter_definitions USING btree (runtime_parameter_definition_id); -ALTER TABLE ONLY public.flows - ADD CONSTRAINT fk_rails_8f97500cd4 FOREIGN KEY (return_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; +CREATE INDEX index_reference_paths_on_reference_value_id ON reference_paths USING btree (reference_value_id); +CREATE INDEX index_reference_values_on_data_type_identifier_id ON reference_values USING btree (data_type_identifier_id); --- --- Name: reference_paths fk_rails_92e51047ea; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_runtime_function_definitions_on_return_type_id ON runtime_function_definitions USING btree (return_type_id); -ALTER TABLE ONLY public.reference_paths - ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES public.reference_values(id) ON DELETE RESTRICT; +CREATE INDEX index_runtime_parameter_definitions_on_data_type_id ON runtime_parameter_definitions USING btree (data_type_id); +CREATE INDEX index_runtimes_on_namespace_id ON runtimes USING btree (namespace_id); --- --- Name: active_storage_variant_records fk_rails_993965df05; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX index_runtimes_on_token ON runtimes USING btree (token); -ALTER TABLE ONLY public.active_storage_variant_records - ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id); +CREATE INDEX index_translations_on_owner ON translations USING btree (owner_type, owner_id); +CREATE UNIQUE INDEX index_user_identities_on_provider_id_and_identifier ON user_identities USING btree (provider_id, identifier); --- --- Name: function_generic_mappers fk_rails_9f59fae6ab; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_user_identities_on_user_id ON user_identities USING btree (user_id); -ALTER TABLE ONLY public.function_generic_mappers - ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES public.runtime_function_definitions(id) ON DELETE RESTRICT; +CREATE UNIQUE INDEX index_user_identities_on_user_id_and_provider_id ON user_identities USING btree (user_id, provider_id); +CREATE UNIQUE INDEX index_user_sessions_on_token ON user_sessions USING btree (token); --- --- Name: user_sessions fk_rails_9fa262d742; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE INDEX index_user_sessions_on_user_id ON user_sessions USING btree (user_id); -ALTER TABLE ONLY public.user_sessions - ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; +CREATE UNIQUE INDEX "index_users_on_LOWER_email" ON users USING btree (lower(email)); +CREATE UNIQUE INDEX "index_users_on_LOWER_username" ON users USING btree (lower(username)); --- --- Name: namespace_members fk_rails_a0a760b9b4; Type: FK CONSTRAINT; Schema: public; Owner: - --- +CREATE UNIQUE INDEX index_users_on_totp_secret ON users USING btree (totp_secret) WHERE (totp_secret IS NOT NULL); -ALTER TABLE ONLY public.namespace_members - ADD CONSTRAINT fk_rails_a0a760b9b4 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; +ALTER TABLE ONLY flow_types + ADD CONSTRAINT fk_rails_01f5c9215f FOREIGN KEY (input_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_01f5d14544 FOREIGN KEY (generic_mapper_id) REFERENCES generic_mappers(id) ON DELETE RESTRICT; --- --- Name: flow_type_settings fk_rails_a1471d011d; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY runtime_function_definition_error_types + ADD CONSTRAINT fk_rails_070c5bfcf0 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.flow_type_settings - ADD CONSTRAINT fk_rails_a1471d011d FOREIGN KEY (data_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY function_definitions + ADD CONSTRAINT fk_rails_0c2eb746ef FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT fk_rails_0d79310cfa FOREIGN KEY (node_function_id) REFERENCES node_functions(id) ON DELETE CASCADE; --- --- Name: flows fk_rails_ab927e0ecb; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT fk_rails_0ff4fd0049 FOREIGN KEY (runtime_parameter_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.flows - ADD CONSTRAINT fk_rails_ab927e0ecb FOREIGN KEY (project_id) REFERENCES public.namespace_projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY data_types + ADD CONSTRAINT fk_rails_118c914ed0 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY generic_combination_strategies + ADD CONSTRAINT fk_rails_1f88a2577e FOREIGN KEY (generic_mapper_id) REFERENCES generic_mappers(id) ON DELETE CASCADE; --- --- Name: reference_values fk_rails_bb34a5d62c; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY namespace_roles + ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.reference_values - ADD CONSTRAINT fk_rails_bb34a5d62c FOREIGN KEY (data_type_identifier_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY generic_types + ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY runtime_parameter_definitions + ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; --- --- Name: flows fk_rails_bb587eff6a; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_26b6470eba FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE RESTRICT; -ALTER TABLE ONLY public.flows - ADD CONSTRAINT fk_rails_bb587eff6a FOREIGN KEY (input_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY generic_types + ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY namespace_licenses + ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; --- --- Name: flow_types fk_rails_bead35b1a6; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY parameter_definitions + ADD CONSTRAINT fk_rails_3b02763f84 FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.flow_types - ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES public.data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY runtime_function_definition_error_types + ADD CONSTRAINT fk_rails_408d037751 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_40d8496abb FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; --- --- Name: namespace_project_runtime_assignments fk_rails_c019e5b233; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY data_types + ADD CONSTRAINT fk_rails_4434ad0b90 FOREIGN KEY (parent_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY public.namespace_project_runtime_assignments - ADD CONSTRAINT fk_rails_c019e5b233 FOREIGN KEY (namespace_project_id) REFERENCES public.namespace_projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_4593a9a9b6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY function_definitions + ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; --- --- Name: active_storage_attachments fk_rails_c3b3935057; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY data_types + ADD CONSTRAINT fk_rails_490081f598 FOREIGN KEY (flows_id) REFERENCES flows(id) ON DELETE RESTRICT; -ALTER TABLE ONLY public.active_storage_attachments - ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id); +ALTER TABLE ONLY runtime_function_definitions + ADD CONSTRAINT fk_rails_5161ff47e6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY backup_codes + ADD CONSTRAINT fk_rails_556c1feac3 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; --- --- Name: namespace_project_runtime_assignments fk_rails_c640af2146; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY namespace_members + ADD CONSTRAINT fk_rails_567f152a62 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.namespace_project_runtime_assignments - ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY namespace_member_roles + ADD CONSTRAINT fk_rails_585a684166 FOREIGN KEY (role_id) REFERENCES namespace_roles(id) ON DELETE CASCADE; +ALTER TABLE ONLY namespace_role_project_assignments + ADD CONSTRAINT fk_rails_623f8a5b72 FOREIGN KEY (role_id) REFERENCES namespace_roles(id); --- --- Name: generic_mappers fk_rails_c7984c8a7a; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT fk_rails_646d4dbfbc FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; -ALTER TABLE ONLY public.generic_mappers - ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES public.runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_65151da1fb FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY user_identities + ADD CONSTRAINT fk_rails_684b0e1ce0 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; --- --- Name: parameter_definitions fk_rails_ca0a397b6f; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY flow_types + ADD CONSTRAINT fk_rails_687d671458 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.parameter_definitions - ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY namespace_role_project_assignments + ADD CONSTRAINT fk_rails_69066bda8f FOREIGN KEY (project_id) REFERENCES namespace_projects(id); +ALTER TABLE ONLY namespace_member_roles + ADD CONSTRAINT fk_rails_6c0d5a04c4 FOREIGN KEY (member_id) REFERENCES namespace_members(id) ON DELETE CASCADE; --- --- Name: data_type_identifiers fk_rails_d08626f743; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY namespace_role_abilities + ADD CONSTRAINT fk_rails_6f3304b078 FOREIGN KEY (namespace_role_id) REFERENCES namespace_roles(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.data_type_identifiers - ADD CONSTRAINT fk_rails_d08626f743 FOREIGN KEY (function_generic_mapper_id) REFERENCES public.function_generic_mappers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY runtime_function_definitions + ADD CONSTRAINT fk_rails_73ca8569ea FOREIGN KEY (return_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY node_parameters + ADD CONSTRAINT fk_rails_74b7800b37 FOREIGN KEY (function_value_id) REFERENCES node_functions(id) ON DELETE RESTRICT; --- --- Name: namespace_projects fk_rails_d4f50e2f00; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY data_type_rules + ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.namespace_projects - ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY namespace_projects + ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_7de9ce6578 FOREIGN KEY (starting_node_id) REFERENCES node_functions(id) ON DELETE RESTRICT; --- --- Name: flows fk_rails_d9ad50fe4b; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY node_functions + ADD CONSTRAINT fk_rails_8953e1d86a FOREIGN KEY (runtime_function_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; -ALTER TABLE ONLY public.flows - ADD CONSTRAINT fk_rails_d9ad50fe4b FOREIGN KEY (flow_type_id) REFERENCES public.flow_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_8d8385e8ec FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_8f97500cd4 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; --- --- Name: flow_settings fk_rails_da3b2fb3c5; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY reference_paths + ADD CONSTRAINT fk_rails_92e51047ea FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; -ALTER TABLE ONLY public.flow_settings - ADD CONSTRAINT fk_rails_da3b2fb3c5 FOREIGN KEY (flow_id) REFERENCES public.flows(id) ON DELETE CASCADE; +ALTER TABLE ONLY active_storage_variant_records + ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); +ALTER TABLE ONLY function_generic_mappers + ADD CONSTRAINT fk_rails_9f59fae6ab FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE RESTRICT; --- --- Name: generic_mappers fk_rails_e0d918961b; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY user_sessions + ADD CONSTRAINT fk_rails_9fa262d742 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.generic_mappers - ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES public.generic_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY namespace_members + ADD CONSTRAINT fk_rails_a0a760b9b4 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; +ALTER TABLE ONLY flow_type_settings + ADD CONSTRAINT fk_rails_a1471d011d FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; --- --- Name: runtime_parameter_definitions fk_rails_e64f825793; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_ab927e0ecb FOREIGN KEY (project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.runtime_parameter_definitions - ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES public.data_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY generic_combination_strategies + ADD CONSTRAINT fk_rails_b95038cdbe FOREIGN KEY (function_generic_mapper_id) REFERENCES function_generic_mappers(id) ON DELETE CASCADE; +ALTER TABLE ONLY reference_values + ADD CONSTRAINT fk_rails_bb34a5d62c FOREIGN KEY (data_type_identifier_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; --- --- Name: runtimes fk_rails_eeb42116cc; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_bb587eff6a FOREIGN KEY (input_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; -ALTER TABLE ONLY public.runtimes - ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES public.namespaces(id); +ALTER TABLE ONLY flow_types + ADD CONSTRAINT fk_rails_bead35b1a6 FOREIGN KEY (return_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; +ALTER TABLE ONLY namespace_project_runtime_assignments + ADD CONSTRAINT fk_rails_c019e5b233 FOREIGN KEY (namespace_project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; --- --- Name: audit_events fk_rails_f64374fc56; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY active_storage_attachments + ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES active_storage_blobs(id); -ALTER TABLE ONLY public.audit_events - ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES public.users(id) ON DELETE SET NULL; +ALTER TABLE ONLY namespace_project_runtime_assignments + ADD CONSTRAINT fk_rails_c640af2146 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +ALTER TABLE ONLY generic_mappers + ADD CONSTRAINT fk_rails_c7984c8a7a FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; --- --- Name: flow_type_settings fk_rails_f6af7d8edf; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY parameter_definitions + ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; -ALTER TABLE ONLY public.flow_type_settings - ADD CONSTRAINT fk_rails_f6af7d8edf FOREIGN KEY (flow_type_id) REFERENCES public.flow_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY data_type_identifiers + ADD CONSTRAINT fk_rails_d08626f743 FOREIGN KEY (function_generic_mapper_id) REFERENCES function_generic_mappers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY namespace_projects + ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; --- --- Name: node_functions fk_rails_fbc91a3407; Type: FK CONSTRAINT; Schema: public; Owner: - --- +ALTER TABLE ONLY flows + ADD CONSTRAINT fk_rails_d9ad50fe4b FOREIGN KEY (flow_type_id) REFERENCES flow_types(id) ON DELETE CASCADE; -ALTER TABLE ONLY public.node_functions - ADD CONSTRAINT fk_rails_fbc91a3407 FOREIGN KEY (next_node_id) REFERENCES public.node_functions(id) ON DELETE RESTRICT; +ALTER TABLE ONLY flow_settings + ADD CONSTRAINT fk_rails_da3b2fb3c5 FOREIGN KEY (flow_id) REFERENCES flows(id) ON DELETE CASCADE; +ALTER TABLE ONLY generic_mappers + ADD CONSTRAINT fk_rails_e0d918961b FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE RESTRICT; --- --- PostgreSQL database dump complete --- +ALTER TABLE ONLY runtime_parameter_definitions + ADD CONSTRAINT fk_rails_e64f825793 FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; -SET search_path TO "$user", public; +ALTER TABLE ONLY runtimes + ADD CONSTRAINT fk_rails_eeb42116cc FOREIGN KEY (namespace_id) REFERENCES namespaces(id); +ALTER TABLE ONLY audit_events + ADD CONSTRAINT fk_rails_f64374fc56 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL; +ALTER TABLE ONLY flow_type_settings + ADD CONSTRAINT fk_rails_f6af7d8edf FOREIGN KEY (flow_type_id) REFERENCES flow_types(id) ON DELETE CASCADE; +ALTER TABLE ONLY node_functions + ADD CONSTRAINT fk_rails_fbc91a3407 FOREIGN KEY (next_node_id) REFERENCES node_functions(id) ON DELETE RESTRICT; diff --git a/spec/factories/generic_mappers.rb b/spec/factories/generic_mappers.rb index ba3ea1e7..8aefd3fc 100644 --- a/spec/factories/generic_mappers.rb +++ b/spec/factories/generic_mappers.rb @@ -4,7 +4,7 @@ factory :generic_mapper do runtime target { nil } - sources { nil } + source { nil } generic_combination_strategies { [] } end end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb index 01dd84c3..8b26abd8 100644 --- a/spec/models/data_type_identifier_spec.rb +++ b/spec/models/data_type_identifier_spec.rb @@ -8,8 +8,8 @@ it { is_expected.to belong_to(:data_type).optional } it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to belong_to(:generic_mapper).optional.inverse_of(:sources) } - it { is_expected.to belong_to(:function_generic_mapper).optional.inverse_of(:sources) } + it { is_expected.to belong_to(:generic_mapper).optional.inverse_of(:source) } + it { is_expected.to belong_to(:function_generic_mapper).optional.inverse_of(:source) } it { is_expected.to have_many(:child_types).class_name('DataType').inverse_of(:parent_type) } end diff --git a/spec/models/function_definition_spec.rb b/spec/models/function_definition_spec.rb index fafdd6eb..8b71fa5c 100644 --- a/spec/models/function_definition_spec.rb +++ b/spec/models/function_definition_spec.rb @@ -11,5 +11,10 @@ it { is_expected.to have_many(:names).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:descriptions).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:documentations).class_name('Translation').inverse_of(:owner) } + + it { + is_expected.to have_many(:generic_combination_strategies) + .class_name('GenericCombinationStrategy').inverse_of(:function_generic_mapper) + } end end diff --git a/spec/models/function_generic_mapper_spec.rb b/spec/models/function_generic_mapper_spec.rb index 4c3aa23e..98388818 100644 --- a/spec/models/function_generic_mapper_spec.rb +++ b/spec/models/function_generic_mapper_spec.rb @@ -4,7 +4,7 @@ RSpec.describe FunctionGenericMapper do describe 'associations' do - it { is_expected.to have_many(:sources).class_name('DataTypeIdentifier').inverse_of(:function_generic_mapper) } + it { is_expected.to have_many(:source).class_name('DataTypeIdentifier').inverse_of(:function_generic_mapper) } it { is_expected.to belong_to(:runtime_parameter_definition).optional } it { diff --git a/spec/models/generic_combination_strategy_spec.rb b/spec/models/generic_combination_strategy_spec.rb index 0d9b7eac..fdf68c3f 100644 --- a/spec/models/generic_combination_strategy_spec.rb +++ b/spec/models/generic_combination_strategy_spec.rb @@ -4,7 +4,8 @@ RSpec.describe GenericCombinationStrategy do describe 'associations' do - it { is_expected.to belong_to(:generic_mapper) } + it { is_expected.to belong_to(:generic_mapper).optional } + it { is_expected.to belong_to(:function_generic_mapper).optional } end describe 'enums' do diff --git a/spec/models/generic_mapper_spec.rb b/spec/models/generic_mapper_spec.rb index b2481b8f..f643d4b8 100644 --- a/spec/models/generic_mapper_spec.rb +++ b/spec/models/generic_mapper_spec.rb @@ -7,7 +7,7 @@ describe 'associations' do it { is_expected.to belong_to(:generic_type).optional } it { is_expected.to belong_to(:runtime) } - it { is_expected.to have_many(:sources).class_name('DataTypeIdentifier').inverse_of(:generic_mapper) } + it { is_expected.to have_many(:source).class_name('DataTypeIdentifier').inverse_of(:generic_mapper) } it { is_expected.to have_many(:generic_combination_strategies) diff --git a/spec/requests/grpc/sagittarius/data_type_service_spec.rb b/spec/requests/grpc/sagittarius/data_type_service_spec.rb index c79812e9..f610356f 100644 --- a/spec/requests/grpc/sagittarius/data_type_service_spec.rb +++ b/spec/requests/grpc/sagittarius/data_type_service_spec.rb @@ -54,7 +54,9 @@ name: [ { code: 'de_DE', content: 'Kleine positive Zahl' } ], - parent_type_identifier: 'positive_number', + parent_type: { + data_type_identifier: 'positive_number', + }, rules: [ Tucana::Shared::DataTypeRule.create(:number_range, { from: 9 }) ], @@ -84,7 +86,7 @@ expect(positive_number.generic_keys).to be_empty expect(small_positive_number.generic_keys).to eq(['T']) - expect(small_positive_number.parent_type).to eq(positive_number) + expect(small_positive_number.parent_type.data_type).to eq(positive_number) end end diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 06dcb862..569f118c 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -81,7 +81,7 @@ expect(stub.update(message, authorization(runtime)).success).to be(true) expect(GenericMapper.count).to eq(1) - expect(GenericMapper.last.sources.first.generic_key).to eq('T') + expect(GenericMapper.last.source.first.generic_key).to eq('T') expect(GenericMapper.last.target).to eq('V') expect(GenericType.count).to eq(1) @@ -117,7 +117,7 @@ expect(parameter_definition.default_value).to eq({ 'key' => 'value' }) expect(FunctionGenericMapper.count).to eq(1) - expect(FunctionGenericMapper.last.sources.first.generic_key).to eq('X') + expect(FunctionGenericMapper.last.source.first.generic_key).to eq('X') expect(FunctionGenericMapper.last.target).to eq('Y') expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') end diff --git a/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb index 3f118045..0b445b87 100644 --- a/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb @@ -45,7 +45,7 @@ create(:data_type_identifier, generic_key: 'T', runtime: runtime) end let(:generic_mapper) do - create(:generic_mapper, sources: [data_type_identifier], target: 'T') + create(:generic_mapper, source: [data_type_identifier], target: 'T') end context 'when generic mapper points to a existing generic_key' do From fa0f9440650fe599bcb5f095ad784ed9d1158b50 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Sun, 1 Jun 2025 01:19:15 +0200 Subject: [PATCH 42/54] Update tucana gem version to 0.0.30 --- Gemfile | 2 +- Gemfile.lock | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index 3eca0b2e..7194b72f 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.0', path: '../tucana/build/ruby' +gem 'tucana', '0.0.30' gem 'code0-identities', '~> 0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index ac19d5d5..a79540dd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,9 +1,3 @@ -PATH - remote: ../tucana/build/ruby - specs: - tucana (0.0.0) - grpc (~> 1.64) - GEM remote: https://rubygems.org/ specs: @@ -368,6 +362,8 @@ GEM test-prof (1.4.4) thor (1.3.2) timeout (0.4.3) + tucana (0.0.30) + grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.6.0) @@ -420,7 +416,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 2.1) test-prof (~> 1.0) - tucana (= 0.0.0)! + tucana (= 0.0.30) tzinfo-data RUBY VERSION From 37731db6c9801ecf4e11831dbe6937c4b90e3ea7 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:11:16 +0200 Subject: [PATCH 43/54] remove parameter_id of function generic mapper --- .../runtime_function_definitions/update_service.rb | 13 +++++++++---- db/migrate/20250525192143_implement_generics.rb | 2 -- db/structure.sql | 1 - .../runtime_function_definition_service_spec.rb | 6 +++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 80b15125..01b153c9 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -37,12 +37,12 @@ def update_runtime_function_definition(runtime_function_definition, t) runtime_name: runtime_function_definition.runtime_name ) db_object.removed_at = nil + db_object.parameters = update_parameters(db_object, runtime_function_definition.runtime_parameter_definitions, + db_object.parameters, t) db_object.return_type = if runtime_function_definition.return_type_identifier.present? find_data_type_identifier(runtime_function_definition.return_type_identifier, runtime_function_definition.generic_mappers, t) end - db_object.parameters = update_parameters(runtime_function_definition.runtime_parameter_definitions, - db_object.parameters, t) db_object.names = update_translations(runtime_function_definition.name, db_object.names) db_object.descriptions = update_translations(runtime_function_definition.description, db_object.descriptions) db_object.documentations = update_translations(runtime_function_definition.documentation, @@ -79,12 +79,14 @@ def update_mappers(generic_mappers, runtime_function_definition, t) end) end if generic_mapper.is_a? Tucana::Shared::FunctionGenericMapper + parameter = RuntimeParameterDefinition.find_by(runtime_name: generic_mapper.parameter_id, + runtime_function_definition: runtime_function_definition) mapper = FunctionGenericMapper.create_or_find_by( runtime_id: current_runtime.id, runtime_function_definition: runtime_function_definition, source: generic_mapper.source.map { |source| find_data_type_identifier(source, generic_mappers, t) }, target: generic_mapper.target, - parameter_id: generic_mapper.parameter_id + runtime_parameter_definition: parameter ) end @@ -161,7 +163,7 @@ def find_data_type(identifier, t) data_type end - def update_parameters(parameters, db_parameters, t) + def update_parameters(runtime_function_definition, parameters, db_parameters, t) # rubocop:disable Rails/SkipsModelValidations -- when marking definitions as removed, we don't care about validations db_parameters.update_all(removed_at: Time.zone.now) # rubocop:enable Rails/SkipsModelValidations @@ -172,6 +174,7 @@ def update_parameters(parameters, db_parameters, t) db_param = RuntimeParameterDefinition.new db_parameters << db_param end + db_param.runtime_function_definition = runtime_function_definition db_param.runtime_name = real_param.runtime_name db_param.removed_at = nil db_param.data_type = find_data_type_identifier(real_param.data_type_identifier, [], t) @@ -182,6 +185,8 @@ def update_parameters(parameters, db_parameters, t) db_param.default_value = real_param.default_value&.to_ruby(true) + db_param.save + next unless db_param.parameter_definitions.empty? definition = ParameterDefinition.new diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 1307dd54..2004d40a 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -41,8 +41,6 @@ def change create_table :function_generic_mappers do |t| t.text :target, null: false - t.text :parameter_id, null: true - t.references :runtime_parameter_definition, null: true, foreign_key: { to_table: :runtime_parameter_definitions, on_delete: :restrict } diff --git a/db/structure.sql b/db/structure.sql index 6f005916..1fea36d5 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -283,7 +283,6 @@ ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; CREATE TABLE function_generic_mappers ( id bigint NOT NULL, target text NOT NULL, - parameter_id text, runtime_parameter_definition_id bigint, runtime_function_definition_id bigint, runtime_id bigint NOT NULL, diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 569f118c..42103a8e 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -56,7 +56,7 @@ data_type_identifier: { data_type_identifier: parameter_type.data_type.identifier, }, - runtime_name: 'runtime_parameter_definition_id', + runtime_name: 'some_id', default_value: Tucana::Shared::Value.from_ruby({ 'key' => 'value' }), name: [ { code: 'de_DE', content: 'Ein Parameter' } @@ -97,7 +97,7 @@ expect(function.error_types.first.data_type.identifier).to eq(error_type.identifier) parameter = function.parameters.first expect(parameter.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) - expect(parameter.runtime_name).to eq('runtime_parameter_definition_id') + expect(parameter.runtime_name).to eq('some_id') expect(parameter.names.first.content).to eq('Ein Parameter') expect(parameter.descriptions.first.content).to eq('Eine Parameterbeschreibung') expect(parameter.documentations.first.content).to eq('Eine Parameterdokumentation') @@ -119,7 +119,7 @@ expect(FunctionGenericMapper.count).to eq(1) expect(FunctionGenericMapper.last.source.first.generic_key).to eq('X') expect(FunctionGenericMapper.last.target).to eq('Y') - expect(FunctionGenericMapper.last.parameter_id).to eq('some_id') + expect(FunctionGenericMapper.last.runtime_parameter_definition.runtime_name).to eq('some_id') end end From 49786ec4a59d6887007c6cfed0bccf2bdd3dfeea Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:12:59 +0200 Subject: [PATCH 44/54] remove_reference also has specifies the foreign key now --- db/migrate/20250525192143_implement_generics.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 2004d40a..981e91c4 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -74,7 +74,10 @@ def change add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_reference :data_types, :parent_type + remove_reference :data_types, :parent_type, + null: true, + foreign_key: { to_table: :data_types, on_delete: :restrict } + add_reference :data_types, :parent_type, null: true, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict } From 9b522ce4345ed8bab40263552da77c5b7ef62ebc Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:20:39 +0200 Subject: [PATCH 45/54] Add validation and constraints for generic_keys length in data types and runtime function definitions --- app/models/data_type.rb | 7 +++++++ app/models/runtime_function_definition.rb | 8 ++++++++ db/migrate/20250525192143_implement_generics.rb | 11 +++++++++++ spec/models/data_type_spec.rb | 10 ++++++++++ spec/models/runtime_function_definition_spec.rb | 14 +++++++++++++- 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/app/models/data_type.rb b/app/models/data_type.rb index 635c5459..bf5cb326 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -26,6 +26,8 @@ class DataType < ApplicationRecord in: VARIANTS.keys.map(&:to_s), } + validate :generic_keys_length + validate :validate_recursion, if: :parent_type_changed? def validate_recursion @@ -39,4 +41,9 @@ def validate_recursion end end end + + def generic_keys_length + errors.add(:generic_keys, 'each key must be 50 characters or fewer') if generic_keys.any? { |key| key.length > 50 } + errors.add(:generic_keys, 'must be 30 or fewer') if generic_keys.size > 30 + end end diff --git a/app/models/runtime_function_definition.rb b/app/models/runtime_function_definition.rb index f22f6ee8..a6c4d165 100644 --- a/app/models/runtime_function_definition.rb +++ b/app/models/runtime_function_definition.rb @@ -19,4 +19,12 @@ class RuntimeFunctionDefinition < ApplicationRecord validates :runtime_name, presence: true, length: { minimum: 3, maximum: 50 }, uniqueness: { case_sensitive: false, scope: :runtime_id } + + validate :generic_keys_length + + def generic_keys_length + errors.add(:generic_keys, 'each key must be 50 characters or fewer') if generic_keys.any? { |key| key.length > 50 } + errors.add(:generic_keys, 'must be 30 or fewer') if generic_keys.size > 30 + end + end diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index 981e91c4..d6d3b76a 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -6,6 +6,11 @@ def change # https://github.com/code0-tech/tucana/pull/93 add_column :data_types, :generic_keys, 'text[]', null: false, default: [] + add_check_constraint :data_types, + "NOT EXISTS ( + SELECT 1 FROM unnest(generic_keys) AS key + WHERE length(key) > 50 + )", name: 'generic_keys_max_length' create_table :data_type_identifiers do |t| # One of them needs to be set will be enforced later @@ -61,6 +66,12 @@ def change add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] + add_check_constraint :runtime_function_definitions, + "NOT EXISTS ( + SELECT 1 FROM unnest(generic_keys) AS key + WHERE length(key) > 50 + )", name: 'generic_keys_max_length' + remove_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_parameter_definitions, :data_type, diff --git a/spec/models/data_type_spec.rb b/spec/models/data_type_spec.rb index 083373b0..8cf2496b 100644 --- a/spec/models/data_type_spec.rb +++ b/spec/models/data_type_spec.rb @@ -15,6 +15,16 @@ describe 'validations' do it { is_expected.to allow_values(*described_class::VARIANTS.keys).for(:variant) } + context 'when generic keys are too long' do + let(:data_type) { build(:data_type, generic_keys: Array.new(31, 'a' * 51)) } # 31 keys, each 51 characters long + + it 'is expected to be invalid' do + expect(data_type).not_to be_valid + expect(data_type.errors[:generic_keys]).to include('each key must be 50 characters or fewer') + expect(data_type.errors[:generic_keys]).to include('must be 30 or fewer') + end + end + it 'detects recursions' do dt1 = create(:data_type) dt2 = create(:data_type, parent_type: create(:data_type_identifier, data_type: dt1)) diff --git a/spec/models/runtime_function_definition_spec.rb b/spec/models/runtime_function_definition_spec.rb index 67b8b0b0..9970702c 100644 --- a/spec/models/runtime_function_definition_spec.rb +++ b/spec/models/runtime_function_definition_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe RuntimeFunctionDefinition do - subject { create(:runtime_function_definition) } + subject(:function) { create(:runtime_function_definition) } describe 'validations' do it { is_expected.to have_many(:parameters).inverse_of(:runtime_function_definition) } @@ -11,6 +11,18 @@ it { is_expected.to validate_presence_of(:runtime_name) } it { is_expected.to validate_uniqueness_of(:runtime_name).case_insensitive.scoped_to(:runtime_id) } it { is_expected.to validate_length_of(:runtime_name).is_at_most(50) } + + context 'when generic keys are too long' do + before do + function.generic_keys = Array.new(31, 'a' * 51) # 31 keys, each 51 characters long + end + + it 'is expected to be invalid' do + expect(function).not_to be_valid + expect(function.errors[:generic_keys]).to include('each key must be 50 characters or fewer') + expect(function.errors[:generic_keys]).to include('must be 30 or fewer') + end + end end describe 'associations' do From 12d5a594bef886a2c31cdb7ea42586a4660add1a Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:27:34 +0200 Subject: [PATCH 46/54] Remove runtime association from GenericType and related specs and remove database level constraint for generic_keys (model only) --- app/models/generic_type.rb | 5 ++--- app/models/runtime.rb | 1 - app/services/runtimes/data_types/update_service.rb | 1 - .../runtime_function_definitions/update_service.rb | 1 - db/migrate/20250525192143_implement_generics.rb | 12 ------------ db/structure.sql | 6 ------ spec/factories/generic_types.rb | 1 - spec/models/generic_type_spec.rb | 1 - spec/models/runtime_spec.rb | 1 - .../runtime_function_definition_service_spec.rb | 2 +- .../generic_mapper_validation_service_spec.rb | 4 ++-- 11 files changed, 5 insertions(+), 30 deletions(-) diff --git a/app/models/generic_type.rb b/app/models/generic_type.rb index b67edf49..7c1291f3 100644 --- a/app/models/generic_type.rb +++ b/app/models/generic_type.rb @@ -2,15 +2,14 @@ class GenericType < ApplicationRecord belongs_to :data_type, class_name: 'DataType', inverse_of: :generic_types - belongs_to :runtime, class_name: 'Runtime', inverse_of: :generic_types has_many :generic_mappers, inverse_of: :generic_type has_many :data_type_identifiers, class_name: 'DataTypeIdentifier', inverse_of: :generic_type - def to_grcp + def to_grpc Tucana::Sagittarius::GenericType.new( data_type_identifier: data_type_identifier&.data_type&.identifier, - generic_mappers: generic_mappers.map(&:to_grcp) + generic_mappers: generic_mappers.map(&:to_grpc) ) end end diff --git a/app/models/runtime.rb b/app/models/runtime.rb index eee6ffa8..ae479487 100644 --- a/app/models/runtime.rb +++ b/app/models/runtime.rb @@ -15,7 +15,6 @@ class Runtime < ApplicationRecord has_many :data_types, inverse_of: :runtime has_many :data_type_identifiers, inverse_of: :runtime - has_many :generic_types, inverse_of: :runtime has_many :generic_mappers, inverse_of: :runtime has_many :flow_types, inverse_of: :runtime diff --git a/app/services/runtimes/data_types/update_service.rb b/app/services/runtimes/data_types/update_service.rb index c9e61cd9..ed1cb356 100644 --- a/app/services/runtimes/data_types/update_service.rb +++ b/app/services/runtimes/data_types/update_service.rb @@ -69,7 +69,6 @@ def find_data_type_identifier(identifier, t) data_type = find_datatype(identifier.generic_type.data_type_identifier, t) generic_type = GenericType.find_by( - runtime_id: current_runtime.id, data_type: data_type ) if generic_type.nil? diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 01b153c9..20f48992 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -109,7 +109,6 @@ def find_data_type_identifier(identifier, _generic_mappers, t) data_type = find_data_type(identifier.generic_type.data_type_identifier, t) generic_type = GenericType.find_by( - runtime_id: current_runtime.id, data_type: data_type ) if generic_type.nil? diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index d6d3b76a..bcefb180 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -6,11 +6,6 @@ def change # https://github.com/code0-tech/tucana/pull/93 add_column :data_types, :generic_keys, 'text[]', null: false, default: [] - add_check_constraint :data_types, - "NOT EXISTS ( - SELECT 1 FROM unnest(generic_keys) AS key - WHERE length(key) > 50 - )", name: 'generic_keys_max_length' create_table :data_type_identifiers do |t| # One of them needs to be set will be enforced later @@ -23,7 +18,6 @@ def change end create_table :generic_types do |t| - t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } t.references :data_type, null: false, foreign_key: { to_table: :data_types, on_delete: :cascade } t.timestamps_with_timezone @@ -66,12 +60,6 @@ def change add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] - add_check_constraint :runtime_function_definitions, - "NOT EXISTS ( - SELECT 1 FROM unnest(generic_keys) AS key - WHERE length(key) > 50 - )", name: 'generic_keys_max_length' - remove_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_parameter_definitions, :data_type, diff --git a/db/structure.sql b/db/structure.sql index 1fea36d5..d971982a 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -337,7 +337,6 @@ ALTER SEQUENCE generic_mappers_id_seq OWNED BY generic_mappers.id; CREATE TABLE generic_types ( id bigint NOT NULL, - runtime_id bigint NOT NULL, data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL @@ -1175,8 +1174,6 @@ CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); -CREATE INDEX index_generic_types_on_runtime_id ON generic_types USING btree (runtime_id); - CREATE INDEX index_good_job_executions_on_active_job_id_and_created_at ON good_job_executions USING btree (active_job_id, created_at); CREATE INDEX index_good_job_executions_on_process_id_and_created_at ON good_job_executions USING btree (process_id, created_at); @@ -1308,9 +1305,6 @@ ALTER TABLE ONLY generic_combination_strategies ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; -ALTER TABLE ONLY generic_types - ADD CONSTRAINT fk_rails_20f4bf6b34 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; - ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT fk_rails_260318ad67 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb index a7601bec..32458025 100644 --- a/spec/factories/generic_types.rb +++ b/spec/factories/generic_types.rb @@ -2,7 +2,6 @@ FactoryBot.define do factory :generic_type do - runtime generic_mappers { [] } data_type end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb index 86ff0fec..9254edf4 100644 --- a/spec/models/generic_type_spec.rb +++ b/spec/models/generic_type_spec.rb @@ -6,7 +6,6 @@ RSpec.describe GenericType do describe 'associations' do it { is_expected.to belong_to(:data_type) } - it { is_expected.to belong_to(:runtime) } it { is_expected.to have_many(:generic_mappers) } end end diff --git a/spec/models/runtime_spec.rb b/spec/models/runtime_spec.rb index 395b5e21..796bfc6e 100644 --- a/spec/models/runtime_spec.rb +++ b/spec/models/runtime_spec.rb @@ -9,7 +9,6 @@ it { is_expected.to belong_to(:namespace).optional } it { is_expected.to have_many(:data_types).inverse_of(:runtime) } it { is_expected.to have_many(:data_type_identifiers).inverse_of(:runtime) } - it { is_expected.to have_many(:generic_types).inverse_of(:runtime) } it { is_expected.to have_many(:generic_mappers).inverse_of(:runtime) } it { is_expected.to have_many(:flow_types).inverse_of(:runtime) } diff --git a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb index 42103a8e..2288f26a 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -15,7 +15,7 @@ end let!(:generic_type) do - create(:generic_type, runtime: runtime, data_type: create(:data_type, runtime: runtime)) + create(:generic_type, data_type: create(:data_type, runtime: runtime)) end let!(:return_type) { create(:data_type_identifier, runtime: runtime, generic_type: generic_type.reload).reload } let(:error_type) { create(:data_type, runtime: runtime) } diff --git a/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb index 0b445b87..57b3a9e2 100644 --- a/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb @@ -27,8 +27,8 @@ data_type: create(:data_type_identifier, generic_type: create(:generic_type, data_type: create(:data_type), - generic_mappers: [generic_mapper], - runtime: runtime))), + generic_mappers: [generic_mapper] + ))), literal_value: nil, function_value: create(:node_function)) end From f17379ed6c13d1a89f0c9da49ca40b31a5fa5175 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:28:24 +0200 Subject: [PATCH 47/54] Fix rubocop vulnerabilities --- app/models/runtime_function_definition.rb | 1 - .../node_function/generic_mapper_validation_service_spec.rb | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/models/runtime_function_definition.rb b/app/models/runtime_function_definition.rb index a6c4d165..ec25ba83 100644 --- a/app/models/runtime_function_definition.rb +++ b/app/models/runtime_function_definition.rb @@ -26,5 +26,4 @@ def generic_keys_length errors.add(:generic_keys, 'each key must be 50 characters or fewer') if generic_keys.any? { |key| key.length > 50 } errors.add(:generic_keys, 'must be 30 or fewer') if generic_keys.size > 30 end - end diff --git a/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb b/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb index 57b3a9e2..fe35287b 100644 --- a/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb +++ b/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb @@ -27,8 +27,7 @@ data_type: create(:data_type_identifier, generic_type: create(:generic_type, data_type: create(:data_type), - generic_mappers: [generic_mapper] - ))), + generic_mappers: [generic_mapper]))), literal_value: nil, function_value: create(:node_function)) end From c3ddbc9b8586bd2c9ea8eb64008893f0fd81ba10 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:29:23 +0200 Subject: [PATCH 48/54] Update references in runtime and parameter definitions to allow null values --- db/migrate/20250525192143_implement_generics.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index bcefb180..f0cf4671 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -54,6 +54,7 @@ def change end remove_reference :runtime_function_definitions, :return_type, + null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true @@ -61,15 +62,20 @@ def change add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] remove_reference :runtime_parameter_definitions, :data_type, + null: true, foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :runtime_parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_reference :parameter_definitions, :data_type, + null: true, + foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :parameter_definitions, :data_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true - remove_reference :function_definitions, :return_type, foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_reference :function_definitions, :return_type, + null: true, + foreign_key: { to_table: :data_types, on_delete: :restrict } add_reference :function_definitions, :return_type, foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, null: true From 10acdb0beef46aef38eb1d6d2c9c2fcd0345fd8f Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:32:18 +0200 Subject: [PATCH 49/54] Add presence and inclusion validations for type in GenericCombinationStrategy and status in Runtime --- app/models/generic_combination_strategy.rb | 5 +++++ app/models/runtime.rb | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/models/generic_combination_strategy.rb b/app/models/generic_combination_strategy.rb index 092e5dcb..2b88df1a 100644 --- a/app/models/generic_combination_strategy.rb +++ b/app/models/generic_combination_strategy.rb @@ -10,4 +10,9 @@ class GenericCombinationStrategy < ApplicationRecord belongs_to :function_generic_mapper, optional: true, inverse_of: :generic_combination_strategies enum :type, TYPES, prefix: :type + + validates :type, presence: true, + inclusion: { + in: TYPES.keys.map(&:to_s), + } end diff --git a/app/models/runtime.rb b/app/models/runtime.rb index ae479487..ab1e6598 100644 --- a/app/models/runtime.rb +++ b/app/models/runtime.rb @@ -3,11 +3,21 @@ class Runtime < ApplicationRecord include TokenAttr + STATUS_TYPES = { + disconnected: 0, + connected: 1 + }.with_indifferent_access + belongs_to :namespace, optional: true token_attr :token, prefix: 's_rt_', length: 48 - enum :status, { disconnected: 0, connected: 1 }, default: :disconnected + enum :status, STATUS_TYPES, default: :disconnected + + validates :status, presence: true, + inclusion: { + in: STATUS_TYPES.keys.map(&:to_s), + } has_many :project_assignments, class_name: 'NamespaceProjectRuntimeAssignment', inverse_of: :runtime has_many :projects, class_name: 'NamespaceProject', through: :project_assignments, source: :namespace_project, From 0d9487dc9fb28c0dd6473a2063735809882635a8 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:33:44 +0200 Subject: [PATCH 50/54] Change :base to :value --- app/models/node_parameter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/node_parameter.rb b/app/models/node_parameter.rb index f580828d..e2321368 100644 --- a/app/models/node_parameter.rb +++ b/app/models/node_parameter.rb @@ -31,7 +31,7 @@ def only_one_value_present values = [literal_value.present?, reference_value.present?, function_value.present?] return if values.count(true) == 1 - errors.add(:base, + errors.add(:value, 'Exactly one of literal_value, reference_value, or function_value must be present') end end From b836858b374b06a0e7490524882dc0d866b015b9 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:36:59 +0200 Subject: [PATCH 51/54] Change description of abilities and remove update_flows as its not implemented yet --- app/models/generic_combination_strategy.rb | 6 +++--- app/models/namespace_role_ability.rb | 5 ++--- app/models/runtime.rb | 8 ++++---- spec/models/node_parameter_spec.rb | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/models/generic_combination_strategy.rb b/app/models/generic_combination_strategy.rb index 2b88df1a..188f2532 100644 --- a/app/models/generic_combination_strategy.rb +++ b/app/models/generic_combination_strategy.rb @@ -12,7 +12,7 @@ class GenericCombinationStrategy < ApplicationRecord enum :type, TYPES, prefix: :type validates :type, presence: true, - inclusion: { - in: TYPES.keys.map(&:to_s), - } + inclusion: { + in: TYPES.keys.map(&:to_s), + } end diff --git a/app/models/namespace_role_ability.rb b/app/models/namespace_role_ability.rb index 650d9dd4..f6ce69bd 100644 --- a/app/models/namespace_role_ability.rb +++ b/app/models/namespace_role_ability.rb @@ -25,9 +25,8 @@ class NamespaceRoleAbility < ApplicationRecord rotate_runtime_token: { db: 21, description: 'Allows to regenerate a runtime token' }, assign_role_projects: { db: 22, description: 'Allows to change the assigned projects of a namespace role' }, assign_project_runtimes: { db: 23, description: 'Allows to assign runtimes to a project in the namespace' }, - create_flows: { db: 24, description: 'Allows to create flows in the namespace' }, - update_flows: { db: 25, description: 'Allows to update flows in the namespace' }, - delete_flows: { db: 26, description: 'Allows to delete flows in the namespace' }, + create_flows: { db: 24, description: 'Allows to create flows in a namespace project' }, + delete_flows: { db: 25, description: 'Allows to delete flows in a namespace project' }, }.with_indifferent_access enum :ability, ABILITIES.transform_values { |v| v[:db] }, prefix: :can diff --git a/app/models/runtime.rb b/app/models/runtime.rb index ab1e6598..178a2eb8 100644 --- a/app/models/runtime.rb +++ b/app/models/runtime.rb @@ -5,7 +5,7 @@ class Runtime < ApplicationRecord STATUS_TYPES = { disconnected: 0, - connected: 1 + connected: 1, }.with_indifferent_access belongs_to :namespace, optional: true @@ -15,9 +15,9 @@ class Runtime < ApplicationRecord enum :status, STATUS_TYPES, default: :disconnected validates :status, presence: true, - inclusion: { - in: STATUS_TYPES.keys.map(&:to_s), - } + inclusion: { + in: STATUS_TYPES.keys.map(&:to_s), + } has_many :project_assignments, class_name: 'NamespaceProjectRuntimeAssignment', inverse_of: :runtime has_many :projects, class_name: 'NamespaceProject', through: :project_assignments, source: :namespace_project, diff --git a/spec/models/node_parameter_spec.rb b/spec/models/node_parameter_spec.rb index bc0c2593..3635fc3e 100644 --- a/spec/models/node_parameter_spec.rb +++ b/spec/models/node_parameter_spec.rb @@ -27,7 +27,7 @@ data_type: create(:data_type_identifier, data_type: create(:data_type)))) expect(param).not_to be_valid - expect(param.errors[:base]) + expect(param.errors[:value]) .to include('Exactly one of literal_value, reference_value, or function_value must be present') end end From a6ff8ba38b2e23382f32b7b9b1a0822d3b69505b Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:41:53 +0200 Subject: [PATCH 52/54] Update foreign key constraints to use cascade on delete and enforce presence for type in GenericCombinationStrategy --- app/models/function_definition.rb | 3 --- db/migrate/20250525192143_implement_generics.rb | 4 ++-- db/migrate/20250526124346_create_flows.rb | 6 ++---- .../20250530213244_create_generic_combination_strategies.rb | 2 +- spec/models/function_definition_spec.rb | 5 ----- 5 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/models/function_definition.rb b/app/models/function_definition.rb index 5d58eb93..389961a7 100644 --- a/app/models/function_definition.rb +++ b/app/models/function_definition.rb @@ -4,9 +4,6 @@ class FunctionDefinition < ApplicationRecord belongs_to :runtime_function_definition belongs_to :return_type, class_name: 'DataTypeIdentifier', optional: true - has_many :generic_combination_strategies, - class_name: 'GenericCombinationStrategy', inverse_of: :function_generic_mapper - has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :documentations, -> { by_purpose(:documentation) }, class_name: 'Translation', as: :owner, inverse_of: :owner diff --git a/db/migrate/20250525192143_implement_generics.rb b/db/migrate/20250525192143_implement_generics.rb index f0cf4671..40101cdb 100644 --- a/db/migrate/20250525192143_implement_generics.rb +++ b/db/migrate/20250525192143_implement_generics.rb @@ -89,9 +89,9 @@ def change add_reference :data_type_identifiers, :generic_mapper, null: true, foreign_key: { to_table: :generic_mappers, - on_delete: :restrict } + on_delete: :cascade } add_reference :data_type_identifiers, :function_generic_mapper, null: true, foreign_key: { to_table: :function_generic_mappers, - on_delete: :restrict } + on_delete: :cascade } end end diff --git a/db/migrate/20250526124346_create_flows.rb b/db/migrate/20250526124346_create_flows.rb index bc605938..4501cf3c 100644 --- a/db/migrate/20250526124346_create_flows.rb +++ b/db/migrate/20250526124346_create_flows.rb @@ -37,7 +37,7 @@ def change t.jsonb :literal_value, null: true t.references :reference_value, null: true, foreign_key: { to_table: :reference_values, - on_delete: :restrict } + on_delete: :cascade } t.references :function_value, null: true, foreign_key: { to_table: :node_functions, on_delete: :restrict } @@ -62,10 +62,8 @@ def change t.timestamps_with_timezone end - add_reference :data_types, :flows, null: true, foreign_key: { to_table: :flows, on_delete: :restrict } - create_table :flow_settings do |t| - t.references :flow, null: true, foreign_key: { to_table: :flows, on_delete: :cascade } + t.references :flow, null: false, foreign_key: { to_table: :flows, on_delete: :cascade } t.text :flow_setting_id, null: false t.jsonb :object, null: false diff --git a/db/migrate/20250530213244_create_generic_combination_strategies.rb b/db/migrate/20250530213244_create_generic_combination_strategies.rb index 1655ab92..6500e5f3 100644 --- a/db/migrate/20250530213244_create_generic_combination_strategies.rb +++ b/db/migrate/20250530213244_create_generic_combination_strategies.rb @@ -3,7 +3,7 @@ class CreateGenericCombinationStrategies < Code0::ZeroTrack::Database::Migration[1.0] def change create_table :generic_combination_strategies do |t| - t.integer :type + t.integer :type, null: false t.references :generic_mapper, null: true, foreign_key: { to_table: :generic_mappers, on_delete: :cascade, diff --git a/spec/models/function_definition_spec.rb b/spec/models/function_definition_spec.rb index 8b71fa5c..fafdd6eb 100644 --- a/spec/models/function_definition_spec.rb +++ b/spec/models/function_definition_spec.rb @@ -11,10 +11,5 @@ it { is_expected.to have_many(:names).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:descriptions).class_name('Translation').inverse_of(:owner) } it { is_expected.to have_many(:documentations).class_name('Translation').inverse_of(:owner) } - - it { - is_expected.to have_many(:generic_combination_strategies) - .class_name('GenericCombinationStrategy').inverse_of(:function_generic_mapper) - } end end From c37d4f1143e2968d2820c5cf12d29a84af77f6ce Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:43:32 +0200 Subject: [PATCH 53/54] Regenerate docs --- docs/graphql/enum/namespaceroleability.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/graphql/enum/namespaceroleability.md b/docs/graphql/enum/namespaceroleability.md index 810c90a6..98f25db2 100644 --- a/docs/graphql/enum/namespaceroleability.md +++ b/docs/graphql/enum/namespaceroleability.md @@ -10,12 +10,12 @@ Represents abilities that can be granted to roles in namespaces. | `ASSIGN_PROJECT_RUNTIMES` | Allows to assign runtimes to a project in the namespace | | `ASSIGN_ROLE_ABILITIES` | Allows to change the abilities of a namespace role | | `ASSIGN_ROLE_PROJECTS` | Allows to change the assigned projects of a namespace role | -| `CREATE_FLOWS` | Allows to create flows in the namespace | +| `CREATE_FLOWS` | Allows to create flows in a namespace project | | `CREATE_NAMESPACE_LICENSE` | Allows to create a license for the namespace | | `CREATE_NAMESPACE_PROJECT` | Allows to create a project in the namespace | | `CREATE_NAMESPACE_ROLE` | Allows the creation of roles in a namespace | | `CREATE_RUNTIME` | Allows to create a runtime globally or for the namespace | -| `DELETE_FLOWS` | Allows to delete flows in the namespace | +| `DELETE_FLOWS` | Allows to delete flows in a namespace project | | `DELETE_MEMBER` | Allows to remove members of a namespace | | `DELETE_NAMESPACE_LICENSE` | Allows to delete the license of the namespace | | `DELETE_NAMESPACE_PROJECT` | Allows to delete the project of the namespace | @@ -27,7 +27,6 @@ Represents abilities that can be granted to roles in namespaces. | `READ_NAMESPACE_LICENSE` | Allows to read the license of the namespace | | `READ_NAMESPACE_PROJECT` | Allows to read the project of the namespace | | `ROTATE_RUNTIME_TOKEN` | Allows to regenerate a runtime token | -| `UPDATE_FLOWS` | Allows to update flows in the namespace | | `UPDATE_NAMESPACE_PROJECT` | Allows to update the project of the namespace | | `UPDATE_NAMESPACE_ROLE` | Allows to update the namespace role | | `UPDATE_ORGANIZATION` | Allows to update the organization | From 1ec9b35ac5270bdda2510e8190583609e4106697 Mon Sep 17 00:00:00 2001 From: Dario Pranjic Date: Fri, 6 Jun 2025 10:43:48 +0200 Subject: [PATCH 54/54] Recompile structure.sql --- db/structure.sql | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index d971982a..f13e4163 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -171,7 +171,6 @@ CREATE TABLE data_types ( removed_at timestamp with time zone, generic_keys text[] DEFAULT '{}'::text[] NOT NULL, parent_type_id bigint, - flows_id bigint, CONSTRAINT check_3a7198812e CHECK ((char_length(identifier) <= 50)) ); @@ -186,7 +185,7 @@ ALTER SEQUENCE data_types_id_seq OWNED BY data_types.id; CREATE TABLE flow_settings ( id bigint NOT NULL, - flow_id bigint, + flow_id bigint NOT NULL, flow_setting_id text NOT NULL, object jsonb NOT NULL, created_at timestamp with time zone NOT NULL, @@ -301,7 +300,7 @@ ALTER SEQUENCE function_generic_mappers_id_seq OWNED BY function_generic_mappers CREATE TABLE generic_combination_strategies ( id bigint NOT NULL, - type integer, + type integer NOT NULL, generic_mapper_id bigint, function_generic_mapper_id bigint, created_at timestamp with time zone NOT NULL, @@ -1132,8 +1131,6 @@ CREATE INDEX index_data_type_identifiers_on_runtime_id ON data_type_identifiers CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btree (data_type_id); -CREATE INDEX index_data_types_on_flows_id ON data_types USING btree (flows_id); - CREATE INDEX index_data_types_on_parent_type_id ON data_types USING btree (parent_type_id); CREATE UNIQUE INDEX index_data_types_on_runtime_id_and_identifier ON data_types USING btree (runtime_id, identifier); @@ -1282,7 +1279,7 @@ ALTER TABLE ONLY flow_types ADD CONSTRAINT fk_rails_01f5c9215f FOREIGN KEY (input_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_01f5d14544 FOREIGN KEY (generic_mapper_id) REFERENCES generic_mappers(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_01f5d14544 FOREIGN KEY (generic_mapper_id) REFERENCES generic_mappers(id) ON DELETE CASCADE; ALTER TABLE ONLY runtime_function_definition_error_types ADD CONSTRAINT fk_rails_070c5bfcf0 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; @@ -1335,9 +1332,6 @@ ALTER TABLE ONLY function_generic_mappers ALTER TABLE ONLY function_definitions ADD CONSTRAINT fk_rails_48f4bbe3b6 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; -ALTER TABLE ONLY data_types - ADD CONSTRAINT fk_rails_490081f598 FOREIGN KEY (flows_id) REFERENCES flows(id) ON DELETE RESTRICT; - ALTER TABLE ONLY runtime_function_definitions ADD CONSTRAINT fk_rails_5161ff47e6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; @@ -1354,7 +1348,7 @@ ALTER TABLE ONLY namespace_role_project_assignments ADD CONSTRAINT fk_rails_623f8a5b72 FOREIGN KEY (role_id) REFERENCES namespace_roles(id); ALTER TABLE ONLY node_parameters - ADD CONSTRAINT fk_rails_646d4dbfbc FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_646d4dbfbc FOREIGN KEY (reference_value_id) REFERENCES reference_values(id) ON DELETE CASCADE; ALTER TABLE ONLY data_type_identifiers ADD CONSTRAINT fk_rails_65151da1fb FOREIGN KEY (generic_type_id) REFERENCES generic_types(id) ON DELETE CASCADE; @@ -1447,7 +1441,7 @@ ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_ca0a397b6f FOREIGN KEY (data_type_id) REFERENCES data_type_identifiers(id) ON DELETE RESTRICT; ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_d08626f743 FOREIGN KEY (function_generic_mapper_id) REFERENCES function_generic_mappers(id) ON DELETE RESTRICT; + ADD CONSTRAINT fk_rails_d08626f743 FOREIGN KEY (function_generic_mapper_id) REFERENCES function_generic_mappers(id) ON DELETE CASCADE; ALTER TABLE ONLY namespace_projects ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;