diff --git a/Gemfile b/Gemfile index cbabc137..eb6283f9 100644 --- a/Gemfile +++ b/Gemfile @@ -79,7 +79,7 @@ gem 'good_job', '~> 4.0' gem 'rotp' gem 'grpc', '~> 1.67' -gem 'tucana', '0.0.53' +gem 'tucana', '0.0.58' gem 'code0-identities', '~> 0.0.3' diff --git a/Gemfile.lock b/Gemfile.lock index ccac940f..67cb0581 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -377,7 +377,7 @@ GEM thor (1.4.0) timeout (0.6.0) tsort (0.2.0) - tucana (0.0.53) + tucana (0.0.58) grpc (~> 1.64) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -431,7 +431,7 @@ DEPENDENCIES simplecov (~> 0.22.0) simplecov-cobertura (~> 3.0) test-prof (~> 1.0) - tucana (= 0.0.53) + tucana (= 0.0.58) tzinfo-data RUBY VERSION diff --git a/app/finders/data_type_identifiers_finder.rb b/app/finders/data_type_identifiers_finder.rb deleted file mode 100644 index 8d25e87b..00000000 --- a/app/finders/data_type_identifiers_finder.rb +++ /dev/null @@ -1,152 +0,0 @@ -# frozen_string_literal: true - -class DataTypeIdentifiersFinder < ApplicationFinder - def execute - data_type_identifiers = base_scope - data_type_identifiers = by_data_type(data_type_identifiers) - data_type_identifiers = by_runtime(data_type_identifiers) - data_type_identifiers = by_related_to_function_definition(data_type_identifiers) - - data_type_identifiers = add_related_identifiers(data_type_identifiers) - - super(data_type_identifiers) - end - - private - - def base_scope - DataTypeIdentifier.all - end - - def by_runtime(data_type_identifiers) - return data_type_identifiers unless params[:runtime] - - data_type_identifiers.where(runtime: params[:runtime]) - end - - def by_related_to_function_definition(data_type_identifiers) - return data_type_identifiers unless params[:function_definition] - - data_type_identifiers - .where(id: params[:function_definition].return_type_id) - .or(data_type_identifiers.where(id: params[:function_definition].parameter_definitions.pluck(:data_type_id))) - end - - def by_data_type(data_type_identifiers) - return data_type_identifiers unless params[:data_type] - - dt = DataType.arel_table - dtr = DataTypeRule.arel_table - dti = DataTypeIdentifier.arel_table - - data_type_id_condition = case params[:data_type] - when DataType - dt[:id].eq(params[:data_type].id) - else - dt[:id].in(params[:data_type].pluck(:id)) - end - - DataTypeIdentifier - .from(dt) - .joins( - dt - .join(dtr, Arel::Nodes::InnerJoin) - .on(dt[:id].eq(dtr[:data_type_id])) - .join(dti, Arel::Nodes::InnerJoin) - .on(data_type_identifier_by_data_type_condition) - .join_sources - ) - .where(data_type_id_condition) - .select(dti[Arel.star]) - end - - def add_related_identifiers(data_type_identifiers) - return data_type_identifiers unless params[:expand_recursively] - - tree = Arel::Table.new(:data_type_identifier_tree) - - DataTypeIdentifier - .with_recursive(data_type_identifier_tree: [ - data_type_identifiers, - add_related_identifiers_recursive_case - ]) - .from(tree) - .select(tree[Arel.star]) - .distinct - .order(:id) - end - - def add_related_identifiers_recursive_case - tree = Arel::Table.new(:data_type_identifier_tree) - dti = DataTypeIdentifier.arel_table - dt = DataType.arel_table - dtr = DataTypeRule.arel_table - gt = GenericType.arel_table - gm = GenericMapper.arel_table - - mapper_condition = dti[:generic_mapper_id].eq(gm[:id]) - - join_condition = Arel::Nodes::Grouping.new(data_type_identifier_by_data_type_condition.or(mapper_condition)) - - DataTypeIdentifier - .from(tree) - .joins( - tree.join(dt, Arel::Nodes::OuterJoin) - .on(tree[:data_type_id].eq(dt[:id])) - .join(dtr, Arel::Nodes::OuterJoin) - .on(dt[:id].eq(dtr[:data_type_id])) - .join(gt, Arel::Nodes::OuterJoin) - .on(tree[:generic_type_id].eq(gt[:id])) - .join(gm, Arel::Nodes::OuterJoin) - .on(gt[:id].eq(gm[:generic_type_id])) - .join(dti, Arel::Nodes::InnerJoin) - .on(join_condition) - .join_sources - ) - .select(dti[Arel.star]) - end - - def data_type_identifier_by_data_type_condition - dt = DataType.arel_table - dti = DataTypeIdentifier.arel_table - dtr = DataTypeRule.arel_table - - basic_rule_condition = dti[:id].eq( - Arel::Nodes::NamedFunction.new( - 'CAST', - [ - Arel::Nodes::As.new( - Arel::Nodes::InfixOperation.new('->', dtr[:config], Arel::Nodes.build_quoted('data_type_identifier_id')), - Arel::Nodes::SqlLiteral.new('BIGINT') - ) - ] - ) - ) - - input_types_any_condition = Arel::Nodes::NamedFunction.new( - 'ANY', - [ - Arel::Nodes::NamedFunction.new( - 'ARRAY', [ - Arel::Nodes::SqlLiteral.new( - <<~SQL.squish - SELECT elem::BIGINT - FROM JSONB_ARRAY_ELEMENTS_TEXT( - JSONB_PATH_QUERY_ARRAY(data_type_rules.config, '$.input_types[*].data_type_identifier_id') - ) elem - SQL - ) - ] - ) - ] - ) - - input_types_rule_condition = dti[:id].eq(input_types_any_condition) - - parent_type_condition = dt[:parent_type_id].eq(dti[:id]) - - Arel::Nodes::Grouping.new( - basic_rule_condition.or(input_types_rule_condition).or(parent_type_condition) - ) - end -end diff --git a/app/finders/data_types_finder.rb b/app/finders/data_types_finder.rb new file mode 100644 index 00000000..608cdc7d --- /dev/null +++ b/app/finders/data_types_finder.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +class DataTypesFinder < ApplicationFinder + def execute + data_types = base_scope + data_types = by_data_type(data_types) + data_types = by_runtime_function_definition(data_types) + data_types = by_flow_type_setting(data_types) + data_types = by_flow_type(data_types) + data_types = by_flow(data_types) + + data_types = add_related_data_types(data_types) + + super(data_types) + end + + private + + def base_scope + DataType.all + end + + def by_data_type(data_types) + return data_types unless params[:data_type] + + data_types.where(id: params[:data_type].referenced_data_types.pluck(:id)) + end + + def by_runtime_function_definition(data_types) + return data_types unless params[:runtime_function_definition] + + data_types.where(id: params[:runtime_function_definition].referenced_data_types.pluck(:id)) + end + + def by_flow_type_setting(data_types) + return data_types unless params[:flow_type_setting] + + data_types.where(id: params[:flow_type_setting].referenced_data_types.pluck(:id)) + end + + def by_flow_type(data_types) + return data_types unless params[:flow_type] + + data_types.where(id: params[:flow_type].referenced_data_types.pluck(:id)) + end + + def by_flow(data_types) + return data_types unless params[:flow] + + data_types.where(id: params[:flow].referenced_data_types.pluck(:id)) + end + + def add_related_data_types(data_types) + return data_types unless params[:expand_recursively] + + tree = Arel::Table.new(:data_type_tree) + + DataType + .with_recursive(data_type_tree: [ + data_types, + add_related_data_types_recursive_case + ]) + .from(tree) + .select(tree[Arel.star]) + .distinct + .order(:id) + end + + def add_related_data_types_recursive_case + tree = Arel::Table.new(:data_type_tree) + dt = DataType.arel_table + link = DataTypeDataTypeLink.arel_table + + DataType + .from(tree) + .joins( + tree.join(link, Arel::Nodes::InnerJoin) + .on(tree[:id].eq(link[:data_type_id])) + .join(dt, Arel::Nodes::InnerJoin) + .on(link[:referenced_data_type_id].eq(dt[:id])) + .join_sources + ) + .select(dt[Arel.star]) + end +end diff --git a/app/graphql/types/data_type_identifier_type.rb b/app/graphql/types/data_type_identifier_type.rb deleted file mode 100644 index d1056f6c..00000000 --- a/app/graphql/types/data_type_identifier_type.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Types - class DataTypeIdentifierType < Types::BaseObject - description 'Represents a data type identifier.' - - field :data_type, Types::DataTypeType, null: true, description: 'The data type of the data type identifier.' - - # rubocop:disable GraphQL/ExtractType -- generic_key and generic_type don't have anything in common - field :generic_key, String, null: true, description: 'The generic key of the data type identifier.' - field :generic_type, Types::GenericTypeType, null: true, - description: 'The generic type of the data type identifier.' - # rubocop:enable GraphQL/ExtractType - - id_field DataTypeIdentifier - timestamps - end -end diff --git a/app/graphql/types/data_type_rule_type.rb b/app/graphql/types/data_type_rule_type.rb index a02f18e8..20c8e20e 100644 --- a/app/graphql/types/data_type_rule_type.rb +++ b/app/graphql/types/data_type_rule_type.rb @@ -19,11 +19,7 @@ def variant end def config - if object.variant_parent_type? - object - else - object.config.merge(variant: object.variant) - end + 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 index a1b5a8f0..e79f1897 100644 --- a/app/graphql/types/data_type_rules/config_type.rb +++ b/app/graphql/types/data_type_rules/config_type.rb @@ -5,27 +5,14 @@ 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, InputTypesConfigType, ReturnTypeConfigType, ParentTypeConfigType + possible_types NumberRangeConfigType, RegexConfigType def self.resolve_type(object, _context) case object[:variant].to_sym - when :contains_key - Types::DataTypeRules::ContainsKeyConfigType - when :contains_type - Types::DataTypeRules::ContainsTypeConfigType when :number_range Types::DataTypeRules::NumberRangeConfigType - when :item_of_collection - Types::DataTypeRules::ItemOfCollectionConfigType when :regex Types::DataTypeRules::RegexConfigType - when :input_types - Types::DataTypeRules::InputTypesConfigType - when :return_type - Types::DataTypeRules::ReturnTypeConfigType - when :parent_type - Types::DataTypeRules::ParentTypeConfigType else raise GraphQL::ExecutionError, "Unknown data type rule variant: #{object[:variant]}" 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 deleted file mode 100644 index 5efa8733..00000000 --- a/app/graphql/types/data_type_rules/contains_key_config_type.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Types - module DataTypeRules - class ContainsKeyConfigType < Types::BaseObject - description 'Represents a rule that can be applied to a data type.' - - # rubocop:disable GraphQL/ExtractType -- one of the fields is types-only - field :data_type_identifier, Types::DataTypeIdentifierType, - null: false, - description: 'types-only field', - visibility_profile: :types - - field :data_type_identifier_id, Types::GlobalIdType[::DataTypeIdentifier], - null: false, description: 'ID of the identifier of the data type this rule belongs to' - # rubocop:enable GraphQL/ExtractType - - field :key, String, null: false, description: 'The key of the rule' - - def data_type_identifier_id - DataTypeIdentifier.new(id: object['data_type_identifier_id']).to_global_id - end - 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 deleted file mode 100644 index 0a464a3f..00000000 --- a/app/graphql/types/data_type_rules/contains_type_config_type.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module Types - module DataTypeRules - class ContainsTypeConfigType < Types::BaseObject - description 'Represents a rule that can be applied to a data type.' - - # rubocop:disable GraphQL/ExtractType -- one of the fields is types-only - field :data_type_identifier, Types::DataTypeIdentifierType, - null: false, - description: 'types-only field', - visibility_profile: :types - - field :data_type_identifier_id, Types::GlobalIdType[::DataTypeIdentifier], - null: false, description: 'ID of the identifier of the data type this rule belongs to' - # rubocop:enable GraphQL/ExtractType - - def data_type_identifier_id - DataTypeIdentifier.new(id: object['data_type_identifier_id']).to_global_id - end - end - end -end diff --git a/app/graphql/types/data_type_rules/input_type_config_type.rb b/app/graphql/types/data_type_rules/input_type_config_type.rb deleted file mode 100644 index 61501255..00000000 --- a/app/graphql/types/data_type_rules/input_type_config_type.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -module Types - module DataTypeRules - class InputTypeConfigType < Types::BaseObject - description 'Represents a subtype of input type configuration for a input data type.' - - # rubocop:disable GraphQL/ExtractType -- one of the fields is types-only - field :data_type_identifier, Types::DataTypeIdentifierType, - null: false, - description: 'types-only field', - visibility_profile: :types - - field :data_type_identifier_id, Types::GlobalIdType[::DataTypeIdentifier], - null: false, description: 'ID of the identifier of the data type this input type belongs to' - # rubocop:enable GraphQL/ExtractType - - field :input_identifier, String, - null: false, description: 'The input identifier that this configuration applies to' - - def data_type_identifier_id - DataTypeIdentifier.new(id: object['data_type_identifier_id']).to_global_id - end - 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 deleted file mode 100644 index f5246eb7..00000000 --- a/app/graphql/types/data_type_rules/input_types_config_type.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module Types - module DataTypeRules - class InputTypesConfigType < Types::BaseObject - description 'Represents a rule that can be applied to a data type.' - - field :input_types, [Types::DataTypeRules::InputTypeConfigType], - null: false, description: 'The input types that can be used in this data type rule' - 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 deleted file mode 100644 index 523f5937..00000000 --- a/app/graphql/types/data_type_rules/item_of_collection_config_type.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module Types - module DataTypeRules - class ItemOfCollectionConfigType < Types::BaseObject - description 'Represents a rule that can be applied to a data type.' - - 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/parent_type_config_type.rb b/app/graphql/types/data_type_rules/parent_type_config_type.rb deleted file mode 100644 index 89b76587..00000000 --- a/app/graphql/types/data_type_rules/parent_type_config_type.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module Types - module DataTypeRules - class ParentTypeConfigType < Types::BaseObject - description 'Represents a rule that can be applied to a data type.' - - # rubocop:disable GraphQL/ExtractType -- one of the fields is types-only - field :data_type_identifier, Types::DataTypeIdentifierType, - null: false, - description: 'types-only field', - visibility_profile: :types - - field :data_type_identifier_id, Types::GlobalIdType[::DataTypeIdentifier], - null: false, description: 'ID of the data type identifier for the parent type.' - # rubocop:enable GraphQL/ExtractType - - def data_type_identifier_id - object.data_type.parent_type.to_global_id - end - end - end -end diff --git a/app/graphql/types/data_type_rules/return_type_config_type.rb b/app/graphql/types/data_type_rules/return_type_config_type.rb deleted file mode 100644 index 88641711..00000000 --- a/app/graphql/types/data_type_rules/return_type_config_type.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module Types - module DataTypeRules - class ReturnTypeConfigType < Types::BaseObject - description 'Represents a rule that can be applied to a data type.' - - # rubocop:disable GraphQL/ExtractType -- one of the fields is types-only - field :data_type_identifier, Types::DataTypeIdentifierType, - null: false, - description: 'types-only field', - visibility_profile: :types - - field :data_type_identifier_id, Types::GlobalIdType[::DataTypeIdentifier], - null: false, description: 'The data type identifier for the return type.' - # rubocop:enable GraphQL/ExtractType - - def data_type_identifier_id - DataTypeIdentifier.new(id: object['data_type_identifier_id']).to_global_id - end - end - end -end diff --git a/app/graphql/types/data_type_rules/variant_enum.rb b/app/graphql/types/data_type_rules/variant_enum.rb index 243d5a2c..bc54983c 100644 --- a/app/graphql/types/data_type_rules/variant_enum.rb +++ b/app/graphql/types/data_type_rules/variant_enum.rb @@ -5,22 +5,10 @@ module DataTypeRules class VariantEnum < 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_TYPES, 'The rule checks if the data type matches a specific input type.', - value: :input_types - value :RETURN_TYPE, 'The rule checks if the data type matches a specific return type.', - value: :return_type - value :PARENT_TYPE, 'The rule checks if the data type is a child of a specific parent type.', - value: :parent_type end end end diff --git a/app/graphql/types/data_type_type.rb b/app/graphql/types/data_type_type.rb index 4d59656a..63a58d5f 100644 --- a/app/graphql/types/data_type_type.rb +++ b/app/graphql/types/data_type_type.rb @@ -9,7 +9,7 @@ class DataTypeType < Types::BaseObject field :aliases, [Types::TranslationType], null: true, description: 'Name of the function' field :display_messages, [Types::TranslationType], null: true, description: 'Display message of the function' - field :generic_keys, [String], null: true, description: 'Generic keys of the datatype' + field :generic_keys, [String], null: false, description: 'The generic keys of the datatype' field :identifier, String, null: false, description: 'The identifier scoped to the namespace' field :name, [Types::TranslationType], method: :names, null: false, description: 'Names of the flow type setting' @@ -17,18 +17,17 @@ class DataTypeType < Types::BaseObject description: 'Rules of the datatype' field :runtime, Types::RuntimeType, null: true, description: 'The runtime where this datatype belongs to' - field :variant, Types::DataTypeVariantEnum, null: false, - description: 'The type of the datatype' + field :type, String, null: false, description: 'The type of the datatype' - field :data_type_identifiers, Types::DataTypeIdentifierType.connection_type, + field :referenced_data_types, Types::DataTypeType.connection_type, null: false, - description: 'The data type identifiers that are referenced in this data type and its rules' + description: 'The data types that are referenced in this data type' id_field DataType timestamps - def data_type_identifiers - DataTypeIdentifiersFinder.new({ data_type: object, expand_recursively: true }).execute + def referenced_data_types + DataTypesFinder.new({ data_type: object, expand_recursively: true }).execute end end end diff --git a/app/graphql/types/data_type_variant_enum.rb b/app/graphql/types/data_type_variant_enum.rb deleted file mode 100644 index 4b9c3cf8..00000000 --- a/app/graphql/types/data_type_variant_enum.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Types - class DataTypeVariantEnum < BaseEnum - description 'Represent all available types of a datatype' - - value :PRIMITIVE, 'Represents a primitive datatype', value: 'primitive' - value :TYPE, 'Represents a type', value: 'type' - 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 :ERROR, 'Represents a error', value: 'error' - value :NODE, 'Represents a node', value: 'node' - end -end diff --git a/app/graphql/types/errors/detailed_error_type.rb b/app/graphql/types/errors/detailed_error_type.rb index 2fe9916c..191041f6 100644 --- a/app/graphql/types/errors/detailed_error_type.rb +++ b/app/graphql/types/errors/detailed_error_type.rb @@ -7,13 +7,10 @@ class DetailedErrorType < Types::BaseUnion graphql_name 'DetailedError' # rubocop:enable GraphQL/GraphqlName description 'Represents a detailed error with either a message or an active model error' - possible_types Types::Errors::ActiveModelErrorType, Types::Errors::MessageErrorType, - Types::Errors::FlowValidationErrorType + possible_types Types::Errors::ActiveModelErrorType, Types::Errors::MessageErrorType def self.resolve_type(object, _ctx) case object - when Namespaces::Projects::Flows::Validation::ValidationResult - Types::Errors::FlowValidationErrorType when ActiveModel::Error Types::Errors::ActiveModelErrorType when Hash diff --git a/app/graphql/types/errors/flow_validation_error_code_enum.rb b/app/graphql/types/errors/flow_validation_error_code_enum.rb deleted file mode 100644 index a3f5bfcf..00000000 --- a/app/graphql/types/errors/flow_validation_error_code_enum.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Types - module Errors - # rubocop:disable GraphQL/GraphqlName -- we don't want the module prefix - class FlowValidationErrorCodeEnum < Types::BaseEnum - graphql_name 'FlowValidationErrorCodeEnum' - # rubocop:enable GraphQL/GraphqlName - description 'Represents the available error responses' - - ::Namespaces::Projects::Flows::Validation::FlowValidationErrorCode.error_codes.each do |error_code, details| - value error_code.upcase, details[:description], - value: error_code, - deprecation_reason: details.fetch(:deprecation_reason, nil) - end - end - end -end diff --git a/app/graphql/types/errors/flow_validation_error_type.rb b/app/graphql/types/errors/flow_validation_error_type.rb deleted file mode 100644 index 0c99d508..00000000 --- a/app/graphql/types/errors/flow_validation_error_type.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module Types - module Errors - # rubocop:disable GraphQL/GraphqlName -- we don't want the module prefix - class FlowValidationErrorType < Types::BaseObject - graphql_name 'FlowValidationError' - # rubocop:enable GraphQL/GraphqlName - description 'Represents a flow validation error' - - field :details, Errors::ActiveModelErrorType, null: true, - description: 'Additional details about the validation error' - field :error_code, Errors::FlowValidationErrorCodeEnum, - null: false, description: 'The code representing the validation error type' - field :severity, Errors::FlowValidationSeverityEnum, null: false, - description: 'The severity of the validation error' - end - end -end diff --git a/app/graphql/types/errors/flow_validation_severity_enum.rb b/app/graphql/types/errors/flow_validation_severity_enum.rb deleted file mode 100644 index a04969ae..00000000 --- a/app/graphql/types/errors/flow_validation_severity_enum.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Types - module Errors - # rubocop:disable GraphQL/GraphqlName -- we don't want the module prefix - class FlowValidationSeverityEnum < Types::BaseEnum - graphql_name 'FlowValidationSeverityEnum' - # rubocop:enable GraphQL/GraphqlName - description 'Represents the severity of a flow validation error' - - value 'WARNING', 'A non-blocking validation warning', value: :warning - value 'ERROR', 'A blocking validation error', value: :error - value 'WEAK', 'A weak validation issue that may not need to be addressed', value: :weak - value 'TYPO', 'A minor typographical issue can also be blocking', value: :typo - end - end -end diff --git a/app/graphql/types/flow_type.rb b/app/graphql/types/flow_type.rb index 577367dd..bb4322ab 100644 --- a/app/graphql/types/flow_type.rb +++ b/app/graphql/types/flow_type.rb @@ -8,13 +8,13 @@ class FlowType < Types::BaseObject field :name, String, null: false, description: 'Name of the flow' - field :input_type, Types::DataTypeType, + field :input_type, String, null: true, description: 'The input data type of the flow' field :project, Types::NamespaceProjectType, null: false, description: 'The project the flow belongs to' - field :return_type, Types::DataTypeType, + field :return_type, String, null: true, description: 'The return data type of the flow' field :settings, Types::FlowSettingType.connection_type, @@ -33,6 +33,10 @@ class FlowType < Types::BaseObject description: 'Nodes of the flow', method: :node_functions + field :referenced_data_types, Types::DataTypeType.connection_type, + null: false, + description: 'The data types that are referenced in this flow' + expose_abilities %i[ delete_flow ] @@ -43,5 +47,9 @@ class FlowType < Types::BaseObject def starting_node_id object.starting_node&.to_global_id end + + def referenced_data_types + DataTypesFinder.new({ flow: object, expand_recursively: true }).execute + end end end diff --git a/app/graphql/types/flow_type_setting_type.rb b/app/graphql/types/flow_type_setting_type.rb index 8ac8a6ba..04639912 100644 --- a/app/graphql/types/flow_type_setting_type.rb +++ b/app/graphql/types/flow_type_setting_type.rb @@ -6,15 +6,23 @@ class FlowTypeSettingType < Types::BaseObject authorize :read_flow_type_setting - field :data_type, Types::DataTypeType, null: true, description: 'Data type of the flow type setting' field :descriptions, [Types::TranslationType], null: false, description: 'Descriptions of the flow type setting' field :flow_type, Types::FlowTypeType, null: true, description: 'Flow type of the flow type setting' field :identifier, String, null: false, description: 'Identifier of the flow type setting' field :names, [Types::TranslationType], null: false, description: 'Names of the flow type setting' + field :type, String, null: false, description: 'Type of the flow type setting' field :unique, Boolean, null: false, description: 'Unique status of the flow type setting' + field :referenced_data_types, Types::DataTypeType.connection_type, + null: false, + description: 'The data types that are referenced in this flow type setting' + id_field FlowTypeSetting timestamps + + def referenced_data_types + DataTypesFinder.new({ flow_type_setting: object, expand_recursively: true }).execute + end end end diff --git a/app/graphql/types/flow_type_type.rb b/app/graphql/types/flow_type_type.rb index 4a2a4530..c1859a59 100644 --- a/app/graphql/types/flow_type_type.rb +++ b/app/graphql/types/flow_type_type.rb @@ -15,13 +15,21 @@ class FlowTypeType < Types::BaseObject field :flow_type_settings, [Types::FlowTypeSettingType], null: false, description: 'Flow type settings of the flow type' field :identifier, String, null: false, description: 'Identifier of the flow type' - field :input_type, Types::DataTypeType, null: true, description: 'Input type of the flow type' + field :input_type, String, null: true, description: 'Input type of the flow type' field :names, [Types::TranslationType], null: true, description: 'Names of the flow type' - field :return_type, Types::DataTypeType, null: true, description: 'Return type of the flow type' + field :return_type, String, null: true, description: 'Return type of the flow type' field :runtime, Types::RuntimeType, null: false, description: 'Runtime of the flow type' + field :referenced_data_types, Types::DataTypeType.connection_type, + null: false, + description: 'The data types that are referenced in this flow type' + id_field ::FlowType timestamps + + def referenced_data_types + DataTypesFinder.new({ flow_type: object, expand_recursively: true }).execute + end end end diff --git a/app/graphql/types/function_definition_type.rb b/app/graphql/types/function_definition_type.rb index ae117c5c..94c3f23f 100644 --- a/app/graphql/types/function_definition_type.rb +++ b/app/graphql/types/function_definition_type.rb @@ -8,8 +8,6 @@ class FunctionDefinitionType < Types::BaseObject field :identifier, String, null: false, description: 'Identifier of the function' - field :return_type, Types::DataTypeIdentifierType, null: true, description: 'Return type of the function' - field :parameter_definitions, Types::ParameterDefinitionType.connection_type, null: true, description: 'Parameters of the function' @@ -30,14 +28,14 @@ class FunctionDefinitionType < Types::BaseObject field :runtime_function_definition, Types::RuntimeFunctionDefinitionType, null: true, description: 'Runtime function definition' - field :generic_keys, [String], null: true, description: 'Generic keys of the function' + field :signature, String, null: false, description: 'Signature of the function' field :throws_error, Boolean, null: false, description: 'Indicates if the function can throw an error' - field :data_type_identifiers, Types::DataTypeIdentifierType.connection_type, + field :referenced_data_types, Types::DataTypeType.connection_type, null: false, - description: 'All data type identifiers used within this Node Function' + description: 'All data types referenced within this function definition' id_field FunctionDefinition timestamps @@ -46,16 +44,19 @@ def identifier object.runtime_function_definition&.runtime_name end - def generic_keys - object.runtime_function_definition&.generic_keys + def signature + object.runtime_function_definition&.signature end def throws_error object.runtime_function_definition&.throws_error end - def data_type_identifiers - DataTypeIdentifiersFinder.new({ function_definition: object, expand_recursively: true }).execute + def referenced_data_types + return [] unless object.runtime_function_definition + + DataTypesFinder.new({ runtime_function_definition: object.runtime_function_definition, + expand_recursively: true }).execute end end end diff --git a/app/graphql/types/generic_combination_strategy_type.rb b/app/graphql/types/generic_combination_strategy_type.rb deleted file mode 100644 index 0815d7b8..00000000 --- a/app/graphql/types/generic_combination_strategy_type.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Types - class GenericCombinationStrategyType < Types::BaseObject - description 'Represents a combination strategy with AND/OR logic used by a generic mapper.' - - field :type, Types::GenericCombinationStrategyTypeEnum, null: false, - description: "The combination type ('AND' or 'OR')." - - field :generic_mapper, Types::GenericMapperType, null: true, - description: 'The associated generic mapper, if any.' - - id_field GenericCombinationStrategy - timestamps - end -end diff --git a/app/graphql/types/generic_combination_strategy_type_enum.rb b/app/graphql/types/generic_combination_strategy_type_enum.rb deleted file mode 100644 index ee4f56a7..00000000 --- a/app/graphql/types/generic_combination_strategy_type_enum.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Types - class GenericCombinationStrategyTypeEnum < Types::BaseEnum - description 'The available combination strategy types.' - - value 'AND', value: 'and', description: 'Represents a logical AND combination.' - value 'OR', value: 'or', description: 'Represents a logical OR combination.' - end -end diff --git a/app/graphql/types/generic_mapper_type.rb b/app/graphql/types/generic_mapper_type.rb deleted file mode 100644 index 6aaca9e1..00000000 --- a/app/graphql/types/generic_mapper_type.rb +++ /dev/null @@ -1,35 +0,0 @@ -# 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_datatype - - # rubocop:disable GraphQL/ExtractType -- one of the fields is types-only - field :source_data_type_identifier_ids, [Types::GlobalIdType[::DataTypeIdentifier]], - null: false, - description: 'The source data type identifier.' - - field :source_data_type_identifiers, [Types::DataTypeIdentifierType], - null: false, - description: 'types-only field', - visibility_profile: :types - # rubocop:enable GraphQL/ExtractType - - field :target, String, - null: false, - description: 'The target key for the generic value.' - - field :generic_combination_strategies, [Types::GenericCombinationStrategyType], - null: true, - description: 'Combination strategies associated with this generic mapper.' - - id_field GenericMapper - timestamps - - def source_data_type_identifier_ids - object.sources.map(&:to_global_id) - end - end -end diff --git a/app/graphql/types/generic_type_type.rb b/app/graphql/types/generic_type_type.rb deleted file mode 100644 index af098193..00000000 --- a/app/graphql/types/generic_type_type.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Types - class GenericTypeType < Types::BaseObject - description 'Represents a generic type that can be used in various contexts.' - - authorize :read_datatype - - 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.' - - id_field GenericType - 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 deleted file mode 100644 index 337e2957..00000000 --- a/app/graphql/types/input/data_type_identifier_input_type.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Types - module Input - class DataTypeIdentifierInputType < Types::BaseInputObject - description 'Input type for data type identifier' - - 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, - description: 'Generic type information' - 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 deleted file mode 100644 index 09043fb0..00000000 --- a/app/graphql/types/input/generic_mapper_input_type.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Types - module Input - class GenericMapperInputType < Types::BaseInputObject - description 'Input type for generic mappers' - - argument :source_data_type_identifiers, [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' - 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 deleted file mode 100644 index c58d8255..00000000 --- a/app/graphql/types/input/generic_type_input_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Types - 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.' - end - end -end diff --git a/app/graphql/types/parameter_definition_type.rb b/app/graphql/types/parameter_definition_type.rb index 1812ccaa..41544618 100644 --- a/app/graphql/types/parameter_definition_type.rb +++ b/app/graphql/types/parameter_definition_type.rb @@ -8,11 +8,6 @@ class ParameterDefinitionType < Types::BaseObject field :identifier, String, null: false, description: 'Identifier of the parameter' - field :data_type_identifier, Types::DataTypeIdentifierType, - null: true, - description: 'Data type of the parameter', - method: :data_type - field :descriptions, [Types::TranslationType], null: true, description: 'Description of the parameter' field :names, [Types::TranslationType], null: true, description: 'Name of the parameter' @@ -20,6 +15,9 @@ class ParameterDefinitionType < Types::BaseObject null: true, description: 'Documentation of the parameter' + field :runtime_parameter_definition, Types::RuntimeParameterDefinitionType, + null: true, description: 'Runtime parameter definition' + id_field ParameterDefinition timestamps diff --git a/app/graphql/types/runtime_function_definition_type.rb b/app/graphql/types/runtime_function_definition_type.rb index 3183963b..125a55e8 100644 --- a/app/graphql/types/runtime_function_definition_type.rb +++ b/app/graphql/types/runtime_function_definition_type.rb @@ -22,7 +22,19 @@ class RuntimeFunctionDefinitionType < Types::BaseObject description: 'Identifier of the runtime function definition', method: :runtime_name + field :signature, String, + null: false, + description: 'Signature of the runtime function definition' + + field :referenced_data_types, Types::DataTypeType.connection_type, + null: false, + description: 'The data types that are referenced in this runtime function definition' + id_field RuntimeFunctionDefinition timestamps + + def referenced_data_types + DataTypesFinder.new({ runtime_function_definition: object, expand_recursively: true }).execute + end end end diff --git a/app/models/data_type.rb b/app/models/data_type.rb index 08262887..68c33d9b 100644 --- a/app/models/data_type.rb +++ b/app/models/data_type.rb @@ -1,43 +1,24 @@ # frozen_string_literal: true class DataType < ApplicationRecord - VARIANTS = { - primitive: 1, - type: 2, - object: 3, - datatype: 4, - array: 5, - error: 6, - node: 7, - }.with_indifferent_access + self.inheritance_column = :_type_disabled - enum :variant, VARIANTS, prefix: :variant - - belongs_to :parent_type, class_name: 'DataTypeIdentifier', inverse_of: :child_types, optional: true belongs_to :runtime, inverse_of: :data_types 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 - has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner + has_many :data_type_data_type_links, inverse_of: :data_type + has_many :referenced_data_types, through: :data_type_data_type_links, source: :referenced_data_type has_many :display_messages, -> { by_purpose(:display_message) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :aliases, -> { by_purpose(:alias) }, class_name: 'Translation', as: :owner, inverse_of: :owner - validates :variant, presence: true, - inclusion: { - in: VARIANTS.keys.map(&:to_s), - } + validates :type, presence: true, length: { maximum: 2000 } validate :validate_version - validate :generic_keys_length - - validate :validate_parent, if: :parent_type_changed? - def validate_version return errors.add(:version, :blank) if version.blank? @@ -49,21 +30,4 @@ def validate_version def parsed_version Gem::Version.new(version) end - - def validate_parent - current_type = self - until current_type.parent_type&.data_type.nil? - current_type = current_type.parent_type&.data_type || current_type.parent_type&.generic_type&.data_type - - if current_type == self - errors.add(:parent_type, :recursion) - break - 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/data_type_data_type_link.rb b/app/models/data_type_data_type_link.rb new file mode 100644 index 00000000..3344f601 --- /dev/null +++ b/app/models/data_type_data_type_link.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class DataTypeDataTypeLink < ApplicationRecord + belongs_to :data_type, inverse_of: :data_type_data_type_links + belongs_to :referenced_data_type, class_name: 'DataType' +end diff --git a/app/models/data_type_identifier.rb b/app/models/data_type_identifier.rb deleted file mode 100644 index aa9c792c..00000000 --- a/app/models/data_type_identifier.rb +++ /dev/null @@ -1,29 +0,0 @@ -# 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_identifiers - belongs_to :runtime, inverse_of: :data_type_identifiers - belongs_to :generic_mapper, class_name: 'GenericMapper', optional: true, inverse_of: :sources - - has_many :child_types, class_name: 'DataType', inverse_of: :parent_type - - 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 - 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') - end -end diff --git a/app/models/data_type_rule.rb b/app/models/data_type_rule.rb index c0a0bcd0..9b7acb20 100644 --- a/app/models/data_type_rule.rb +++ b/app/models/data_type_rule.rb @@ -2,45 +2,19 @@ class DataTypeRule < ApplicationRecord VARIANTS = { - contains_key: 1, - contains_type: 2, - item_of_collection: 3, - number_range: 4, - regex: 5, - return_type: 6, - input_types: 7, - parent_type: 8, + number_range: 1, + regex: 2, }.with_indifferent_access enum :variant, VARIANTS, prefix: :variant belongs_to :data_type, inverse_of: :rules - has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner - validates :variant, presence: true, inclusion: { in: VARIANTS.keys.map(&:to_s), } - validates :config, if: :variant_contains_key?, - 'sagittarius/validators/json_schema': { - filename: 'data_types/ContainsKeyRuleConfig', - hash_conversion: true, - } - - validates :config, if: :variant_contains_type?, - 'sagittarius/validators/json_schema': { - filename: 'data_types/ContainsTypeRuleConfig', - hash_conversion: true, - } - - validates :config, if: :variant_item_of_collection?, - 'sagittarius/validators/json_schema': { - filename: 'data_types/ItemOfCollectionRuleConfig', - hash_conversion: true, - } - validates :config, if: :variant_number_range?, 'sagittarius/validators/json_schema': { filename: 'data_types/NumberRangeRuleConfig', @@ -52,22 +26,4 @@ class DataTypeRule < ApplicationRecord filename: 'data_types/RegexRuleConfig', 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_types?, - 'sagittarius/validators/json_schema': { - filename: 'data_types/InputTypesRuleConfig', - hash_conversion: true, - } - - validate :no_parent_type_config, if: :variant_parent_type? - - def no_parent_type_config - errors.add(:config, :not_blank) if config.present? - end end diff --git a/app/models/flow.rb b/app/models/flow.rb index 89f748d2..f9c1c299 100644 --- a/app/models/flow.rb +++ b/app/models/flow.rb @@ -3,17 +3,21 @@ class Flow < ApplicationRecord belongs_to :project, class_name: 'NamespaceProject' belongs_to :flow_type - 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', optional: true has_many :flow_settings, class_name: 'FlowSetting', inverse_of: :flow has_many :node_functions, class_name: 'NodeFunction', inverse_of: :flow + has_many :flow_data_type_links, inverse_of: :flow + has_many :referenced_data_types, through: :flow_data_type_links, source: :referenced_data_type + validates :name, presence: true, allow_blank: false, uniqueness: { case_sensitive: false, scope: :project_id } + validates :input_type, length: { maximum: 2000 }, allow_nil: true + validates :return_type, length: { maximum: 2000 }, allow_nil: true + def to_grpc Tucana::Shared::ValidationFlow.new( flow_id: id, @@ -21,8 +25,8 @@ def to_grpc project_slug: project.slug, type: flow_type.identifier, data_types: [], # TODO: when data types are creatable - input_type: Tucana::Shared::DataTypeIdentifier.from_hash({ data_type_identifier: input_type&.identifier }), - return_type: Tucana::Shared::DataTypeIdentifier.from_hash({ data_type_identifier: return_type&.identifier }), + input_type: input_type, + return_type: return_type, settings: flow_settings.map(&:to_grpc), starting_node_id: starting_node.id, node_functions: node_functions.map(&:to_grpc) diff --git a/app/models/flow_data_type_link.rb b/app/models/flow_data_type_link.rb new file mode 100644 index 00000000..b0599479 --- /dev/null +++ b/app/models/flow_data_type_link.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class FlowDataTypeLink < ApplicationRecord + belongs_to :flow, inverse_of: :flow_data_type_links + belongs_to :referenced_data_type, class_name: 'DataType' +end diff --git a/app/models/flow_type.rb b/app/models/flow_type.rb index bfb630e3..701b5c19 100644 --- a/app/models/flow_type.rb +++ b/app/models/flow_type.rb @@ -3,14 +3,17 @@ class FlowType < ApplicationRecord belongs_to :runtime, inverse_of: :flow_types - belongs_to :input_type, class_name: 'DataType', optional: true - belongs_to :return_type, class_name: 'DataType', optional: true - has_many :flow_type_settings, inverse_of: :flow_type + has_many :flow_type_data_type_links, inverse_of: :flow_type + has_many :referenced_data_types, through: :flow_type_data_type_links, source: :referenced_data_type + validates :identifier, presence: true, uniqueness: { scope: :runtime_id } validates :editable, inclusion: { in: [true, false] } + validates :input_type, length: { maximum: 2000 }, allow_nil: true + validates :return_type, length: { maximum: 2000 }, allow_nil: 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 has_many :documentations, -> { by_purpose(:documentation) }, class_name: 'Translation', as: :owner, inverse_of: :owner diff --git a/app/models/flow_type_data_type_link.rb b/app/models/flow_type_data_type_link.rb new file mode 100644 index 00000000..01eb7287 --- /dev/null +++ b/app/models/flow_type_data_type_link.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class FlowTypeDataTypeLink < ApplicationRecord + belongs_to :flow_type, inverse_of: :flow_type_data_type_links + belongs_to :referenced_data_type, class_name: 'DataType' +end diff --git a/app/models/flow_type_setting.rb b/app/models/flow_type_setting.rb index 2c925d0e..135d5bad 100644 --- a/app/models/flow_type_setting.rb +++ b/app/models/flow_type_setting.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class FlowTypeSetting < ApplicationRecord + self.inheritance_column = :_type_disabled + belongs_to :flow_type, inverse_of: :flow_type_settings UNIQUENESS_SCOPE = { @@ -11,7 +13,8 @@ class FlowTypeSetting < ApplicationRecord enum :unique, UNIQUENESS_SCOPE, prefix: :unique - belongs_to :data_type + has_many :flow_type_setting_data_type_links, inverse_of: :flow_type_setting + has_many :referenced_data_types, through: :flow_type_setting_data_type_links, source: :referenced_data_type validates :identifier, presence: true, uniqueness: { scope: :flow_type_id } validates :unique, presence: true, @@ -20,6 +23,8 @@ class FlowTypeSetting < ApplicationRecord }, exclusion: [0, :unknown, 'unknown'] + validates :type, presence: true, length: { maximum: 2000 } + 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 end diff --git a/app/models/flow_type_setting_data_type_link.rb b/app/models/flow_type_setting_data_type_link.rb new file mode 100644 index 00000000..ceefd434 --- /dev/null +++ b/app/models/flow_type_setting_data_type_link.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class FlowTypeSettingDataTypeLink < ApplicationRecord + belongs_to :flow_type_setting, inverse_of: :flow_type_setting_data_type_links + belongs_to :referenced_data_type, class_name: 'DataType' +end diff --git a/app/models/function_definition.rb b/app/models/function_definition.rb index 15ec160b..ecd0a9aa 100644 --- a/app/models/function_definition.rb +++ b/app/models/function_definition.rb @@ -2,7 +2,6 @@ class FunctionDefinition < ApplicationRecord belongs_to :runtime_function_definition - belongs_to :return_type, class_name: 'DataTypeIdentifier', optional: true has_many :node_functions, inverse_of: :function_definition has_many :parameter_definitions, inverse_of: :function_definition diff --git a/app/models/generic_combination_strategy.rb b/app/models/generic_combination_strategy.rb deleted file mode 100644 index 8e9edd50..00000000 --- a/app/models/generic_combination_strategy.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -class GenericCombinationStrategy < ApplicationRecord - TYPES = { - and: 1, - or: 2, - }.with_indifferent_access - - belongs_to :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/generic_mapper.rb b/app/models/generic_mapper.rb deleted file mode 100644 index b6d77252..00000000 --- a/app/models/generic_mapper.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -class GenericMapper < ApplicationRecord - belongs_to :generic_type, inverse_of: :generic_mappers, optional: true - 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 - - has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner - - validates :target, presence: true - - 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 deleted file mode 100644 index 5d1a98c9..00000000 --- a/app/models/generic_type.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -class GenericType < ApplicationRecord - belongs_to :owner, polymorphic: true - belongs_to :data_type, class_name: 'DataType', 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_grpc - Tucana::Sagittarius::GenericType.new( - data_type_identifier: data_type_identifier&.data_type&.identifier, - generic_mappers: generic_mappers.map(&:to_grpc) - ) - end -end diff --git a/app/models/json_schemas/DataTypeIdentifier.json b/app/models/json_schemas/DataTypeIdentifier.json deleted file mode 100644 index bb03a759..00000000 --- a/app/models/json_schemas/DataTypeIdentifier.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$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/GenericMapper.json b/app/models/json_schemas/GenericMapper.json deleted file mode 100644 index 814cc13c..00000000 --- a/app/models/json_schemas/GenericMapper.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "$id": "https://example.com/schemas/GenericMapper.json", - "title": "GenericMapper", - "type": "object", - "required": [ - "source", - "target", - "generic_combinations" - ], - "properties": { - "source": { - "type": "array", - "items": { - "$ref": "DataTypeIdentifier.json" - } - }, - "target": { - "type": "string" - }, - "generic_combinations": { - "type": "array", - "items": { - "enum": [ - "AND", - "OR" - ] - } - } - } -} diff --git a/app/models/json_schemas/GenericType.json b/app/models/json_schemas/GenericType.json deleted file mode 100644 index b710e3d2..00000000 --- a/app/models/json_schemas/GenericType.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$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/ContainsKeyRuleConfig.json b/app/models/json_schemas/data_types/ContainsKeyRuleConfig.json deleted file mode 100644 index 1e60b7ec..00000000 --- a/app/models/json_schemas/data_types/ContainsKeyRuleConfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "$id": "https://example.com/schemas/DataTypeContainsKeyRuleConfig.json", - "title": "DataTypeContainsKeyRuleConfig", - "type": "object", - "required": [ - "key", - "data_type_identifier", - "data_type_identifier_id" - ], - "properties": { - "key": { - "type": "string" - }, - "data_type_identifier": { - "$ref": "../DataTypeIdentifier.json" - }, - "data_type_identifier_id": { - "type": "integer" - } - } -} diff --git a/app/models/json_schemas/data_types/ContainsTypeRuleConfig.json b/app/models/json_schemas/data_types/ContainsTypeRuleConfig.json deleted file mode 100644 index 51b14263..00000000 --- a/app/models/json_schemas/data_types/ContainsTypeRuleConfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "DataTypeContainsTypeRuleConfig", - "type": "object", - "required": [ - "data_type_identifier", - "data_type_identifier_id" - ], - "properties": { - "data_type_identifier": { - "$ref": "../DataTypeIdentifier.json" - }, - "data_type_identifier_id": { - "type": "integer" - } - } -} diff --git a/app/models/json_schemas/data_types/InputTypesRuleConfig.json b/app/models/json_schemas/data_types/InputTypesRuleConfig.json deleted file mode 100644 index 43d70111..00000000 --- a/app/models/json_schemas/data_types/InputTypesRuleConfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$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", - "data_type_identifier_id", - "input_identifier" - ], - "properties": { - "data_type_identifier": { - "$ref": "../DataTypeIdentifier.json" - }, - "data_type_identifier_id": { - "type": "integer" - }, - "input_identifier": { - "type": "string" - } - } - } - } - } -} diff --git a/app/models/json_schemas/data_types/ItemOfCollectionRuleConfig.json b/app/models/json_schemas/data_types/ItemOfCollectionRuleConfig.json deleted file mode 100644 index 3a5ff9c3..00000000 --- a/app/models/json_schemas/data_types/ItemOfCollectionRuleConfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$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/ReturnTypeRuleConfig.json b/app/models/json_schemas/data_types/ReturnTypeRuleConfig.json deleted file mode 100644 index 43f6d817..00000000 --- a/app/models/json_schemas/data_types/ReturnTypeRuleConfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "$id": "https://example.com/schemas/ReturnTypeRuleConfig.json", - "title": "ReturnTypeRuleConfig", - "type": "object", - "required": [ - "data_type_identifier", - "data_type_identifier_id" - ], - "properties": { - "data_type_identifier": { - "$ref": "../DataTypeIdentifier.json" - }, - "data_type_identifier_id": { - "type": "integer" - } - } -} diff --git a/app/models/parameter_definition.rb b/app/models/parameter_definition.rb index ff543fc3..9accb373 100644 --- a/app/models/parameter_definition.rb +++ b/app/models/parameter_definition.rb @@ -2,7 +2,6 @@ class ParameterDefinition < ApplicationRecord belongs_to :runtime_parameter_definition - belongs_to :data_type, class_name: 'DataTypeIdentifier' belongs_to :function_definition, inverse_of: :parameter_definitions diff --git a/app/models/runtime.rb b/app/models/runtime.rb index cbfd7468..23dc5498 100644 --- a/app/models/runtime.rb +++ b/app/models/runtime.rb @@ -15,8 +15,6 @@ class Runtime < ApplicationRecord has_many :primary_projects, class_name: 'NamespaceProject', inverse_of: :primary_runtime has_many :data_types, inverse_of: :runtime - has_many :data_type_identifiers, inverse_of: :runtime - has_many :generic_mappers, inverse_of: :runtime has_many :runtime_function_definitions, inverse_of: :runtime has_many :function_definitions, through: :runtime_function_definitions diff --git a/app/models/runtime_function_definition.rb b/app/models/runtime_function_definition.rb index 2a830504..ecb6b8f9 100644 --- a/app/models/runtime_function_definition.rb +++ b/app/models/runtime_function_definition.rb @@ -1,12 +1,14 @@ # frozen_string_literal: true class RuntimeFunctionDefinition < ApplicationRecord - 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 :runtime_function_definition_data_type_links, inverse_of: :runtime_function_definition + has_many :referenced_data_types, through: :runtime_function_definition_data_type_links, source: :referenced_data_type + 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 @@ -18,13 +20,11 @@ class RuntimeFunctionDefinition < ApplicationRecord class_name: 'Translation', as: :owner, inverse_of: :owner has_many :aliases, -> { by_purpose(:alias) }, class_name: 'Translation', as: :owner, inverse_of: :owner - has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner - validates :runtime_name, presence: true, length: { minimum: 3, maximum: 50 }, uniqueness: { case_sensitive: false, scope: :runtime_id } - validate :generic_keys_length + validates :signature, presence: true, length: { maximum: 500 } validate :validate_version @@ -39,9 +39,4 @@ def validate_version def parsed_version Gem::Version.new(version) 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_data_type_link.rb b/app/models/runtime_function_definition_data_type_link.rb new file mode 100644 index 00000000..0b6bdaf7 --- /dev/null +++ b/app/models/runtime_function_definition_data_type_link.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class RuntimeFunctionDefinitionDataTypeLink < ApplicationRecord + belongs_to :runtime_function_definition, inverse_of: :runtime_function_definition_data_type_links + belongs_to :referenced_data_type, class_name: 'DataType' +end diff --git a/app/models/runtime_parameter_definition.rb b/app/models/runtime_parameter_definition.rb index d3638264..a6a5724c 100644 --- a/app/models/runtime_parameter_definition.rb +++ b/app/models/runtime_parameter_definition.rb @@ -2,7 +2,6 @@ class RuntimeParameterDefinition < ApplicationRecord belongs_to :runtime_function_definition, inverse_of: :parameters - 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 @@ -10,8 +9,6 @@ class RuntimeParameterDefinition < ApplicationRecord has_many :parameter_definitions, inverse_of: :runtime_parameter_definition - has_many :owned_generic_types, class_name: 'GenericType', inverse_of: :owner - validates :runtime_name, length: { minimum: 3, maximum: 50 }, presence: true, uniqueness: { case_sensitive: false, scope: :runtime_function_definition_id } end diff --git a/app/policies/generic_mapper_policy.rb b/app/policies/generic_mapper_policy.rb deleted file mode 100644 index a0a3f862..00000000 --- a/app/policies/generic_mapper_policy.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -class GenericMapperPolicy < BasePolicy - delegate { subject.generic_type } -end diff --git a/app/policies/generic_type_policy.rb b/app/policies/generic_type_policy.rb deleted file mode 100644 index ab376072..00000000 --- a/app/policies/generic_type_policy.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -class GenericTypePolicy < BasePolicy - delegate { subject.data_type } -end diff --git a/app/services/error_code.rb b/app/services/error_code.rb index 7fdae4e6..1f2812b6 100644 --- a/app/services/error_code.rb +++ b/app/services/error_code.rb @@ -51,7 +51,6 @@ def self.error_codes invalid_organization: { description: 'The organization is invalid because of active model errors' }, invalid_namespace_role: { description: 'The namespace role is invalid because of active model errors' }, invalid_namespace_project: { description: 'The namespace project is invalid because of active model errors' }, - flow_validation_failed: { description: 'The flow validation has failed' }, failed_to_reset_password: { description: 'Failed to reset the user password' }, loading_identity_failed: { description: 'Failed to load user identity from external provider' }, invalid_flow_setting: { description: 'The flow setting is invalid because of active model errors' }, @@ -77,14 +76,11 @@ def self.error_codes referenced_value_not_found: { description: 'A referenced value could not be found' }, invalid_runtime_parameter_definition: { description: 'The runtime parameter definition is invalid' }, invalid_runtime_function_definition: { description: 'The runtime function definition is invalid' }, - no_generic_type_for_identifier: { description: 'No generic type could be found for the given identifier' }, - no_datatype_identifier_for_generic_key: { description: 'No data type identifier could be found for the given generic key' }, - invalid_generic_mapper: { description: 'The generic mapper is invalid because of active model errors' }, invalid_data_type: { description: 'The data type is invalid because of active model errors' }, - data_type_identifier_not_found: { description: 'The data type identifier with the given identifier was not found' }, data_type_not_found: { description: 'The data type with the given identifier was not found' }, invalid_flow_type: { description: 'The flow type is invalid because of active model errors' }, no_data_type_for_identifier: { description: 'No data type could be found for the given identifier' }, + invalid_data_type_link: { description: 'The data type link is invalid because of active model errors' }, node_not_found: { description: 'The node with this id does not exist' }, function_value_not_found: { description: 'The id for the function value node does not exist' }, invalid_node_parameter: { description: 'The node parameter is invalid' }, diff --git a/app/services/namespaces/projects/flows/create_service.rb b/app/services/namespaces/projects/flows/create_service.rb index 20b2e0be..2d907f57 100644 --- a/app/services/namespaces/projects/flows/create_service.rb +++ b/app/services/namespaces/projects/flows/create_service.rb @@ -5,7 +5,6 @@ module Projects module Flows class CreateService include Sagittarius::Database::Transactional - include FlowServiceHelper attr_reader :current_authentication, :namespace_project, :flow_input diff --git a/app/services/namespaces/projects/flows/flow_service_helper.rb b/app/services/namespaces/projects/flows/flow_service_helper.rb deleted file mode 100644 index ef7cd91b..00000000 --- a/app/services/namespaces/projects/flows/flow_service_helper.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -module Namespaces - module Projects - module Flows - module FlowServiceHelper - def get_data_type_identifier(runtime, identifier, t) - if identifier.generic_key.present? - return DataTypeIdentifier.find_or_create_by(runtime: runtime, - generic_key: identifier.generic_key) - end - - if identifier.generic_type.present? - data_type = runtime.data_types.find_by( - id: identifier.generic_type.data_type_id.model_id - ) - - if data_type.nil? - t.rollback_and_return! ServiceResponse.error( - message: 'Data type not found', - error_code: :data_type_not_found - ) - end - - mappers = identifier.generic_type.mappers.map do |mapper| - GenericMapper.find_or_create_by( - runtime: runtime, - generic_mapper_id: mapper.generic_mapper_id, - source: mapper.source, - target: mapper.target - ) - end - generic_type = GenericType.joins(:generic_mappers).find_or_create_by(data_type: data_type, - generic_mappers: mappers) - return DataTypeIdentifier.find_or_create_by(runtime: runtime, generic_type: generic_type) - end - - data_type = runtime.data_types.find_by(id: identifier.data_type_id.model_id) - - if data_type.nil? - t.rollback_and_return! ServiceResponse.error( - message: 'Data type not found', - error_code: :data_type_not_found - ) - end - - DataTypeIdentifier.find_or_create_by(runtime: runtime, data_type: data_type) - 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 index 141a9495..b64163af 100644 --- a/app/services/namespaces/projects/flows/update_service.rb +++ b/app/services/namespaces/projects/flows/update_service.rb @@ -5,7 +5,6 @@ module Projects module Flows class UpdateService include Sagittarius::Database::Transactional - include FlowServiceHelper attr_reader :current_authentication, :flow, :flow_input @@ -42,8 +41,6 @@ def update_flow(t) ) end - validate_flow(t) - UpdateRuntimesForProjectJob.perform_later(flow.project.id) end @@ -250,18 +247,6 @@ def update_node_parameters(t, current_node, current_node_input, all_nodes) current_node.node_parameters = db_parameters end - def validate_flow(t) - res = Validation::ValidationService.new(current_authentication, flow).execute - - return unless res.error? - - t.rollback_and_return! ServiceResponse.error( - message: 'Flow validation failed', - error_code: res.payload[:error_code], - details: res.payload[:details] - ) - end - def create_audit_event AuditService.audit( :flow_updated, diff --git a/app/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service.rb b/app/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service.rb deleted file mode 100644 index c3447b76..00000000 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -module Namespaces - module Projects - module Flows - module Validation - module DataType - class DataTypeIdentifierValidationService - include Code0::ZeroTrack::Loggable - include Sagittarius::Database::Transactional - - attr_reader :current_authentication, :flow, :node, :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 - errors = [] - logger.debug(message: 'Validating data_type_identifier', data_type_identifier: data_type_identifier.id, - flow_id: flow.id) - - 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) - errors << ValidationResult.error( - :data_type_identifier_model_invalid, - details: data_type_identifier.errors, - location: data_type_identifier - ) - 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) - errors << ValidationResult.error( - :data_type_identifier_runtime_mismatch, - location: data_type_identifier - ) - end - - if data_type_identifier.generic_key.present? - runtime_function_definition = node.function_definition.runtime_function_definition - unless runtime_function_definition.generic_keys.include?(data_type_identifier.generic_key) - errors << ValidationResult.error( - :data_type_identifier_generic_key_not_found, - location: data_type_identifier - ) - end - elsif data_type_identifier.generic_type.present? - errors += ::NodeFunction::GenericTypeValidationService.new( - current_authentication, - flow, - data_type_identifier.generic_type - ).execute - elsif data_type_identifier.data_type.present? - errors += DataTypeValidationService.new( - current_authentication, - flow, - data_type_identifier.data_type - ).execute - end - - errors - end - end - end - end - 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 deleted file mode 100644 index f409f3cf..00000000 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service.rb +++ /dev/null @@ -1,46 +0,0 @@ -# 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 - errors = [] - logger.debug(message: 'Validating data type rule', rule_id: rule.id) - - transactional 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) - errors << ValidationResult.error( - :data_type_rule_model_invalid, - details: rule.errors, - location: rule - ) - end - end - errors - 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 deleted file mode 100644 index 4589e8eb..00000000 --- a/app/services/namespaces/projects/flows/validation/data_type/data_type_validation_service.rb +++ /dev/null @@ -1,79 +0,0 @@ -# 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 - errors = [] - - logger.debug("Validating data type: #{data_type.id} for flow: #{flow.id}") - - 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) - errors << ValidationResult.error( - :data_type_model_invalid, - details: data_type.errors, - location: data_type - ) - 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) - errors << ValidationResult.error( - :data_type_runtime_mismatch, - location: data_type - ) - end - - data_type.parent_type&.tap do |parent_type| - logger.debug("Validating parent type: #{parent_type.id} for data type: #{data_type.id}") - errors += DataTypeIdentifierValidationService.new( - current_authentication, - flow, - nil, - parent_type - ).execute - end - - data_type.rules.each do |rule| - logger.debug("Validating data type rule: #{rule.id} for data type: #{data_type.id}") - errors += 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) - errors - 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 deleted file mode 100644 index 4a0ccf8e..00000000 --- a/app/services/namespaces/projects/flows/validation/flow_setting_validation_service.rb +++ /dev/null @@ -1,37 +0,0 @@ -# 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 - errors = [] - logger.debug("Validating setting: #{setting.inspect} for flow: #{flow.id}") - - if setting.invalid? - logger.debug("Invalid setting: #{setting.errors.full_messages.join(', ')}") - errors << ValidationResult.error( - :flow_setting_model_invalid, - details: setting.errors, - location: setting - ) - end - errors - 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 deleted file mode 100644 index 30e26935..00000000 --- a/app/services/namespaces/projects/flows/validation/flow_type_validation_service.rb +++ /dev/null @@ -1,35 +0,0 @@ -# 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 - errors = [] - logger.debug("Validating flow_type: #{flow_type.inspect} for flow: #{flow.id}") - - if flow_type.runtime != flow.project.primary_runtime - errors << ValidationResult.error( - :flow_type_runtime_mismatch, - location: flow_type - ) - end - errors - end - end - end - end - end -end diff --git a/app/services/namespaces/projects/flows/validation/flow_validation_error_code.rb b/app/services/namespaces/projects/flows/validation/flow_validation_error_code.rb deleted file mode 100644 index d6745ebf..00000000 --- a/app/services/namespaces/projects/flows/validation/flow_validation_error_code.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -module Namespaces - module Projects - module Flows - module Validation - class FlowValidationErrorCode - InvalidErrorCode = Class.new(StandardError) - - def self.validate_error_code!(error_code) - return unless error_code.is_a?(Symbol) - return if Rails.env.production? - - raise InvalidErrorCode, error_code unless error_codes.include?(error_code) - end - - # rubocop:disable Layout/LineLength -- We want each description on a single line for readability - def self.error_codes - { - data_type_identifier_runtime_mismatch: { description: 'The data type identifier runtime does not match the flow type runtime.' }, - data_type_identifier_generic_key_not_found: { description: 'The generic key for the data type identifier was not found.' }, - data_type_rule_model_invalid: { description: 'The data type rule model is invalid.' }, - data_type_runtime_mismatch: { description: 'The data type runtime does not match the flow type runtime.' }, - flow_setting_model_invalid: { description: 'The flow setting model is invalid.' }, - flow_type_runtime_mismatch: { description: 'The flow type runtime does not match the project primary runtime.' }, - no_primary_runtime: { description: 'The project does not have a primary runtime set.' }, - node_function_runtime_mismatch: { description: 'The node function runtime does not match the project primary runtime.' }, - } - end - # rubocop:enable Layout/LineLength - 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 deleted file mode 100644 index 53dc529b..00000000 --- a/app/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service.rb +++ /dev/null @@ -1,55 +0,0 @@ -# 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 - errors = [] - logger.debug("Validating generic mapper: #{generic_mapper.inspect} for flow: #{flow.id}") - - target = generic_mapper.target - - # Validate the target the identifier gets validated later - runtime_function_definition = parameter.node_function.function_definition.runtime_function_definition - unless runtime_function_definition.generic_keys.include?(target) - errors << ValidationResult.error( - :generic_key_not_found, - location: generic_mapper - ) - end - - generic_mapper.generic_combination_strategies.each do |_strategy| - # https://github.com/code0-tech/sagittarius/issues/509 - end - - generic_mapper.sources.each do |source| - errors += Namespaces::Projects::Flows::Validation::DataType::DataTypeIdentifierValidationService.new( - current_authentication, - flow, - parameter.node_function, - source - ).execute - end - errors - 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 deleted file mode 100644 index 4796ea60..00000000 --- a/app/services/namespaces/projects/flows/validation/node_function/generic_type_validation_service.rb +++ /dev/null @@ -1,44 +0,0 @@ -# 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 - errors = [] - errors += ::DataType::DataTypeValidationService.new( - current_authentication, - flow, - generic_type.data_type - ).execute - - generic_type.generic_mappers.each do |generic_mapper| - errors += ::DataType::GenericMapperValidationService.new( - current_authentication, - flow, - parameter, - generic_mapper - ).execute - end - errors - 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 deleted file mode 100644 index cfa74716..00000000 --- a/app/services/namespaces/projects/flows/validation/node_function/node_function_parameter_validation_service.rb +++ /dev/null @@ -1,71 +0,0 @@ -# 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 - errors = [] - logger.debug("Validating node parameter: #{parameter.id} for flow: #{flow.id}") - - if parameter.invalid? - logger.debug(message: 'Node parameter validation failed', - errors: parameter.errors.full_messages) - errors << ValidationResult.error( - :node_parameter_model_invalid, - details: parameter.errors, - location: parameter - ) - end - runtime_parameter_definition = parameter.parameter_definition.runtime_parameter_definition - if runtime_parameter_definition.runtime_function_definition.runtime != flow.project.primary_runtime - errors << ValidationResult.error( - :node_parameter_runtime_mismatch, - location: parameter - ) - end - - if parameter.literal_value.present? - return errors # TODO: ig - end - - if parameter.reference_value.present? - errors += ReferenceValueValidationService.new( - current_authentication, - flow, - parameter.node_function, - parameter.reference_value - ).execute - return errors - end - if parameter.function_value.present? - logger.debug("Validating function value: - #{parameter.function_value.id} for node parameter: #{parameter.id}") - errors += NodeFunctionValidationService.new( - current_authentication, - flow, - parameter.function_value - ).execute - end - errors - 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 deleted file mode 100644 index a4ef66da..00000000 --- a/app/services/namespaces/projects/flows/validation/node_function/node_function_validation_service.rb +++ /dev/null @@ -1,80 +0,0 @@ -# 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 - errors = [] - logger.debug("Validating node function: #{node_function.id} for flow: #{flow.id}") - - if node_function.invalid? - logger.debug(message: 'Node function validation failed', - errors: node_function.errors.full_messages) - errors << ValidationResult.error( - :node_function_model_invalid, - details: node_function.errors, - location: node_function - ) - end - if node_function.function_definition.runtime_function_definition.runtime != flow.project.primary_runtime - errors << ValidationResult.error( - :node_function_runtime_mismatch, - location: node_function - ) - end - - node_function.function_definition.runtime_function_definition.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 - errors << ValidationResult.error( - :node_function_runtime_mismatch, - location: node_function - ) - end - end - - node_function.node_parameters.each do |parameter| - logger.debug("Validating node parameter: #{parameter.id} for function: #{node_function.id}") - parameter_function_definition = parameter.parameter_definition.function_definition - - if parameter_function_definition != node_function.function_definition - logger.debug(message: 'Node parameter does not match its function', - node_function: node_function.id, - runtime_parameter: parameter.runtime_parameter.id, - flow: flow.id) - errors << ValidationResult.error( - :parameter_mismatch, - location: parameter - ) - end - - errors += NodeFunctionParameterValidationService.new( - current_authentication, - flow, - node_function, - parameter - ).execute - end - errors - 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 deleted file mode 100644 index 0fc80609..00000000 --- a/app/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service.rb +++ /dev/null @@ -1,40 +0,0 @@ -# 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, :reference_value - - def initialize(current_authentication, flow, node, reference_value) - @current_authentication = current_authentication - @flow = flow - @node = node - @reference_value = reference_value - end - - def execute - errors = [] - - unless reference_value.valid? - errors << ValidationResult.error( - :reference_value_invalid, - details: reference_value.errors, - location: reference_value - ) - end - - # https://github.com/code0-tech/sagittarius/issues/508 Validate the usage and datatypes - errors - end - end - end - end - end - end -end diff --git a/app/services/namespaces/projects/flows/validation/validation_result.rb b/app/services/namespaces/projects/flows/validation/validation_result.rb deleted file mode 100644 index aa725846..00000000 --- a/app/services/namespaces/projects/flows/validation/validation_result.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -module Namespaces - module Projects - module Flows - module Validation - class ValidationResult - def self.typo(error_code, location:, details: nil) - new(severity: :typo, error_code: error_code, details: details, location: location) - end - - def self.error(error_code, location:, details: nil) - new(severity: :error, error_code: error_code, details: details, location: location) - end - - def self.weak(error_code, location:, details: nil) - new(severity: :weak, error_code: error_code, details: details, location: location) - end - - def self.warning(error_code, location:, details: nil) - new(severity: :warning, error_code: error_code, details: details, location: location) - end - - attr_reader :severity, :error_code, :details, :location - - def initialize(severity:, error_code:, details:, location:) - FlowValidationErrorCode.validate_error_code!(error_code) - - @severity = severity - @error_code = error_code - @details = details - @location = location - 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 deleted file mode 100644 index 76ad8270..00000000 --- a/app/services/namespaces/projects/flows/validation/validation_service.rb +++ /dev/null @@ -1,92 +0,0 @@ -# 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 - errors = [] - - primary_runtime = flow.project.primary_runtime - if primary_runtime.nil? - errors << ValidationResult.error( - :no_primary_runtime, - location: flow.project - ) - end - - # --- - # Input Type Validation - # --- - if flow.input_type.present? - errors += Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService.new( - current_authentication, - flow, - flow.input_type - ).execute - end - - # --- - # Return Type Validation - # --- - if flow.return_type.present? - errors += Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService.new( - current_authentication, - flow, - flow.return_type - ).execute - end - - # --- - # Setting - # --- - flow.flow_settings.each do |setting| - errors += Namespaces::Projects::Flows::Validation::FlowSettingValidationService.new( - current_authentication, - flow, - setting - ).execute - end - - # --- - # All nodes - # --- - flow.node_functions.each do |node_function| - errors += Namespaces::Projects::Flows::Validation::NodeFunction::NodeFunctionValidationService.new( - current_authentication, - flow, - node_function - ).execute - end - - # --- - # Flow Type - # --- - errors += FlowTypeValidationService.new( - current_authentication, - flow, - flow.flow_type - ).execute - - if errors.any? - return ServiceResponse.error(message: 'Flow validation failed', error_code: :flow_validation_failed, - details: errors) - end - - ServiceResponse.success(message: 'Validation service executed successfully', payload: flow) - end - end - end - end - end -end diff --git a/app/services/runtimes/grpc/data_type_helper.rb b/app/services/runtimes/grpc/data_type_helper.rb index 5e6733a6..c287261b 100644 --- a/app/services/runtimes/grpc/data_type_helper.rb +++ b/app/services/runtimes/grpc/data_type_helper.rb @@ -3,92 +3,9 @@ module Runtimes module Grpc module DataTypeHelper - # This method updates or creates GenericMappers based on the provided gRPC GenericMapper objects - # within the current runtime. - # @param generic_mappers [Array] An array of gRPC GenericMapper objects. - def update_mappers(generic_mappers, generic_type, t) - raise 'Including class must define current_runtime' unless respond_to?(:current_runtime) - - generic_mappers.to_a.map do |generic_mapper| - mapper = GenericMapper.find_by(runtime: current_runtime, generic_type: generic_type) - - mapper = GenericMapper.new(runtime: current_runtime, generic_type: generic_type) if mapper.nil? - - mapper.target = generic_mapper.target - mapper.sources = generic_mapper.source.map do |source| - find_data_type_identifier(source, mapper, t, additional_dti_kwargs: { generic_mapper: mapper }) - end - - if mapper.nil? || !mapper.save - t.rollback_and_return! ServiceResponse.error( - message: "Could not find or create generic mapper (#{generic_mapper})", - error_code: :invalid_generic_mapper - ) - end - mapper - end - end - - # This method finds or creates a DataTypeIdentifier based on the provided identifier within the current runtime. - # @param identifier [Tucana::Sagittarius::DataTypeIdentifier] The gRPC DataTypeIdentifier object. - def find_data_type_identifier(identifier, owner, t, additional_dti_kwargs: {}) - if identifier.data_type_identifier.present? - return create_data_type_identifier( - t, - **additional_dti_kwargs, - data_type_id: find_data_type(identifier.data_type_identifier, t).id - ) - end - - if identifier.generic_type.present? - data_type = find_data_type(identifier.generic_type.data_type_identifier, t) - - generic_type = owner.owned_generic_types.find_or_initialize_by(data_type: data_type) - - if generic_type.nil? - t.rollback_and_return! ServiceResponse.error( - message: "Could not find generic type with identifier #{identifier.generic_type.data_type_identifier}", - error_code: :no_generic_type_for_identifier - ) - end - - generic_type.generic_mappers = update_mappers(identifier.generic_type.generic_mappers, generic_type, t) - - return create_data_type_identifier(t, **additional_dti_kwargs, generic_type_id: generic_type.id) - end - - if identifier.generic_key.present? - return create_data_type_identifier(t, **additional_dti_kwargs, generic_key: identifier.generic_key) - end - - raise ArgumentError, "Invalid identifier: #{identifier.inspect}" - end - - # This method creates or finds a DataTypeIdentifier based on the provided keyword arguments - # within the current runtime. - # It also handles transaction rollback in case of failure. - # @param t [ActiveRecord::Connection] The database transaction context. - # @param kwargs [Hash] The attributes to find or create the DataTypeIdentifier. - def create_data_type_identifier(t, **kwargs) - raise 'Including class must define current_runtime' unless respond_to?(:current_runtime) - - 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}", - error_code: :no_datatype_identifier_for_generic_key - ) - end - - data_type_identifier - end - # This method finds a DataType by its identifier within the current runtime. # @param identifier [String] The identifier of the DataType to find. + # @param t [Object] The transaction context. def find_data_type(identifier, t) raise 'Including class must define current_runtime' unless respond_to?(:current_runtime) @@ -101,6 +18,31 @@ def find_data_type(identifier, t) data_type end + + # This method links data types referenced by identifiers to the given record. + # It re-uses existing link records and only creates new ones when needed. + # @param record [ApplicationRecord] The record to link data types to. + # @param identifiers [Array] The list of data type identifiers to link. + # @param t [Object] The transaction context. + def link_data_types(record, identifiers, t) + link_relation = record.public_send(:"#{record.class.name.underscore}_data_type_links") + db_links = link_relation.first(identifiers.length) + + identifiers.each_with_index do |identifier, index| + db_links[index] ||= link_relation.build + db_links[index].referenced_data_type = find_data_type(identifier, t) + + next if db_links[index].save + + t.rollback_and_return! ServiceResponse.error( + message: "Could not link data type #{identifier}", + error_code: :invalid_data_type_link, + details: db_links[index].errors + ) + end + + link_relation.where.not(id: db_links.map(&:id)).delete_all + end end end end diff --git a/app/services/runtimes/grpc/data_types/update_service.rb b/app/services/runtimes/grpc/data_types/update_service.rb index bd697e77..df66d387 100644 --- a/app/services/runtimes/grpc/data_types/update_service.rb +++ b/app/services/runtimes/grpc/data_types/update_service.rb @@ -45,145 +45,52 @@ def execute protected 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| contains_sortable_rule?(dt) } + sorted_types = data_types.reject { |dt| dt.linked_data_type_identifiers.any? } 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| - find_sortable_data_type_identifiers(find_sortable_rules(to_sort)).include?(to_search.identifier) + to_sort.linked_data_type_identifiers.include?(to_search.identifier) end end sorted_types << next_datatype unsorted_types.delete(next_datatype) end - # any unsorted types also need to be processed. They might still fail validations sorted_types + unsorted_types end - def find_sortable_data_type_identifiers(rules) - types = [] - - rules.each do |rule| - # noinspection RubyCaseWithoutElseBlockInspection - case rule.variant - when :contains_key, :contains_type, :return_type - extract_data_type_identifier_strings(rule.rule_config.data_type_identifier, types) - when :parent_type - extract_data_type_identifier_strings(rule.rule_config.parent_type, types) - when :input_types - rule.rule_config.input_types.each do |input_type| - extract_data_type_identifier_strings(input_type.data_type_identifier, types) - end - end - end - - types - end - - def extract_data_type_identifier_strings(data_type_identifier, collector) - data_type = data_type_identifier - - if data_type.generic_type.nil? - collector << data_type.data_type_identifier - else - collector << data_type.generic_type.data_type_identifier - data_type.generic_type.generic_mappers.each do |mapper| - mapper.source.each do |source_identifier| - extract_data_type_identifier_strings(source_identifier, collector) - end - end - end - end - - SORTABLE_RULES = %i[contains_key contains_type parent_type input_types return_type].freeze - - def contains_sortable_rule?(data_type) - data_type.rules.any? { |rule| SORTABLE_RULES.include?(rule.variant) } - end - - def find_sortable_rules(data_type) - data_type.rules.select { |rule| SORTABLE_RULES.include?(rule.variant) } - end - - def parent?(data_type) - data_type.rules.any? { |rule| rule.variant == :parent_type } - end - - def find_parent_rule(data_type) - data_type.rules.find { |rule| rule.variant == :parent_type } - end - 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 parent?(data_type) - db_object.parent_type = find_data_type_identifier( - find_parent_rule(data_type).rule_config.parent_type, - db_object, - t - ) - end - db_object.rules = update_rules(data_type.rules, db_object, t) + db_object.type = data_type.type + db_object.rules = update_rules(data_type.rules, db_object) db_object.names = update_translations(data_type.name, db_object.names) db_object.aliases = update_translations(data_type.alias, db_object.aliases) db_object.display_messages = update_translations(data_type.display_message, db_object.display_messages) db_object.generic_keys = data_type.generic_keys.to_a db_object.version = data_type.version + link_data_types(db_object, data_type.linked_data_type_identifiers, t) db_object.save db_object end # This method updates the rules of a data type in place. - # It ensures that existing rules are updated and new rules are created as needed. # @param rules [Array] The list of rules to update. # @param data_type [DataType] The data type to which the rules belong. - def update_rules(rules, data_type, t) + def update_rules(rules, data_type) db_rules = data_type.rules.first(rules.length) rules.each_with_index do |rule, index| db_rules[index] ||= DataTypeRule.new db_rules[index].assign_attributes( - variant: rule.variant.to_s.downcase, - config: extend_rule_config(rule, db_rules[index], t) + variant: rule.config, + config: rule.public_send(rule.config).to_h ) end db_rules end - - def extend_rule_config(rule, db_rule, t) - case rule.variant - when :parent_type - {} - when :contains_key - { - key: rule.rule_config.key, - data_type_identifier: rule.rule_config.data_type_identifier, - data_type_identifier_id: find_data_type_identifier(rule.rule_config.data_type_identifier, db_rule, t).id, - } - when :contains_type, :return_type - { - data_type_identifier: rule.rule_config.data_type_identifier, - data_type_identifier_id: find_data_type_identifier(rule.rule_config.data_type_identifier, db_rule, t).id, - } - when :input_types - { - input_types: rule.rule_config.input_types.map do |input_type| - { - input_identifier: input_type.input_identifier, - data_type_identifier: input_type.data_type_identifier, - data_type_identifier_id: find_data_type_identifier(input_type.data_type_identifier, db_rule, t).id, - } - end, - } - else - rule.rule_config.to_h - end - end end end end diff --git a/app/services/runtimes/grpc/flow_types/update_service.rb b/app/services/runtimes/grpc/flow_types/update_service.rb index 0aa90509..90a18664 100644 --- a/app/services/runtimes/grpc/flow_types/update_service.rb +++ b/app/services/runtimes/grpc/flow_types/update_service.rb @@ -50,12 +50,8 @@ def execute def update_flowtype(flow_type, t) db_object = FlowType.find_or_initialize_by(runtime: current_runtime, identifier: flow_type.identifier) db_object.removed_at = nil - if flow_type.input_type_identifier.present? - db_object.input_type = find_data_type(flow_type.input_type_identifier, t) - end - if flow_type.return_type_identifier.present? - db_object.return_type = find_data_type(flow_type.return_type_identifier, t) - end + db_object.input_type = flow_type.input_type.presence + db_object.return_type = flow_type.return_type.presence db_object.editable = flow_type.editable db_object.descriptions = update_translations(flow_type.description, db_object.descriptions) db_object.names = update_translations(flow_type.name, db_object.names) @@ -64,6 +60,7 @@ def update_flowtype(flow_type, t) db_object.aliases = update_translations(flow_type.alias, db_object.aliases) db_object.version = flow_type.version db_object.flow_type_settings = update_settings(flow_type.settings, db_object, t) + link_data_types(db_object, flow_type.linked_data_type_identifiers, t) db_object.save db_object end @@ -72,10 +69,11 @@ def update_settings(flow_type_settings, flow_type, t) flow_type.flow_type_settings = flow_type_settings.map do |setting| db_setting = FlowTypeSetting.find_or_initialize_by(flow_type: flow_type, identifier: setting.identifier) db_setting.unique = setting.unique.to_s.downcase + db_setting.type = setting.type db_setting.default_value = setting.default_value&.to_ruby db_setting.descriptions = update_translations(setting.description, db_setting.descriptions) db_setting.names = update_translations(setting.name, db_setting.names) - db_setting.data_type = find_data_type(setting.data_type_identifier, t) + link_data_types(db_setting, setting.linked_data_type_identifiers, t) unless db_setting.save logger.error( diff --git a/app/services/runtimes/grpc/runtime_function_definitions/update_service.rb b/app/services/runtimes/grpc/runtime_function_definitions/update_service.rb index 2a630504..8b28a0a5 100644 --- a/app/services/runtimes/grpc/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/grpc/runtime_function_definitions/update_service.rb @@ -27,7 +27,7 @@ def execute logger.error(message: 'Failed to update runtime function definition', runtime_id: current_runtime.id, - definition_identifier: runtime_function_definition.identifier, + definition_identifier: runtime_function_definition.runtime_name, errors: response.errors.full_messages) t.rollback_and_return! ServiceResponse.error(message: 'Failed to update runtime function definition', @@ -52,13 +52,9 @@ def update_runtime_function_definition(runtime_function_definition, t) runtime_name: runtime_function_definition.runtime_name ) db_object.removed_at = nil - db_object.return_type = if runtime_function_definition.return_type_identifier.present? - find_data_type_identifier( - runtime_function_definition.return_type_identifier, - db_object, - t - ) - end + db_object.signature = runtime_function_definition.signature + db_object.throws_error = runtime_function_definition.throws_error + db_object.version = runtime_function_definition.version 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, @@ -69,10 +65,7 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.display_messages) db_object.aliases = update_translations(runtime_function_definition.alias, db_object.aliases) - db_object.generic_keys = runtime_function_definition.generic_keys.to_a - - db_object.throws_error = runtime_function_definition.throws_error - db_object.version = runtime_function_definition.version + db_object.save if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -84,7 +77,6 @@ def update_runtime_function_definition(runtime_function_definition, t) definition.display_messages = update_translations(runtime_function_definition.display_message, definition.display_messages) definition.aliases = update_translations(runtime_function_definition.alias, definition.aliases) - definition.return_type = db_object.return_type db_object.function_definitions << definition end @@ -92,7 +84,7 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.parameters = update_parameters(db_object, runtime_function_definition.runtime_parameter_definitions, db_object.parameters, t) - db_object.save + link_data_types(db_object, runtime_function_definition.linked_data_type_identifiers, t) db_object end @@ -110,7 +102,6 @@ def update_parameters(runtime_function_definition, parameters, db_parameters, t) 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, db_param, t) db_param.names = update_translations(real_param.name, db_param.names) db_param.descriptions = update_translations(real_param.description, db_param.descriptions) @@ -132,7 +123,6 @@ def update_parameters(runtime_function_definition, parameters, db_parameters, t) definition.names = update_translations(real_param.name, definition.names) definition.descriptions = update_translations(real_param.description, definition.descriptions) definition.documentations = update_translations(real_param.documentation, definition.documentations) - definition.data_type = db_param.data_type definition.default_value = db_param.default_value definition.function_definition = runtime_function_definition.function_definitions.first diff --git a/app/services/service_response.rb b/app/services/service_response.rb index a7e01378..3d680089 100644 --- a/app/services/service_response.rb +++ b/app/services/service_response.rb @@ -58,8 +58,6 @@ def to_mutation_response(success_key: :object) case message when String { message: message } - when Namespaces::Projects::Flows::Validation::ValidationResult - message else raise "Unsupported error detail type: #{message.class.name}" end diff --git a/db/migrate/20260308201318_migrate_data_types_to_tucana0055.rb b/db/migrate/20260308201318_migrate_data_types_to_tucana0055.rb new file mode 100644 index 00000000..3ce57b40 --- /dev/null +++ b/db/migrate/20260308201318_migrate_data_types_to_tucana0055.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +class MigrateDataTypesToTucana0055 < Code0::ZeroTrack::Database::Migration[1.0] + def change + # Cleanup of old data types + remove_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) + + remove_reference :runtime_function_definitions, :return_type, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, + null: true + remove_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_type_identifiers, on_delete: :restrict }, + null: true + remove_reference :function_definitions, :return_type, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, + null: true + remove_reference :data_types, :parent_type, + foreign_key: { to_table: :data_type_identifiers, on_delete: :restrict }, + null: true + + remove_reference :data_type_identifiers, :generic_type, + foreign_key: { to_table: :generic_types, on_delete: :cascade }, + null: true + + remove_reference :flow_type_settings, :data_type, + foreign_key: { on_delete: :restrict }, + null: false + + remove_reference :flow_types, :input_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_reference :flow_types, :return_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } + + remove_reference :flows, :input_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } + remove_reference :flows, :return_type, + foreign_key: { to_table: :data_types, on_delete: :restrict } + + remove_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: [] + + remove_column :data_types, :variant, :integer, null: false + + drop_table :generic_combination_strategies do |t| + t.integer :type, null: false + t.references :generic_mapper, null: true, foreign_key: { + to_table: :generic_mappers, + on_delete: :cascade, + } + + t.timestamps_with_timezone + end + + remove_reference :data_type_identifiers, :generic_mapper, + foreign_key: { to_table: :generic_mappers, on_delete: :cascade }, + null: true + + drop_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 :generic_type, null: true, foreign_key: { to_table: :generic_types, on_delete: :restrict } + + t.timestamps_with_timezone + end + + drop_table :generic_types do |t| + t.references :data_type, null: false, foreign_key: { to_table: :data_types, on_delete: :cascade } + + t.timestamps_with_timezone + + t.references :owner, polymorphic: true + end + + drop_table :data_type_identifiers do |t| + 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 + + # Creation of tables and relations for the new data types + # rubocop:disable Rails/NotNullColumn -- backwards compatibility intentionally ignored + add_column :runtime_function_definitions, :signature, :text, null: false, limit: 500 + add_column :data_types, :type, :text, null: false, limit: 2000 + add_column :flow_type_settings, :type, :text, null: false, limit: 2000 + add_column :flow_types, :input_type, :text, limit: 2000 + add_column :flow_types, :return_type, :text, limit: 2000 + add_column :flows, :input_type, :text, limit: 2000 + add_column :flows, :return_type, :text, limit: 2000 + # rubocop:enable Rails/NotNullColumn + + create_table :runtime_function_definition_data_type_links do |t| + t.references :runtime_function_definition, null: false, + foreign_key: { on_delete: :cascade }, + index: false + t.references :referenced_data_type, null: false, + foreign_key: { to_table: :data_types, on_delete: :restrict }, + index: false + + t.index %i[runtime_function_definition_id referenced_data_type_id], unique: true + + t.timestamps_with_timezone + end + + create_table :data_type_data_type_links do |t| + t.references :data_type, null: false, + foreign_key: { on_delete: :cascade }, + index: false + t.references :referenced_data_type, null: false, + foreign_key: { to_table: :data_types, on_delete: :restrict }, + index: false + + t.index %i[data_type_id referenced_data_type_id], unique: true + + t.timestamps_with_timezone + end + + create_table :flow_type_setting_data_type_links do |t| + t.references :flow_type_setting, null: false, + foreign_key: { on_delete: :cascade }, + index: false + t.references :referenced_data_type, null: false, + foreign_key: { to_table: :data_types, on_delete: :restrict }, + index: false + + t.index %i[flow_type_setting_id referenced_data_type_id], unique: true + + t.timestamps_with_timezone + end + + create_table :flow_type_data_type_links do |t| + t.references :flow_type, null: false, + foreign_key: { on_delete: :cascade }, + index: false + t.references :referenced_data_type, null: false, + foreign_key: { to_table: :data_types, on_delete: :restrict }, + index: false + + t.index %i[flow_type_id referenced_data_type_id], unique: true + + t.timestamps_with_timezone + end + + create_table :flow_data_type_links do |t| + t.references :flow, null: false, + foreign_key: { on_delete: :cascade }, + index: false + t.references :referenced_data_type, null: false, + foreign_key: { to_table: :data_types, on_delete: :restrict }, + index: false + + t.index %i[flow_id referenced_data_type_id], unique: true + + t.timestamps_with_timezone + end + end +end diff --git a/db/schema_migrations/20260308201318 b/db/schema_migrations/20260308201318 new file mode 100644 index 00000000..7dd314de --- /dev/null +++ b/db/schema_migrations/20260308201318 @@ -0,0 +1 @@ +48ec5f52f080c7b248a4c8423ab9f397e7736e26e37859d55869d640cfcb150a \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 3a59210f..76809bdb 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -121,26 +121,22 @@ CREATE SEQUENCE backup_codes_id_seq ALTER SEQUENCE backup_codes_id_seq OWNED BY backup_codes.id; -CREATE TABLE data_type_identifiers ( +CREATE TABLE data_type_data_type_links ( id bigint NOT NULL, - generic_key text, - data_type_id bigint, - runtime_id bigint NOT NULL, + data_type_id bigint NOT NULL, + referenced_data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - generic_type_id bigint, - generic_mapper_id bigint, - CONSTRAINT check_480d44acbd CHECK ((num_nonnulls(generic_key, data_type_id, generic_type_id) = 1)) + updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE data_type_identifiers_id_seq +CREATE SEQUENCE data_type_data_type_links_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; +ALTER SEQUENCE data_type_data_type_links_id_seq OWNED BY data_type_data_type_links.id; CREATE TABLE data_type_rules ( id bigint NOT NULL, @@ -163,14 +159,14 @@ ALTER SEQUENCE data_type_rules_id_seq OWNED BY data_type_rules.id; CREATE TABLE 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, runtime_id bigint NOT NULL, removed_at timestamp with time zone, generic_keys text[] DEFAULT '{}'::text[] NOT NULL, - parent_type_id bigint, version text NOT NULL, + type text NOT NULL, + CONSTRAINT check_01ca31b7b9 CHECK ((char_length(type) <= 2000)), CONSTRAINT check_3a7198812e CHECK ((char_length(identifier) <= 50)) ); @@ -183,156 +179,158 @@ CREATE SEQUENCE data_types_id_seq ALTER SEQUENCE data_types_id_seq OWNED BY data_types.id; -CREATE TABLE flow_settings ( +CREATE TABLE flow_data_type_links ( id bigint NOT NULL, flow_id bigint NOT NULL, - flow_setting_id text NOT NULL, - object jsonb NOT NULL, + referenced_data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE flow_settings_id_seq +CREATE SEQUENCE flow_data_type_links_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; +ALTER SEQUENCE flow_data_type_links_id_seq OWNED BY flow_data_type_links.id; -CREATE TABLE flow_type_settings ( +CREATE TABLE flow_settings ( id bigint NOT NULL, - flow_type_id bigint NOT NULL, - identifier text NOT NULL, - data_type_id bigint NOT NULL, - default_value jsonb, + flow_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, - "unique" integer DEFAULT 0 NOT NULL + updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE flow_type_settings_id_seq +CREATE SEQUENCE flow_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; +ALTER SEQUENCE flow_settings_id_seq OWNED BY flow_settings.id; -CREATE TABLE flow_types ( +CREATE TABLE flow_type_data_type_links ( id bigint NOT NULL, - runtime_id bigint NOT NULL, - identifier text NOT NULL, - input_type_id bigint, - return_type_id bigint, - editable boolean DEFAULT true NOT NULL, - removed_at timestamp with time zone, + flow_type_id bigint NOT NULL, + referenced_data_type_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - version text NOT NULL + updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE flow_types_id_seq +CREATE SEQUENCE flow_type_data_type_links_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; +ALTER SEQUENCE flow_type_data_type_links_id_seq OWNED BY flow_type_data_type_links.id; -CREATE TABLE flows ( +CREATE TABLE flow_type_setting_data_type_links ( id bigint NOT NULL, - project_id bigint NOT NULL, - flow_type_id bigint NOT NULL, - input_type_id bigint, - return_type_id bigint, - starting_node_id bigint, - name text NOT NULL, + flow_type_setting_id bigint NOT NULL, + referenced_data_type_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 +CREATE SEQUENCE flow_type_setting_data_type_links_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; -ALTER SEQUENCE flows_id_seq OWNED BY flows.id; +ALTER SEQUENCE flow_type_setting_data_type_links_id_seq OWNED BY flow_type_setting_data_type_links.id; -CREATE TABLE function_definitions ( +CREATE TABLE flow_type_settings ( id bigint NOT NULL, - runtime_function_definition_id bigint NOT NULL, + flow_type_id bigint NOT NULL, + identifier text NOT NULL, + default_value jsonb, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, - return_type_id bigint + "unique" integer DEFAULT 0 NOT NULL, + type text NOT NULL, + CONSTRAINT check_52136fe376 CHECK ((char_length(type) <= 2000)) ); -CREATE SEQUENCE function_definitions_id_seq +CREATE SEQUENCE flow_type_settings_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; +ALTER SEQUENCE flow_type_settings_id_seq OWNED BY flow_type_settings.id; -CREATE TABLE generic_combination_strategies ( +CREATE TABLE flow_types ( id bigint NOT NULL, - type integer NOT NULL, - generic_mapper_id bigint, + runtime_id bigint NOT NULL, + identifier text NOT NULL, + editable boolean DEFAULT true NOT NULL, + removed_at timestamp with time zone, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL + updated_at timestamp with time zone NOT NULL, + version text NOT NULL, + input_type text, + return_type text, + CONSTRAINT check_c6b1f013b0 CHECK ((char_length(input_type) <= 2000)), + CONSTRAINT check_f6a6997219 CHECK ((char_length(return_type) <= 2000)) ); -CREATE SEQUENCE generic_combination_strategies_id_seq +CREATE SEQUENCE flow_types_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; +ALTER SEQUENCE flow_types_id_seq OWNED BY flow_types.id; -CREATE TABLE generic_mappers ( +CREATE TABLE flows ( id bigint NOT NULL, - runtime_id bigint NOT NULL, - target text NOT NULL, - generic_type_id bigint, + project_id bigint NOT NULL, + flow_type_id bigint NOT NULL, + starting_node_id bigint, + name text 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, + input_type text, + return_type text, + CONSTRAINT check_1c805d704f CHECK ((char_length(input_type) <= 2000)), + CONSTRAINT check_b2f3f83908 CHECK ((char_length(return_type) <= 2000)) ); -CREATE SEQUENCE generic_mappers_id_seq +CREATE SEQUENCE flows_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; +ALTER SEQUENCE flows_id_seq OWNED BY flows.id; -CREATE TABLE generic_types ( +CREATE TABLE function_definitions ( id bigint NOT NULL, - data_type_id bigint NOT NULL, + runtime_function_definition_id bigint NOT NULL, created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL, - owner_type character varying, - owner_id bigint + updated_at timestamp with time zone NOT NULL ); -CREATE SEQUENCE generic_types_id_seq +CREATE SEQUENCE function_definitions_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; +ALTER SEQUENCE function_definitions_id_seq OWNED BY function_definitions.id; CREATE TABLE good_job_batches ( id uuid DEFAULT gen_random_uuid() NOT NULL, @@ -633,7 +631,6 @@ CREATE TABLE parameter_definitions ( default_value jsonb, created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, - data_type_id bigint, function_definition_id bigint NOT NULL ); @@ -699,6 +696,23 @@ CREATE SEQUENCE runtime_features_id_seq ALTER SEQUENCE runtime_features_id_seq OWNED BY runtime_features.id; +CREATE TABLE runtime_function_definition_data_type_links ( + id bigint NOT NULL, + runtime_function_definition_id bigint NOT NULL, + referenced_data_type_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE runtime_function_definition_data_type_links_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE runtime_function_definition_data_type_links_id_seq OWNED BY runtime_function_definition_data_type_links.id; + CREATE TABLE runtime_function_definitions ( id bigint NOT NULL, runtime_id bigint NOT NULL, @@ -707,9 +721,9 @@ CREATE TABLE runtime_function_definitions ( 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, version text NOT NULL, + signature text NOT NULL, + CONSTRAINT check_86da361565 CHECK ((char_length(signature) <= 500)), CONSTRAINT check_fe8fff4f27 CHECK ((char_length(runtime_name) <= 50)) ); @@ -730,7 +744,6 @@ CREATE TABLE runtime_parameter_definitions ( 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)) ); @@ -901,14 +914,20 @@ 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_data_type_links ALTER COLUMN id SET DEFAULT nextval('data_type_data_type_links_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); +ALTER TABLE ONLY flow_data_type_links ALTER COLUMN id SET DEFAULT nextval('flow_data_type_links_id_seq'::regclass); + ALTER TABLE ONLY flow_settings ALTER COLUMN id SET DEFAULT nextval('flow_settings_id_seq'::regclass); +ALTER TABLE ONLY flow_type_data_type_links ALTER COLUMN id SET DEFAULT nextval('flow_type_data_type_links_id_seq'::regclass); + +ALTER TABLE ONLY flow_type_setting_data_type_links ALTER COLUMN id SET DEFAULT nextval('flow_type_setting_data_type_links_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); @@ -917,12 +936,6 @@ ALTER TABLE ONLY flows ALTER COLUMN id SET DEFAULT nextval('flows_id_seq'::regcl ALTER TABLE ONLY function_definitions ALTER COLUMN id SET DEFAULT nextval('function_definitions_id_seq'::regclass); -ALTER TABLE ONLY generic_combination_strategies ALTER COLUMN id SET DEFAULT nextval('generic_combination_strategies_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); @@ -955,6 +968,8 @@ ALTER TABLE ONLY reference_values ALTER COLUMN id SET DEFAULT nextval('reference ALTER TABLE ONLY runtime_features ALTER COLUMN id SET DEFAULT nextval('runtime_features_id_seq'::regclass); +ALTER TABLE ONLY runtime_function_definition_data_type_links ALTER COLUMN id SET DEFAULT nextval('runtime_function_definition_data_type_links_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); @@ -994,8 +1009,8 @@ 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_data_type_links + ADD CONSTRAINT data_type_data_type_links_pkey PRIMARY KEY (id); ALTER TABLE ONLY data_type_rules ADD CONSTRAINT data_type_rules_pkey PRIMARY KEY (id); @@ -1003,9 +1018,18 @@ ALTER TABLE ONLY data_type_rules ALTER TABLE ONLY data_types ADD CONSTRAINT data_types_pkey PRIMARY KEY (id); +ALTER TABLE ONLY flow_data_type_links + ADD CONSTRAINT flow_data_type_links_pkey PRIMARY KEY (id); + ALTER TABLE ONLY flow_settings ADD CONSTRAINT flow_settings_pkey PRIMARY KEY (id); +ALTER TABLE ONLY flow_type_data_type_links + ADD CONSTRAINT flow_type_data_type_links_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY flow_type_setting_data_type_links + ADD CONSTRAINT flow_type_setting_data_type_links_pkey PRIMARY KEY (id); + ALTER TABLE ONLY flow_type_settings ADD CONSTRAINT flow_type_settings_pkey PRIMARY KEY (id); @@ -1018,15 +1042,6 @@ ALTER TABLE ONLY flows ALTER TABLE ONLY function_definitions ADD CONSTRAINT function_definitions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY generic_combination_strategies - ADD CONSTRAINT generic_combination_strategies_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); @@ -1090,6 +1105,9 @@ ALTER TABLE ONLY reference_values ALTER TABLE ONLY runtime_features ADD CONSTRAINT runtime_features_pkey PRIMARY KEY (id); +ALTER TABLE ONLY runtime_function_definition_data_type_links + ADD CONSTRAINT runtime_function_definition_data_type_links_pkey PRIMARY KEY (id); + ALTER TABLE ONLY runtime_function_definitions ADD CONSTRAINT runtime_function_definitions_pkey PRIMARY KEY (id); @@ -1120,10 +1138,20 @@ ALTER TABLE ONLY user_sessions ALTER TABLE ONLY users ADD CONSTRAINT users_pkey PRIMARY KEY (id); +CREATE UNIQUE INDEX idx_on_data_type_id_referenced_data_type_id_bb9b090c90 ON data_type_data_type_links USING btree (data_type_id, referenced_data_type_id); + +CREATE UNIQUE INDEX idx_on_flow_id_referenced_data_type_id_14b02b52f8 ON flow_data_type_links USING btree (flow_id, referenced_data_type_id); + +CREATE UNIQUE INDEX idx_on_flow_type_id_referenced_data_type_id_70312c9382 ON flow_type_data_type_links USING btree (flow_type_id, referenced_data_type_id); + +CREATE UNIQUE INDEX idx_on_flow_type_setting_id_referenced_data_type_id_facda120ed ON flow_type_setting_data_type_links USING btree (flow_type_setting_id, referenced_data_type_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); +CREATE UNIQUE INDEX idx_on_runtime_function_definition_id_referenced_da_a6da962633 ON runtime_function_definition_data_type_links USING btree (runtime_function_definition_id, referenced_data_type_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); @@ -1144,58 +1172,26 @@ 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_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); - -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); - 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); -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); -CREATE INDEX index_flow_types_on_input_type_id ON flow_types USING btree (input_type_id); - -CREATE INDEX index_flow_types_on_return_type_id ON flow_types USING btree (return_type_id); - 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_id ON flows USING btree (input_type_id); - CREATE UNIQUE INDEX index_flows_on_name_and_project_id ON flows USING btree (name, project_id); 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); - 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); -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); - -CREATE INDEX index_generic_mappers_on_runtime_id ON generic_mappers USING btree (runtime_id); - -CREATE INDEX index_generic_types_on_data_type_id ON generic_types USING btree (data_type_id); - -CREATE INDEX index_generic_types_on_owner ON generic_types USING btree (owner_type, owner_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); @@ -1272,8 +1268,6 @@ CREATE INDEX index_node_parameters_on_reference_value_id ON node_parameters USIN 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_function_definition_id ON parameter_definitions USING btree (function_definition_id); CREATE INDEX index_parameter_definitions_on_runtime_parameter_definition_id ON parameter_definitions USING btree (runtime_parameter_definition_id); @@ -1284,10 +1278,6 @@ CREATE INDEX index_reference_values_on_node_function_id ON reference_values USIN CREATE INDEX index_runtime_features_on_runtime_status_id ON runtime_features USING btree (runtime_status_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); - CREATE INDEX index_runtime_status_configurations_on_runtime_status_id ON runtime_status_configurations USING btree (runtime_status_id); CREATE INDEX index_runtime_statuses_on_runtime_id ON runtime_statuses USING btree (runtime_id); @@ -1314,14 +1304,8 @@ CREATE UNIQUE INDEX "index_users_on_LOWER_username" ON users USING btree (lower( 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; - -ALTER TABLE ONLY data_type_identifiers - ADD CONSTRAINT fk_rails_01f5d14544 FOREIGN KEY (generic_mapper_id) REFERENCES generic_mappers(id) ON DELETE CASCADE; - -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 flow_type_setting_data_type_links + ADD CONSTRAINT fk_rails_0816d2665b FOREIGN KEY (referenced_data_type_id) REFERENCES data_types(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; @@ -1332,21 +1316,18 @@ ALTER TABLE ONLY data_types ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_18c14268dd FOREIGN KEY (function_definition_id) REFERENCES function_definitions(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; - ALTER TABLE ONLY namespace_roles ADD CONSTRAINT fk_rails_205092c9cb FOREIGN KEY (namespace_id) REFERENCES namespaces(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 generic_types - ADD CONSTRAINT fk_rails_275446d9e6 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE; - ALTER TABLE ONLY node_parameters ADD CONSTRAINT fk_rails_2ed7c53167 FOREIGN KEY (parameter_definition_id) REFERENCES parameter_definitions(id) ON DELETE RESTRICT; +ALTER TABLE ONLY flow_type_data_type_links + ADD CONSTRAINT fk_rails_38698de52d FOREIGN KEY (referenced_data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + ALTER TABLE ONLY namespace_licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; @@ -1359,15 +1340,15 @@ ALTER TABLE ONLY runtime_statuses 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 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_type_identifiers(id) ON DELETE RESTRICT; +ALTER TABLE ONLY data_type_data_type_links + ADD CONSTRAINT fk_rails_443c90661b FOREIGN KEY (referenced_data_type_id) REFERENCES data_types(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; +ALTER TABLE ONLY flow_type_data_type_links + ADD CONSTRAINT fk_rails_4a293cd114 FOREIGN KEY (flow_type_id) REFERENCES flow_types(id) ON DELETE CASCADE; + ALTER TABLE ONLY runtime_function_definitions ADD CONSTRAINT fk_rails_5161ff47e6 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; @@ -1383,14 +1364,20 @@ ALTER TABLE ONLY namespace_members 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 runtime_function_definition_data_type_links + ADD CONSTRAINT fk_rails_5a52fd74a0 FOREIGN KEY (referenced_data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; + 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 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 runtime_function_definition_data_type_links + ADD CONSTRAINT fk_rails_64dd235e33 FOREIGN KEY (runtime_function_definition_id) REFERENCES runtime_function_definitions(id) ON DELETE CASCADE; + +ALTER TABLE ONLY flow_data_type_links + ADD CONSTRAINT fk_rails_657ea5202b FOREIGN KEY (referenced_data_type_id) REFERENCES data_types(id) ON DELETE RESTRICT; ALTER TABLE ONLY user_identities ADD CONSTRAINT fk_rails_684b0e1ce0 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; @@ -1407,9 +1394,6 @@ ALTER TABLE ONLY namespace_member_roles 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_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) DEFERRABLE INITIALLY DEFERRED; @@ -1428,11 +1412,8 @@ ALTER TABLE ONLY node_functions ALTER TABLE ONLY reference_values ADD CONSTRAINT fk_rails_8b9d8f68cc FOREIGN KEY (node_function_id) REFERENCES node_functions(id) DEFERRABLE INITIALLY DEFERRED; -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 data_type_data_type_links + ADD CONSTRAINT fk_rails_90fbf0d8ef FOREIGN KEY (data_type_id) REFERENCES data_types(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; @@ -1446,18 +1427,12 @@ ALTER TABLE ONLY user_sessions 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; +ALTER TABLE ONLY flow_type_setting_data_type_links + ADD CONSTRAINT fk_rails_a257bb7ffc FOREIGN KEY (flow_type_setting_id) REFERENCES flow_type_settings(id) ON DELETE CASCADE; ALTER TABLE ONLY flows ADD CONSTRAINT fk_rails_ab927e0ecb FOREIGN KEY (project_id) REFERENCES namespace_projects(id) ON DELETE CASCADE; -ALTER TABLE ONLY flows - ADD CONSTRAINT fk_rails_bb587eff6a FOREIGN KEY (input_type_id) REFERENCES data_types(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; @@ -1467,12 +1442,6 @@ ALTER TABLE ONLY active_storage_attachments 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; - -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 runtime_status_configurations ADD CONSTRAINT fk_rails_d3eeb850ed FOREIGN KEY (runtime_status_id) REFERENCES runtime_statuses(id) ON DELETE CASCADE; @@ -1485,15 +1454,12 @@ ALTER TABLE ONLY flows 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; - -ALTER TABLE ONLY runtime_parameter_definitions - 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 flow_data_type_links + ADD CONSTRAINT fk_rails_f4202724d3 FOREIGN KEY (flow_id) REFERENCES flows(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/enum/datatyperulesvariant.md b/docs/graphql/enum/datatyperulesvariant.md index 582144c8..8c1a0983 100644 --- a/docs/graphql/enum/datatyperulesvariant.md +++ b/docs/graphql/enum/datatyperulesvariant.md @@ -6,11 +6,5 @@ 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_TYPES` | 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. | -| `PARENT_TYPE` | The rule checks if the data type is a child of a specific parent type. | | `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 deleted file mode 100644 index 4e332832..00000000 --- a/docs/graphql/enum/datatypevariant.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: DataTypeVariant ---- - -Represent all available types of a datatype - -| Value | Description | -|-------|-------------| -| `ARRAY` | Represents an array | -| `DATA_TYPE` | Represents an data type containing a data type | -| `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/enum/errorcodeenum.md b/docs/graphql/enum/errorcodeenum.md index 7755b165..b98e3261 100644 --- a/docs/graphql/enum/errorcodeenum.md +++ b/docs/graphql/enum/errorcodeenum.md @@ -11,7 +11,6 @@ Represents the available error responses | `CANNOT_MODIFY_OWN_ADMIN` | Users cannot modify their own admin status | | `CANNOT_REMOVE_LAST_ADMINISTRATOR` | This action would remove the last administrator | | `CANNOT_REMOVE_LAST_ADMIN_ABILITY` | This action would remove the last administrative ability | -| `DATA_TYPE_IDENTIFIER_NOT_FOUND` | The data type identifier with the given identifier was not found | | `DATA_TYPE_NOT_FOUND` | The data type with the given identifier was not found | | `EMAIL_VERIFICATION_SEND_FAILED` | Failed to send the email verification | | `EXTERNAL_IDENTITY_DOES_NOT_EXIST` | This external identity does not exist | @@ -20,7 +19,6 @@ Represents the available error responses | `FAILED_TO_SAVE_VALID_BACKUP_CODE` | The new backup codes could not be saved | | `FLOW_NOT_FOUND` | The flow with the given identifier was not found | | `FLOW_TYPE_NOT_FOUND` | The flow type with the given identifier was not found | -| `FLOW_VALIDATION_FAILED` | The flow validation has failed | | `FUNCTION_VALUE_NOT_FOUND` | The id for the function value node does not exist | | `GENERIC_KEY_NOT_FOUND` | The given key was not found in the data type | | `IDENTITY_NOT_FOUND` | The external identity with the given identifier was not found | @@ -28,13 +26,13 @@ Represents the available error responses | `INCONSISTENT_NAMESPACE` | Resources are from different namespaces | | `INVALID_ATTACHMENT` | The attachment is invalid because of active model errors | | `INVALID_DATA_TYPE` | The data type is invalid because of active model errors | +| `INVALID_DATA_TYPE_LINK` | The data type link is invalid because of active model errors | | `INVALID_EXTERNAL_IDENTITY` | This external identity is invalid | | `INVALID_FLOW` | The flow is invalid because of active model errors | | `INVALID_FLOW_SETTING` | The flow setting is invalid because of active model errors | | `INVALID_FLOW_TYPE` | The flow type is invalid because of active model errors | | `INVALID_FLOW_TYPE_SETTING` | The flow type setting is invalid because of active model errors | | `INVALID_FUNCTION_ID` | The function ID is invalid | -| `INVALID_GENERIC_MAPPER` | The generic mapper is invalid because of active model errors | | `INVALID_LOGIN_DATA` | Invalid login data provided | | `INVALID_NAMESPACE_LICENSE` | The namespace license is invalid because of active model errors | | `INVALID_NAMESPACE_MEMBER` | The namespace member is invalid because of active model errors | @@ -73,10 +71,8 @@ Represents the available error responses | `NAMESPACE_PROJECT_NOT_FOUND` | The namespace project with the given identifier was not found | | `NAMESPACE_ROLE_NOT_FOUND` | The namespace role with the given identifier was not found | | `NODE_NOT_FOUND` | The node with this id does not exist | -| `NO_DATATYPE_IDENTIFIER_FOR_GENERIC_KEY` | No data type identifier could be found for the given generic key | | `NO_DATA_TYPE_FOR_IDENTIFIER` | No data type could be found for the given identifier | | `NO_FREE_LICENSE_SEATS` | There are no free license seats to complete this operation | -| `NO_GENERIC_TYPE_FOR_IDENTIFIER` | No generic type could be found for the given identifier | | `NO_PRIMARY_RUNTIME` | The project does not have a primary runtime | | `ORGANIZATION_NOT_FOUND` | The organization with the given identifier was not found | | `OUTDATED_DEFINITION` | The primary runtime has a newer definition than this one | diff --git a/docs/graphql/enum/flowvalidationerrorcodeenum.md b/docs/graphql/enum/flowvalidationerrorcodeenum.md deleted file mode 100644 index 70b38f79..00000000 --- a/docs/graphql/enum/flowvalidationerrorcodeenum.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: FlowValidationErrorCodeEnum ---- - -Represents the available error responses - -| Value | Description | -|-------|-------------| -| `DATA_TYPE_IDENTIFIER_GENERIC_KEY_NOT_FOUND` | The generic key for the data type identifier was not found. | -| `DATA_TYPE_IDENTIFIER_RUNTIME_MISMATCH` | The data type identifier runtime does not match the flow type runtime. | -| `DATA_TYPE_RULE_MODEL_INVALID` | The data type rule model is invalid. | -| `DATA_TYPE_RUNTIME_MISMATCH` | The data type runtime does not match the flow type runtime. | -| `FLOW_SETTING_MODEL_INVALID` | The flow setting model is invalid. | -| `FLOW_TYPE_RUNTIME_MISMATCH` | The flow type runtime does not match the project primary runtime. | -| `NODE_FUNCTION_RUNTIME_MISMATCH` | The node function runtime does not match the project primary runtime. | -| `NO_PRIMARY_RUNTIME` | The project does not have a primary runtime set. | diff --git a/docs/graphql/enum/flowvalidationseverityenum.md b/docs/graphql/enum/flowvalidationseverityenum.md deleted file mode 100644 index 9fcfe023..00000000 --- a/docs/graphql/enum/flowvalidationseverityenum.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: FlowValidationSeverityEnum ---- - -Represents the severity of a flow validation error - -| Value | Description | -|-------|-------------| -| `ERROR` | A blocking validation error | -| `TYPO` | A minor typographical issue can also be blocking | -| `WARNING` | A non-blocking validation warning | -| `WEAK` | A weak validation issue that may not need to be addressed | diff --git a/docs/graphql/enum/genericcombinationstrategytype.md b/docs/graphql/enum/genericcombinationstrategytype.md deleted file mode 100644 index 6fd4b622..00000000 --- a/docs/graphql/enum/genericcombinationstrategytype.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: GenericCombinationStrategyType ---- - -The available combination strategy types. - -| Value | Description | -|-------|-------------| -| `AND` | Represents a logical AND combination. | -| `OR` | Represents a logical OR combination. | diff --git a/docs/graphql/object/datatype.md b/docs/graphql/object/datatype.md index 70c0e27f..cc4ce694 100644 --- a/docs/graphql/object/datatype.md +++ b/docs/graphql/object/datatype.md @@ -10,14 +10,14 @@ Represents a DataType |------|------|-------------| | `aliases` | [`[Translation!]`](../object/translation.md) | Name of the function | | `createdAt` | [`Time!`](../scalar/time.md) | Time when this DataType was created | -| `dataTypeIdentifiers` | [`DataTypeIdentifierConnection!`](../object/datatypeidentifierconnection.md) | The data type identifiers that are referenced in this data type and its rules | | `displayMessages` | [`[Translation!]`](../object/translation.md) | Display message of the function | -| `genericKeys` | [`[String!]`](../scalar/string.md) | Generic keys of the datatype | +| `genericKeys` | [`[String!]!`](../scalar/string.md) | The 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` | [`[Translation!]!`](../object/translation.md) | Names of the flow type setting | +| `referencedDataTypes` | [`DataTypeConnection!`](../object/datatypeconnection.md) | The data types that are referenced in this data type | | `rules` | [`DataTypeRuleConnection!`](../object/datatyperuleconnection.md) | Rules of the datatype | | `runtime` | [`Runtime`](../object/runtime.md) | The runtime where this datatype belongs to | +| `type` | [`String!`](../scalar/string.md) | The type 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/datatypeidentifier.md b/docs/graphql/object/datatypeidentifier.md deleted file mode 100644 index cd9d763d..00000000 --- a/docs/graphql/object/datatypeidentifier.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: DataTypeIdentifier ---- - -Represents a data type identifier. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `createdAt` | [`Time!`](../scalar/time.md) | Time when this DataTypeIdentifier was created | -| `dataType` | [`DataType`](../object/datatype.md) | The data type of the data type identifier. | -| `genericKey` | [`String`](../scalar/string.md) | The generic key of the data type identifier. | -| `genericType` | [`GenericType`](../object/generictype.md) | The generic type of the data type identifier. | -| `id` | [`DataTypeIdentifierID!`](../scalar/datatypeidentifierid.md) | Global ID of this DataTypeIdentifier | -| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this DataTypeIdentifier was last updated | - diff --git a/docs/graphql/object/datatypeidentifierconnection.md b/docs/graphql/object/datatypeidentifierconnection.md deleted file mode 100644 index 368757c6..00000000 --- a/docs/graphql/object/datatypeidentifierconnection.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: DataTypeIdentifierConnection ---- - -The connection type for DataTypeIdentifier. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `count` | [`Int!`](../scalar/int.md) | Total count of collection. | -| `edges` | [`[DataTypeIdentifierEdge]`](../object/datatypeidentifieredge.md) | A list of edges. | -| `nodes` | [`[DataTypeIdentifier]`](../object/datatypeidentifier.md) | A list of nodes. | -| `pageInfo` | [`PageInfo!`](../object/pageinfo.md) | Information to aid in pagination. | - diff --git a/docs/graphql/object/datatypeidentifieredge.md b/docs/graphql/object/datatypeidentifieredge.md deleted file mode 100644 index 086a0ba7..00000000 --- a/docs/graphql/object/datatypeidentifieredge.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: DataTypeIdentifierEdge ---- - -An edge in a connection. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `cursor` | [`String!`](../scalar/string.md) | A cursor for use in pagination. | -| `node` | [`DataTypeIdentifier`](../object/datatypeidentifier.md) | The item at the end of the edge. | - diff --git a/docs/graphql/object/datatyperulescontainskeyconfig.md b/docs/graphql/object/datatyperulescontainskeyconfig.md deleted file mode 100644 index 0691e62c..00000000 --- a/docs/graphql/object/datatyperulescontainskeyconfig.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: DataTypeRulesContainsKeyConfig ---- - -Represents a rule that can be applied to a data type. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `dataTypeIdentifierId` | [`DataTypeIdentifierID!`](../scalar/datatypeidentifierid.md) | ID of 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/datatyperulescontainstypeconfig.md b/docs/graphql/object/datatyperulescontainstypeconfig.md deleted file mode 100644 index 115b3210..00000000 --- a/docs/graphql/object/datatyperulescontainstypeconfig.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: DataTypeRulesContainsTypeConfig ---- - -Represents a rule that can be applied to a data type. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `dataTypeIdentifierId` | [`DataTypeIdentifierID!`](../scalar/datatypeidentifierid.md) | ID of the identifier of the data type this rule belongs to | - diff --git a/docs/graphql/object/datatyperulesinputtypeconfig.md b/docs/graphql/object/datatyperulesinputtypeconfig.md deleted file mode 100644 index 293dc5fb..00000000 --- a/docs/graphql/object/datatyperulesinputtypeconfig.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: DataTypeRulesInputTypeConfig ---- - -Represents a subtype of input type configuration for a input data type. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `dataTypeIdentifierId` | [`DataTypeIdentifierID!`](../scalar/datatypeidentifierid.md) | ID of the identifier of the data type this input type belongs to | -| `inputIdentifier` | [`String!`](../scalar/string.md) | The input identifier that this configuration applies to | - diff --git a/docs/graphql/object/datatyperulesinputtypesconfig.md b/docs/graphql/object/datatyperulesinputtypesconfig.md deleted file mode 100644 index 4b3ab439..00000000 --- a/docs/graphql/object/datatyperulesinputtypesconfig.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: DataTypeRulesInputTypesConfig ---- - -Represents a rule that can be applied to a data type. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `inputTypes` | [`[DataTypeRulesInputTypeConfig!]!`](../object/datatyperulesinputtypeconfig.md) | The input types that can be used in this data type rule | - diff --git a/docs/graphql/object/datatyperulesitemofcollectionconfig.md b/docs/graphql/object/datatyperulesitemofcollectionconfig.md deleted file mode 100644 index 0dd453c9..00000000 --- a/docs/graphql/object/datatyperulesitemofcollectionconfig.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: DataTypeRulesItemOfCollectionConfig ---- - -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/datatyperulesparenttypeconfig.md b/docs/graphql/object/datatyperulesparenttypeconfig.md deleted file mode 100644 index d7bac94a..00000000 --- a/docs/graphql/object/datatyperulesparenttypeconfig.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: DataTypeRulesParentTypeConfig ---- - -Represents a rule that can be applied to a data type. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `dataTypeIdentifierId` | [`DataTypeIdentifierID!`](../scalar/datatypeidentifierid.md) | ID of the data type identifier for the parent type. | - diff --git a/docs/graphql/object/datatyperulesreturntypeconfig.md b/docs/graphql/object/datatyperulesreturntypeconfig.md deleted file mode 100644 index 0d8b1313..00000000 --- a/docs/graphql/object/datatyperulesreturntypeconfig.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: DataTypeRulesReturnTypeConfig ---- - -Represents a rule that can be applied to a data type. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `dataTypeIdentifierId` | [`DataTypeIdentifierID!`](../scalar/datatypeidentifierid.md) | The data type identifier for the return type. | - diff --git a/docs/graphql/object/flow.md b/docs/graphql/object/flow.md index 0b71f669..7f37f493 100644 --- a/docs/graphql/object/flow.md +++ b/docs/graphql/object/flow.md @@ -10,11 +10,12 @@ Represents a flow |------|------|-------------| | `createdAt` | [`Time!`](../scalar/time.md) | Time when this Flow was created | | `id` | [`FlowID!`](../scalar/flowid.md) | Global ID of this Flow | -| `inputType` | [`DataType`](../object/datatype.md) | The input data type of the flow | +| `inputType` | [`String`](../scalar/string.md) | The input data type of the flow | | `name` | [`String!`](../scalar/string.md) | Name of the flow | | `nodes` | [`NodeFunctionConnection!`](../object/nodefunctionconnection.md) | Nodes of the flow | | `project` | [`NamespaceProject!`](../object/namespaceproject.md) | The project the flow belongs to | -| `returnType` | [`DataType`](../object/datatype.md) | The return data type of the flow | +| `referencedDataTypes` | [`DataTypeConnection!`](../object/datatypeconnection.md) | The data types that are referenced in this flow | +| `returnType` | [`String`](../scalar/string.md) | The return data type of the flow | | `settings` | [`FlowSettingConnection!`](../object/flowsettingconnection.md) | The settings of the flow | | `startingNodeId` | [`NodeFunctionID`](../scalar/nodefunctionid.md) | The ID of the starting node of the flow | | `type` | [`FlowType!`](../object/flowtype.md) | The flow type of the flow | diff --git a/docs/graphql/object/flowtype.md b/docs/graphql/object/flowtype.md index 7b81ce4d..acadf892 100644 --- a/docs/graphql/object/flowtype.md +++ b/docs/graphql/object/flowtype.md @@ -16,9 +16,10 @@ Represents a flow type | `flowTypeSettings` | [`[FlowTypeSetting!]!`](../object/flowtypesetting.md) | Flow type settings of the flow type | | `id` | [`FlowTypeID!`](../scalar/flowtypeid.md) | Global ID of this FlowType | | `identifier` | [`String!`](../scalar/string.md) | Identifier of the flow type | -| `inputType` | [`DataType`](../object/datatype.md) | Input type of the flow type | +| `inputType` | [`String`](../scalar/string.md) | Input type of the flow type | | `names` | [`[Translation!]`](../object/translation.md) | Names of the flow type | -| `returnType` | [`DataType`](../object/datatype.md) | Return type of the flow type | +| `referencedDataTypes` | [`DataTypeConnection!`](../object/datatypeconnection.md) | The data types that are referenced in this flow type | +| `returnType` | [`String`](../scalar/string.md) | Return type of the flow type | | `runtime` | [`Runtime!`](../object/runtime.md) | Runtime of the flow type | | `updatedAt` | [`Time!`](../scalar/time.md) | Time when this FlowType was last updated | diff --git a/docs/graphql/object/flowtypesetting.md b/docs/graphql/object/flowtypesetting.md index 3bc704b0..23c7ef64 100644 --- a/docs/graphql/object/flowtypesetting.md +++ b/docs/graphql/object/flowtypesetting.md @@ -9,12 +9,13 @@ Represents a flow type setting | Name | Type | Description | |------|------|-------------| | `createdAt` | [`Time!`](../scalar/time.md) | Time when this FlowTypeSetting was created | -| `dataType` | [`DataType`](../object/datatype.md) | Data type of the flow type setting | | `descriptions` | [`[Translation!]!`](../object/translation.md) | Descriptions of the flow type setting | | `flowType` | [`FlowType`](../object/flowtype.md) | Flow type of the flow type setting | | `id` | [`FlowTypeSettingID!`](../scalar/flowtypesettingid.md) | Global ID of this FlowTypeSetting | | `identifier` | [`String!`](../scalar/string.md) | Identifier of the flow type setting | | `names` | [`[Translation!]!`](../object/translation.md) | Names of the flow type setting | +| `referencedDataTypes` | [`DataTypeConnection!`](../object/datatypeconnection.md) | The data types that are referenced in this flow type setting | +| `type` | [`String!`](../scalar/string.md) | Type of the flow type setting | | `unique` | [`Boolean!`](../scalar/boolean.md) | Unique status of the flow type setting | | `updatedAt` | [`Time!`](../scalar/time.md) | Time when this FlowTypeSetting was last updated | diff --git a/docs/graphql/object/flowvalidationerror.md b/docs/graphql/object/flowvalidationerror.md deleted file mode 100644 index 6c34e918..00000000 --- a/docs/graphql/object/flowvalidationerror.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: FlowValidationError ---- - -Represents a flow validation error - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `details` | [`ActiveModelError`](../object/activemodelerror.md) | Additional details about the validation error | -| `errorCode` | [`FlowValidationErrorCodeEnum!`](../enum/flowvalidationerrorcodeenum.md) | The code representing the validation error type | -| `severity` | [`FlowValidationSeverityEnum!`](../enum/flowvalidationseverityenum.md) | The severity of the validation error | - diff --git a/docs/graphql/object/functiondefinition.md b/docs/graphql/object/functiondefinition.md index d1ad440f..fc8f414e 100644 --- a/docs/graphql/object/functiondefinition.md +++ b/docs/graphql/object/functiondefinition.md @@ -10,18 +10,17 @@ Represents a function definition |------|------|-------------| | `aliases` | [`[Translation!]`](../object/translation.md) | Name of the function | | `createdAt` | [`Time!`](../scalar/time.md) | Time when this FunctionDefinition was created | -| `dataTypeIdentifiers` | [`DataTypeIdentifierConnection!`](../object/datatypeidentifierconnection.md) | All data type identifiers used within this Node Function | | `deprecationMessages` | [`[Translation!]`](../object/translation.md) | Deprecation message of the function | | `descriptions` | [`[Translation!]`](../object/translation.md) | Description of the function | | `displayMessages` | [`[Translation!]`](../object/translation.md) | Display message of the function | | `documentations` | [`[Translation!]`](../object/translation.md) | Documentation of the function | -| `genericKeys` | [`[String!]`](../scalar/string.md) | Generic keys of the function | | `id` | [`FunctionDefinitionID!`](../scalar/functiondefinitionid.md) | Global ID of this FunctionDefinition | | `identifier` | [`String!`](../scalar/string.md) | Identifier of the function | | `names` | [`[Translation!]`](../object/translation.md) | Name of the function | | `parameterDefinitions` | [`ParameterDefinitionConnection`](../object/parameterdefinitionconnection.md) | Parameters of the function | -| `returnType` | [`DataTypeIdentifier`](../object/datatypeidentifier.md) | Return type of the function | +| `referencedDataTypes` | [`DataTypeConnection!`](../object/datatypeconnection.md) | All data types referenced within this function definition | | `runtimeFunctionDefinition` | [`RuntimeFunctionDefinition`](../object/runtimefunctiondefinition.md) | Runtime function definition | +| `signature` | [`String!`](../scalar/string.md) | Signature of the function | | `throwsError` | [`Boolean!`](../scalar/boolean.md) | Indicates if the function can throw an error | | `updatedAt` | [`Time!`](../scalar/time.md) | Time when this FunctionDefinition was last updated | diff --git a/docs/graphql/object/genericcombinationstrategy.md b/docs/graphql/object/genericcombinationstrategy.md deleted file mode 100644 index 9baff780..00000000 --- a/docs/graphql/object/genericcombinationstrategy.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: GenericCombinationStrategy ---- - -Represents a combination strategy with AND/OR logic used by a generic mapper. - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `createdAt` | [`Time!`](../scalar/time.md) | Time when this GenericCombinationStrategy was created | -| `genericMapper` | [`GenericMapper`](../object/genericmapper.md) | The associated generic mapper, if any. | -| `id` | [`GenericCombinationStrategyID!`](../scalar/genericcombinationstrategyid.md) | Global ID of this GenericCombinationStrategy | -| `type` | [`GenericCombinationStrategyType!`](../enum/genericcombinationstrategytype.md) | The combination type ('AND' or 'OR'). | -| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this GenericCombinationStrategy was last updated | - diff --git a/docs/graphql/object/genericmapper.md b/docs/graphql/object/genericmapper.md deleted file mode 100644 index f56b1276..00000000 --- a/docs/graphql/object/genericmapper.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -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 | -| `genericCombinationStrategies` | [`[GenericCombinationStrategy!]`](../object/genericcombinationstrategy.md) | Combination strategies associated with this generic mapper. | -| `id` | [`GenericMapperID!`](../scalar/genericmapperid.md) | Global ID of this GenericMapper | -| `sourceDataTypeIdentifierIds` | [`[DataTypeIdentifierID!]!`](../scalar/datatypeidentifierid.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 deleted file mode 100644 index f38effd2..00000000 --- a/docs/graphql/object/generictype.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -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. | -| `id` | [`GenericTypeID!`](../scalar/generictypeid.md) | Global ID of this GenericType | -| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this GenericType was last updated | - diff --git a/docs/graphql/object/parameterdefinition.md b/docs/graphql/object/parameterdefinition.md index f73beb10..d7f229ff 100644 --- a/docs/graphql/object/parameterdefinition.md +++ b/docs/graphql/object/parameterdefinition.md @@ -9,11 +9,11 @@ Represents a parameter definition | Name | Type | Description | |------|------|-------------| | `createdAt` | [`Time!`](../scalar/time.md) | Time when this ParameterDefinition was created | -| `dataTypeIdentifier` | [`DataTypeIdentifier`](../object/datatypeidentifier.md) | Data type of the parameter | | `descriptions` | [`[Translation!]`](../object/translation.md) | Description of the parameter | | `documentations` | [`[Translation!]`](../object/translation.md) | Documentation of the parameter | | `id` | [`ParameterDefinitionID!`](../scalar/parameterdefinitionid.md) | Global ID of this ParameterDefinition | | `identifier` | [`String!`](../scalar/string.md) | Identifier of the parameter | | `names` | [`[Translation!]`](../object/translation.md) | Name of the parameter | +| `runtimeParameterDefinition` | [`RuntimeParameterDefinition`](../object/runtimeparameterdefinition.md) | Runtime parameter definition | | `updatedAt` | [`Time!`](../scalar/time.md) | Time when this ParameterDefinition was last updated | diff --git a/docs/graphql/object/runtimefunctiondefinition.md b/docs/graphql/object/runtimefunctiondefinition.md index aceb32b9..165d1d92 100644 --- a/docs/graphql/object/runtimefunctiondefinition.md +++ b/docs/graphql/object/runtimefunctiondefinition.md @@ -12,7 +12,9 @@ Represents a runtime function definition | `functionDefinitions` | [`FunctionDefinitionConnection`](../object/functiondefinitionconnection.md) | Function definitions of the runtime function definition | | `id` | [`RuntimeFunctionDefinitionID!`](../scalar/runtimefunctiondefinitionid.md) | Global ID of this RuntimeFunctionDefinition | | `identifier` | [`String!`](../scalar/string.md) | Identifier of the runtime function definition | +| `referencedDataTypes` | [`DataTypeConnection!`](../object/datatypeconnection.md) | The data types that are referenced in this runtime function definition | | `runtime` | [`Runtime!`](../object/runtime.md) | The runtime this runtime function definition belongs to | | `runtimeParameterDefinitions` | [`RuntimeParameterDefinitionConnection`](../object/runtimeparameterdefinitionconnection.md) | Parameter definitions of the runtime function definition | +| `signature` | [`String!`](../scalar/string.md) | Signature of the runtime function definition | | `updatedAt` | [`Time!`](../scalar/time.md) | Time when this RuntimeFunctionDefinition was last updated | 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/docs/graphql/scalar/genericcombinationstrategyid.md b/docs/graphql/scalar/genericcombinationstrategyid.md deleted file mode 100644 index 28d8d28d..00000000 --- a/docs/graphql/scalar/genericcombinationstrategyid.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: GenericCombinationStrategyID ---- - -A unique identifier for all GenericCombinationStrategy entities of the application diff --git a/docs/graphql/scalar/genericmapperid.md b/docs/graphql/scalar/genericmapperid.md deleted file mode 100644 index 988a99e5..00000000 --- a/docs/graphql/scalar/genericmapperid.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: GenericMapperID ---- - -A unique identifier for all GenericMapper entities of the application diff --git a/docs/graphql/scalar/generictypeid.md b/docs/graphql/scalar/generictypeid.md deleted file mode 100644 index 591c9934..00000000 --- a/docs/graphql/scalar/generictypeid.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: GenericTypeID ---- - -A unique identifier for all GenericType entities of the application diff --git a/docs/graphql/union/datatyperulesconfig.md b/docs/graphql/union/datatyperulesconfig.md index d696d442..4f9f15cf 100644 --- a/docs/graphql/union/datatyperulesconfig.md +++ b/docs/graphql/union/datatyperulesconfig.md @@ -6,11 +6,5 @@ Represents a rule that can be applied to a data type. ## Possible types -- [`DataTypeRulesContainsKeyConfig`](../object/datatyperulescontainskeyconfig.md) -- [`DataTypeRulesContainsTypeConfig`](../object/datatyperulescontainstypeconfig.md) -- [`DataTypeRulesInputTypesConfig`](../object/datatyperulesinputtypesconfig.md) -- [`DataTypeRulesItemOfCollectionConfig`](../object/datatyperulesitemofcollectionconfig.md) - [`DataTypeRulesNumberRangeConfig`](../object/datatyperulesnumberrangeconfig.md) -- [`DataTypeRulesParentTypeConfig`](../object/datatyperulesparenttypeconfig.md) - [`DataTypeRulesRegexConfig`](../object/datatyperulesregexconfig.md) -- [`DataTypeRulesReturnTypeConfig`](../object/datatyperulesreturntypeconfig.md) diff --git a/docs/graphql/union/detailederror.md b/docs/graphql/union/detailederror.md index d5cd6d4c..b4382a3f 100644 --- a/docs/graphql/union/detailederror.md +++ b/docs/graphql/union/detailederror.md @@ -7,5 +7,4 @@ Represents a detailed error with either a message or an active model error ## Possible types - [`ActiveModelError`](../object/activemodelerror.md) -- [`FlowValidationError`](../object/flowvalidationerror.md) - [`MessageError`](../object/messageerror.md) diff --git a/spec/factories/data_type_data_type_links.rb b/spec/factories/data_type_data_type_links.rb new file mode 100644 index 00000000..9b689fc3 --- /dev/null +++ b/spec/factories/data_type_data_type_links.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :data_type_data_type_link do + data_type + referenced_data_type factory: :data_type + end +end diff --git a/spec/factories/data_type_identifiers.rb b/spec/factories/data_type_identifiers.rb deleted file mode 100644 index f3103216..00000000 --- a/spec/factories/data_type_identifiers.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :data_type_identifier do - generic_key { nil } - data_type { nil } - generic_type { nil } - runtime - end -end diff --git a/spec/factories/data_types.rb b/spec/factories/data_types.rb index 4cdea7d2..94f09afc 100644 --- a/spec/factories/data_types.rb +++ b/spec/factories/data_types.rb @@ -4,11 +4,9 @@ sequence(:data_type_name) { |n| "datatype#{n}" } factory :data_type do - variant { :primitive } runtime identifier { generate(:data_type_name) } - parent_type { nil } - generic_keys { [] } + type { 'string' } version { '0.0.0' } end end diff --git a/spec/factories/flow_data_type_links.rb b/spec/factories/flow_data_type_links.rb new file mode 100644 index 00000000..cef650d3 --- /dev/null +++ b/spec/factories/flow_data_type_links.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :flow_data_type_link do + flow + referenced_data_type factory: :data_type + end +end diff --git a/spec/factories/flow_type_data_type_links.rb b/spec/factories/flow_type_data_type_links.rb new file mode 100644 index 00000000..fbe94e90 --- /dev/null +++ b/spec/factories/flow_type_data_type_links.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :flow_type_data_type_link do + flow_type + referenced_data_type factory: :data_type + end +end diff --git a/spec/factories/flow_type_setting_data_type_links.rb b/spec/factories/flow_type_setting_data_type_links.rb new file mode 100644 index 00000000..ed0634f1 --- /dev/null +++ b/spec/factories/flow_type_setting_data_type_links.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :flow_type_setting_data_type_link do + flow_type_setting + referenced_data_type factory: :data_type + end +end diff --git a/spec/factories/flow_type_settings.rb b/spec/factories/flow_type_settings.rb index 51d25cec..8ccb084d 100644 --- a/spec/factories/flow_type_settings.rb +++ b/spec/factories/flow_type_settings.rb @@ -7,7 +7,7 @@ flow_type identifier { generate(:flow_type_setting_identifier) } unique { :none } - data_type + type { 'string' } default_value { '' } end end diff --git a/spec/factories/flow_types.rb b/spec/factories/flow_types.rb index 14f9ebd8..dc3a9472 100644 --- a/spec/factories/flow_types.rb +++ b/spec/factories/flow_types.rb @@ -6,12 +6,8 @@ factory :flow_type do runtime identifier { generate(:flow_type_identifier) } - input_type do - association :data_type, runtime: runtime - end - return_type do - association :data_type, runtime: runtime - end + input_type { 'string' } + return_type { 'string' } editable { false } version { '0.0.0' } end diff --git a/spec/factories/flows.rb b/spec/factories/flows.rb index 72df5c48..7da85541 100644 --- a/spec/factories/flows.rb +++ b/spec/factories/flows.rb @@ -8,8 +8,8 @@ flow_type starting_node { nil } flow_settings { [] } - input_type { nil } - return_type { nil } + input_type { 'string' } + return_type { 'string' } name { generate(:flow_name) } end end diff --git a/spec/factories/function_definitions.rb b/spec/factories/function_definitions.rb index 91ecd68e..0f68bd39 100644 --- a/spec/factories/function_definitions.rb +++ b/spec/factories/function_definitions.rb @@ -2,7 +2,6 @@ FactoryBot.define do factory :function_definition do - return_type { nil } runtime_function_definition end end diff --git a/spec/factories/generic_combination_strategies.rb b/spec/factories/generic_combination_strategies.rb deleted file mode 100644 index c59759ed..00000000 --- a/spec/factories/generic_combination_strategies.rb +++ /dev/null @@ -1,8 +0,0 @@ -# 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 deleted file mode 100644 index 0fa713d4..00000000 --- a/spec/factories/generic_mappers.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :generic_mapper do - runtime - target { nil } - sources { [] } - generic_combination_strategies { [] } - end -end diff --git a/spec/factories/generic_types.rb b/spec/factories/generic_types.rb deleted file mode 100644 index 6e7a9fdf..00000000 --- a/spec/factories/generic_types.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :generic_type do - generic_mappers { [] } - data_type - owner { data_type } - end -end diff --git a/spec/factories/parameter_definitions.rb b/spec/factories/parameter_definitions.rb index dbcc7857..4cb69880 100644 --- a/spec/factories/parameter_definitions.rb +++ b/spec/factories/parameter_definitions.rb @@ -2,11 +2,7 @@ FactoryBot.define do factory :parameter_definition do - data_type factory: :data_type_identifier - - runtime_parameter_definition do - association :runtime_parameter_definition, data_type: data_type - end + runtime_parameter_definition function_definition do association :function_definition, diff --git a/spec/factories/runtime_function_definition_data_type_links.rb b/spec/factories/runtime_function_definition_data_type_links.rb new file mode 100644 index 00000000..6bb9c08c --- /dev/null +++ b/spec/factories/runtime_function_definition_data_type_links.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :runtime_function_definition_data_type_link do + runtime_function_definition + referenced_data_type factory: :data_type + end +end diff --git a/spec/factories/runtime_function_definitions.rb b/spec/factories/runtime_function_definitions.rb index 8dee0f51..540ddec7 100644 --- a/spec/factories/runtime_function_definitions.rb +++ b/spec/factories/runtime_function_definitions.rb @@ -5,10 +5,9 @@ factory :runtime_function_definition do runtime_name { generate(:runtime_function_definition_name) } - return_type { nil } runtime - generic_keys { [] } parameters { [] } + signature { '(): undefined' } version { '0.0.0' } end end diff --git a/spec/factories/runtime_parameter_definitions.rb b/spec/factories/runtime_parameter_definitions.rb index 499eca4f..dd8e2c43 100644 --- a/spec/factories/runtime_parameter_definitions.rb +++ b/spec/factories/runtime_parameter_definitions.rb @@ -5,7 +5,6 @@ factory :runtime_parameter_definition do runtime_function_definition - data_type factory: %i[data_type_identifier] runtime_name { generate(:runtime_parameter_definition_name) } end end diff --git a/spec/finders/data_type_identifiers_finder_spec.rb b/spec/finders/data_type_identifiers_finder_spec.rb deleted file mode 100644 index a61d3d87..00000000 --- a/spec/finders/data_type_identifiers_finder_spec.rb +++ /dev/null @@ -1,292 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe DataTypeIdentifiersFinder do - # rubocop:disable RSpec/IndexedLet -- this is a finder and we need to setup multiple objects of the same time - # rubocop:disable RSpec/LetSetup -- a finder spec needs more objects than referenced in the spec to test that they are excluded in the result - describe '#execute' do - let(:runtime) { create(:runtime) } - let(:other_runtime) { create(:runtime) } - - let!(:data_type1) { create(:data_type, runtime: runtime) } - let!(:data_type2) { create(:data_type, runtime: runtime) } - let!(:data_type3) { create(:data_type, runtime: other_runtime) } - - let!(:data_type_identifier1) do - create(:data_type_identifier, runtime: runtime, data_type: data_type1) - end - let!(:data_type_identifier2) do - create(:data_type_identifier, runtime: runtime, data_type: data_type2) - end - let!(:data_type_identifier3) do - create(:data_type_identifier, runtime: other_runtime, data_type: data_type3) - end - - context 'without any parameters' do - it 'returns all data type identifiers' do - finder = described_class.new({}) - result = finder.execute - - expect(result).to contain_exactly(data_type_identifier1, data_type_identifier2, data_type_identifier3) - end - end - - context 'with runtime parameter' do - it 'filters data type identifiers by runtime' do - finder = described_class.new({ runtime: runtime }) - result = finder.execute - - expect(result).to contain_exactly(data_type_identifier1, data_type_identifier2) - expect(result).not_to include(data_type_identifier3) - end - - it 'returns empty result when runtime has no data type identifiers' do - empty_runtime = create(:runtime) - finder = described_class.new({ runtime: empty_runtime }) - result = finder.execute - - expect(result).to be_empty - end - end - - context 'with function_definition parameter' do - let(:return_data_type) { create(:data_type) } - let(:param_data_type1) { create(:data_type) } - let(:param_data_type2) { create(:data_type) } - let(:unrelated_data_type) { create(:data_type) } - - let(:return_type) do - create(:data_type_identifier, data_type: return_data_type) - end - let(:param_type1) do - create(:data_type_identifier, data_type: param_data_type1) - end - let(:param_type2) do - create(:data_type_identifier, data_type: param_data_type2) - end - let(:unrelated_type) do - create(:data_type_identifier, data_type: unrelated_data_type) - end - - let(:function_definition) do - create(:function_definition, return_type_id: return_type.id) - end - - let!(:parameter_def1) do - create(:parameter_definition, - function_definition: function_definition, - runtime_parameter_definition: create( - :runtime_parameter_definition, - runtime_function_definition: function_definition.runtime_function_definition, - data_type: param_type1 - ), - data_type: param_type1) - end - - let!(:parameter_def2) do - create(:parameter_definition, - function_definition: function_definition, - runtime_parameter_definition: create( - :runtime_parameter_definition, - runtime_function_definition: function_definition.runtime_function_definition, - data_type: param_type2 - ), - data_type: param_type2) - end - - it 'returns data type identifiers related to function definition' do - finder = described_class.new({ function_definition: function_definition }) - result = finder.execute - - expect(result).to contain_exactly(return_type, param_type1, param_type2) - expect(result).not_to include(unrelated_type) - end - - it 'includes return type when function has return type' do - finder = described_class.new({ function_definition: function_definition }) - result = finder.execute - - expect(result).to include(return_type) - end - - it 'includes parameter types when function has parameters' do - finder = described_class.new({ function_definition: function_definition }) - result = finder.execute - - expect(result).to include(param_type1, param_type2) - end - - it 'returns empty result when function definition has no types' do - empty_function = create(:function_definition, return_type_id: nil) - finder = described_class.new({ function_definition: empty_function }) - result = finder.execute - - expect(result).to be_empty - end - end - - context 'with expand_recursively parameter' do - let!(:data_type_identifier_in_contains_type_rule) do - create(:data_type_identifier, data_type: data_type3, runtime: runtime).tap do |dti| - create( - :data_type_rule, - data_type: data_type1, - variant: :contains_type, - config: { - data_type_identifier: { - data_type_identifier: data_type3.identifier, - }, - data_type_identifier_id: dti.id, - } - ) - end - end - - let!(:data_type_identifier_in_input_types_rule) do - create(:data_type_identifier, data_type: data_type3, runtime: runtime).tap do |dti| - create( - :data_type_rule, - data_type: data_type1, - variant: :input_types, - config: { - input_types: [ - { - data_type_identifier: { - data_type_identifier: data_type3.identifier, - }, - data_type_identifier_id: dti.id, - input_identifier: 'something', - } - ], - - } - ) - end - end - - let!(:data_type_identifier_as_parent_type) do - create(:data_type_identifier, data_type: data_type3, runtime: runtime).tap do |dti| - data_type1.parent_type = dti - data_type1.save! - end - end - - let!(:data_type_identifier_in_generic_mapper_source) do - create(:data_type_identifier, data_type: data_type1, runtime: runtime) - end - - let!(:second_data_type_identifier_in_generic_mapper_source) do - create(:data_type_identifier, data_type: data_type2, runtime: runtime) - end - - let!(:data_type_identifier_with_generic_mapper) do - gm = create(:generic_mapper, target: 'A', sources: [data_type_identifier_in_generic_mapper_source]) - gt = create(:generic_type, generic_mappers: [gm]) - create(:data_type_identifier, generic_type: gt, runtime: runtime) - end - - let!(:second_data_type_identifier_with_generic_mapper) do - gm = create(:generic_mapper, target: 'B', sources: [second_data_type_identifier_in_generic_mapper_source]) - gt = create(:generic_type, generic_mappers: [gm]) - create(:data_type_identifier, generic_type: gt, runtime: runtime) - end - - let!(:data_type_identifier_with_nested_generic_mapper) do - gm = create(:generic_mapper, target: 'A', sources: [data_type_identifier_with_generic_mapper]) - gt = create(:generic_type, generic_mappers: [gm]) - create(:data_type_identifier, generic_type: gt, runtime: runtime) - end - - it 'recursively expands data type identifiers through multiple levels' do - finder = described_class.new({ expand_recursively: true }) - allow(finder).to receive(:base_scope).and_return( - DataTypeIdentifier.where(id: data_type_identifier_with_nested_generic_mapper.id) - ) - - result = finder.execute - - expect(result.map(&:id)).to contain_exactly( - data_type_identifier_with_nested_generic_mapper.id, - data_type_identifier_with_generic_mapper.id, - data_type_identifier_in_generic_mapper_source.id, - data_type_identifier_in_contains_type_rule.id, - data_type_identifier_in_input_types_rule.id, - data_type_identifier_as_parent_type.id - ) - end - - it 'does not expand when expand_recursively is false' do - finder = described_class.new({ expand_recursively: false }) - allow(finder).to receive(:base_scope).and_return( - DataTypeIdentifier.where(id: data_type_identifier_with_nested_generic_mapper.id) - ) - - result = finder.execute - - expect(result.map(&:id)).to contain_exactly(data_type_identifier_with_nested_generic_mapper.id) - end - - it 'does not expand when expand_recursively is not provided' do - finder = described_class.new({}) - allow(finder).to receive(:base_scope).and_return( - DataTypeIdentifier.where(id: data_type_identifier_with_nested_generic_mapper.id) - ) - - result = finder.execute - - expect(result.map(&:id)).to contain_exactly(data_type_identifier_with_nested_generic_mapper.id) - end - - it 'handles identifiers with no children' do - leaf_data_type = create(:data_type) - leaf_identifier = create(:data_type_identifier, data_type: leaf_data_type) - - finder = described_class.new({ expand_recursively: true }) - allow(finder).to receive(:base_scope).and_return( - DataTypeIdentifier.where(id: leaf_identifier.id) - ) - - result = finder.execute - - expect(result.map(&:id)).to contain_exactly(leaf_identifier.id) - end - - it 'orders results by id' do - finder = described_class.new({ expand_recursively: true }) - allow(finder).to receive(:base_scope).and_return( - DataTypeIdentifier.where(id: data_type_identifier_with_nested_generic_mapper.id) - ) - - result = finder.execute - - expect(result.map(&:id)).to eq(result.map(&:id).sort) - end - - it 'handles multiple starting identifiers' do - finder = described_class.new({ expand_recursively: true }) - allow(finder).to receive(:base_scope).and_return( - DataTypeIdentifier.where(id: [ - data_type_identifier_with_nested_generic_mapper.id, - second_data_type_identifier_with_generic_mapper.id - ]) - ) - - result = finder.execute - - expect(result.map(&:id)).to contain_exactly( - data_type_identifier_with_nested_generic_mapper.id, - second_data_type_identifier_with_generic_mapper.id, - data_type_identifier_with_generic_mapper.id, - second_data_type_identifier_in_generic_mapper_source.id, - data_type_identifier_in_generic_mapper_source.id, - data_type_identifier_in_contains_type_rule.id, - data_type_identifier_in_input_types_rule.id, - data_type_identifier_as_parent_type.id - ) - end - end - end - # rubocop:enable RSpec/LetSetup - # rubocop:enable RSpec/IndexedLet -end diff --git a/spec/finders/data_types_finder_spec.rb b/spec/finders/data_types_finder_spec.rb new file mode 100644 index 00000000..83c884cb --- /dev/null +++ b/spec/finders/data_types_finder_spec.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe DataTypesFinder do + # rubocop:disable RSpec/IndexedLet -- a finder needs to set up a lot of data with the same type + describe '#execute' do + let(:runtime) { create(:runtime) } + let!(:data_type1) { create(:data_type, runtime: runtime) } + let!(:data_type2) { create(:data_type, runtime: runtime) } + let!(:data_type3) { create(:data_type, runtime: runtime) } + let!(:unrelated_data_type) { create(:data_type, runtime: runtime) } + + context 'without any parameters' do + it 'returns all data types' do + finder = described_class.new({}) + result = finder.execute + + expect(result).to include(data_type1, data_type2, data_type3, unrelated_data_type) + end + end + + context 'with data_type parameter' do + before do + create(:data_type_data_type_link, data_type: data_type1, referenced_data_type: data_type2) + create(:data_type_data_type_link, data_type: data_type1, referenced_data_type: data_type3) + end + + it 'returns referenced data types' do + finder = described_class.new({ data_type: data_type1 }) + result = finder.execute + + expect(result).to contain_exactly(data_type2, data_type3) + end + end + + context 'with runtime_function_definition parameter' do + let(:runtime_function_definition) { create(:runtime_function_definition, runtime: runtime) } + + before do + create(:runtime_function_definition_data_type_link, + runtime_function_definition: runtime_function_definition, + referenced_data_type: data_type1) + create(:runtime_function_definition_data_type_link, + runtime_function_definition: runtime_function_definition, + referenced_data_type: data_type2) + end + + it 'returns referenced data types' do + finder = described_class.new({ runtime_function_definition: runtime_function_definition }) + result = finder.execute + + expect(result).to contain_exactly(data_type1, data_type2) + end + end + + context 'with flow_type_setting parameter' do + let(:flow_type) { create(:flow_type, runtime: runtime) } + let(:flow_type_setting) { create(:flow_type_setting, flow_type: flow_type) } + + before do + create(:flow_type_setting_data_type_link, + flow_type_setting: flow_type_setting, + referenced_data_type: data_type1) + end + + it 'returns referenced data types' do + finder = described_class.new({ flow_type_setting: flow_type_setting }) + result = finder.execute + + expect(result).to contain_exactly(data_type1) + end + end + + context 'with flow_type parameter' do + let(:flow_type) { create(:flow_type, runtime: runtime) } + + before do + create(:flow_type_data_type_link, flow_type: flow_type, referenced_data_type: data_type1) + create(:flow_type_data_type_link, flow_type: flow_type, referenced_data_type: data_type2) + end + + it 'returns referenced data types' do + finder = described_class.new({ flow_type: flow_type }) + result = finder.execute + + expect(result).to contain_exactly(data_type1, data_type2) + end + end + + context 'with flow parameter' do + let(:project) { create(:namespace_project) } + let(:flow) { create(:flow, project: project) } + + before do + create(:flow_data_type_link, flow: flow, referenced_data_type: data_type1) + create(:flow_data_type_link, flow: flow, referenced_data_type: data_type3) + end + + it 'returns referenced data types' do + finder = described_class.new({ flow: flow }) + result = finder.execute + + expect(result).to contain_exactly(data_type1, data_type3) + end + end + + context 'with expand_recursively parameter' do + let!(:data_type4) { create(:data_type, runtime: runtime) } + let!(:data_type5) { create(:data_type, runtime: runtime) } + + before do + create(:data_type_data_type_link, data_type: data_type1, referenced_data_type: data_type2) + create(:data_type_data_type_link, data_type: data_type2, referenced_data_type: data_type3) + create(:data_type_data_type_link, data_type: data_type3, referenced_data_type: data_type4) + end + + it 'recursively expands data types through multiple levels' do + finder = described_class.new({ data_type: data_type1, expand_recursively: true }) + result = finder.execute + + expect(result).to contain_exactly(data_type2, data_type3, data_type4) + end + + it 'does not expand when expand_recursively is false' do + finder = described_class.new({ data_type: data_type1, expand_recursively: false }) + result = finder.execute + + expect(result).to contain_exactly(data_type2) + end + + it 'does not expand when expand_recursively is not provided' do + finder = described_class.new({ data_type: data_type1 }) + result = finder.execute + + expect(result).to contain_exactly(data_type2) + end + + it 'handles data types with no children' do + finder = described_class.new({ data_type: data_type5, expand_recursively: true }) + result = finder.execute + + expect(result).to be_empty + end + + it 'orders results by id' do + finder = described_class.new({ data_type: data_type1, expand_recursively: true }) + result = finder.execute + + expect(result.map(&:id)).to eq(result.map(&:id).sort) + end + end + end + # rubocop:enable RSpec/IndexedLet +end diff --git a/spec/graphql/types/data_type_type_spec.rb b/spec/graphql/types/data_type_type_spec.rb index 7620640c..b01ea438 100644 --- a/spec/graphql/types/data_type_type_spec.rb +++ b/spec/graphql/types/data_type_type_spec.rb @@ -6,15 +6,15 @@ let(:fields) do %w[ identifier - variant + type id rules name display_messages aliases runtime + referenced_data_types generic_keys - data_type_identifiers createdAt updatedAt ] diff --git a/spec/graphql/types/flow_type_setting_spec.rb b/spec/graphql/types/flow_type_setting_spec.rb index db37085f..83e9fcc2 100644 --- a/spec/graphql/types/flow_type_setting_spec.rb +++ b/spec/graphql/types/flow_type_setting_spec.rb @@ -8,10 +8,11 @@ identifier unique flow_type - data_type + type names descriptions id + referenced_data_types created_at updated_at ] diff --git a/spec/graphql/types/flow_type_type_spec.rb b/spec/graphql/types/flow_type_type_spec.rb index c2a3f6c2..8749c8fc 100644 --- a/spec/graphql/types/flow_type_type_spec.rb +++ b/spec/graphql/types/flow_type_type_spec.rb @@ -15,6 +15,7 @@ aliases descriptions runtime + referenced_data_types id created_at updated_at diff --git a/spec/graphql/types/function_definition_type_spec.rb b/spec/graphql/types/function_definition_type_spec.rb index 7b01aefa..70264fd8 100644 --- a/spec/graphql/types/function_definition_type_spec.rb +++ b/spec/graphql/types/function_definition_type_spec.rb @@ -7,7 +7,6 @@ %w[ id identifier - returnType parameterDefinitions names displayMessages @@ -16,9 +15,9 @@ documentations deprecationMessages runtimeFunctionDefinition - genericKeys + signature throwsError - dataTypeIdentifiers + referencedDataTypes createdAt updatedAt ] diff --git a/spec/graphql/types/parameter_definition_type_spec.rb b/spec/graphql/types/parameter_definition_type_spec.rb index f22fb8fc..11f9fb7b 100644 --- a/spec/graphql/types/parameter_definition_type_spec.rb +++ b/spec/graphql/types/parameter_definition_type_spec.rb @@ -7,10 +7,10 @@ %w[ id identifier - dataTypeIdentifier descriptions names documentations + runtimeParameterDefinition createdAt updatedAt ] diff --git a/spec/graphql/types/runtime_function_definition_type_spec.rb b/spec/graphql/types/runtime_function_definition_type_spec.rb index 5769f8c0..e1cd7a9d 100644 --- a/spec/graphql/types/runtime_function_definition_type_spec.rb +++ b/spec/graphql/types/runtime_function_definition_type_spec.rb @@ -10,6 +10,8 @@ functionDefinitions runtimeParameterDefinitions runtime + signature + referencedDataTypes createdAt updatedAt ] diff --git a/spec/models/data_type_data_type_link_spec.rb b/spec/models/data_type_data_type_link_spec.rb new file mode 100644 index 00000000..344c02fb --- /dev/null +++ b/spec/models/data_type_data_type_link_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe DataTypeDataTypeLink do + subject { create(:data_type_data_type_link) } + + describe 'associations' do + it { is_expected.to belong_to(:data_type).inverse_of(:data_type_data_type_links) } + + it { is_expected.to belong_to(:referenced_data_type).class_name('DataType') } + end +end diff --git a/spec/models/data_type_identifier_spec.rb b/spec/models/data_type_identifier_spec.rb deleted file mode 100644 index d470037b..00000000 --- a/spec/models/data_type_identifier_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# 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 belong_to(:runtime) } - it { is_expected.to belong_to(: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 - 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 - 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/data_type_rule_spec.rb b/spec/models/data_type_rule_spec.rb index ea218d66..068699cd 100644 --- a/spec/models/data_type_rule_spec.rb +++ b/spec/models/data_type_rule_spec.rb @@ -12,81 +12,6 @@ describe 'validations' do it { is_expected.to allow_values(*described_class::VARIANTS.keys).for(:variant) } - context 'when variant is contains_key' do - before { rule.variant = :contains_key } - - context 'when validating config with DataTypeContainsKeyRuleConfig schema' do - it 'is correct' do - rule.config = { - key: 'id', - data_type_identifier: { - data_type_identifier: 'User', - }, - data_type_identifier_id: 1, - } - is_expected.to be_valid - end - - it 'when its incorrect' do - rule.config = { - data_type_identifier: { - data_type_identifier: 'User', - }, - } - is_expected.not_to be_valid - end - end - end - - context 'when variant is contains_type' do - before { rule.variant = :contains_type } - - 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_id: 1, - } - is_expected.to be_valid - end - end - - context 'when its incorrect' do - it 'when validating config with DataTypeContainsTypeRuleConfig schema' do - rule.config = { - key: 'id', - } - is_expected.not_to be_valid - end - end - end - - context 'when variant is item_of_collection' do - before { rule.variant = :item_of_collection } - - context 'when validating config with DataTypeItemOfCollectionRuleConfig schema' do - it 'is correct' do - rule.config = { - items: [ - ['a', 1, true, { key: 'value' }], - { test: 2 }, - [] - ], - } - is_expected.to be_valid - end - - it 'when its incorrect' do - rule.config = { - key: 'id', - } - is_expected.not_to be_valid - end - end - end - context 'when variant is number_range' do before { rule.variant = :number_range } diff --git a/spec/models/data_type_spec.rb b/spec/models/data_type_spec.rb index 43c8d963..b9812290 100644 --- a/spec/models/data_type_spec.rb +++ b/spec/models/data_type_spec.rb @@ -6,56 +6,21 @@ subject(:data_type) { create(:data_type) } describe 'associations' do - 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(:names).class_name('Translation') } it { is_expected.to have_many(:aliases).class_name('Translation') } it { is_expected.to have_many(:display_messages).class_name('Translation') } it { is_expected.to have_many(:rules).class_name('DataTypeRule').inverse_of(:data_type) } - end - - 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)) - - dt1.parent_type = create(:data_type_identifier, data_type: dt2) + it { is_expected.to have_many(:data_type_data_type_links).inverse_of(:data_type) } - expect(dt1).not_to be_valid - expect(dt1.errors.added?(:parent_type, :recursion)).to be(true) + it do + is_expected.to have_many(:referenced_data_types).through(:data_type_data_type_links).source(:referenced_data_type) end + end - it 'detects recursions over multiple levels' do - dt1 = create(:data_type) - 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 = create(:data_type_identifier, data_type: dt4) - - expect(dt1.valid?).to be(false) - expect(dt1.errors.added?(:parent_type, :recursion)).to be(true) - end - - it 'detects direct recursions' do - dt1 = create(:data_type) - 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) - end + describe 'validations' do + it { is_expected.to validate_presence_of(:type) } + it { is_expected.to validate_length_of(:type).is_at_most(2000) } describe '#validate_version' do it 'adds an error if version is blank' do diff --git a/spec/models/flow_data_type_link_spec.rb b/spec/models/flow_data_type_link_spec.rb new file mode 100644 index 00000000..c017a289 --- /dev/null +++ b/spec/models/flow_data_type_link_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe FlowDataTypeLink do + subject { create(:flow_data_type_link) } + + describe 'associations' do + it { is_expected.to belong_to(:flow).inverse_of(:flow_data_type_links) } + + it { is_expected.to belong_to(:referenced_data_type).class_name('DataType') } + end +end diff --git a/spec/models/flow_spec.rb b/spec/models/flow_spec.rb index 03900d11..278788e9 100644 --- a/spec/models/flow_spec.rb +++ b/spec/models/flow_spec.rb @@ -9,16 +9,21 @@ 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').optional } - it { is_expected.to belong_to(:input_type).class_name('DataType').optional } - it { is_expected.to belong_to(:return_type).class_name('DataType').optional } it { is_expected.to have_many(:flow_settings) } it { is_expected.to have_many(:node_functions) } + + it { is_expected.to have_many(:flow_data_type_links).inverse_of(:flow) } + + it { is_expected.to have_many(:referenced_data_types).through(:flow_data_type_links).source(:referenced_data_type) } end describe 'validations' do it { is_expected.to validate_presence_of(:name) } it { is_expected.to validate_uniqueness_of(:name).case_insensitive.scoped_to(:project_id) } + + it { is_expected.to validate_length_of(:input_type).is_at_most(2000) } + it { is_expected.to validate_length_of(:return_type).is_at_most(2000) } end describe '#to_grpc' do @@ -26,6 +31,8 @@ create( :flow, flow_type: create(:flow_type, identifier: 'HTTP'), + input_type: 'string', + return_type: 'number', flow_settings: [ create( :flow_setting, @@ -42,17 +49,12 @@ fd = create(:function_definition, runtime_function_definition: rfd) rpd = create( :runtime_parameter_definition, - runtime_function_definition: rfd, - data_type: create( - :data_type_identifier, - generic_key: 'T' - ) + runtime_function_definition: rfd ) pd = create( :parameter_definition, function_definition: fd, - runtime_parameter_definition: rpd, - data_type: rpd.data_type + runtime_parameter_definition: rpd ) func = create( @@ -82,8 +84,8 @@ project_id: flow.project.id, project_slug: flow.project.slug, type: flow.flow_type.identifier, - input_type: {}, - return_type: {}, + input_type: flow.input_type, + return_type: flow.return_type, node_functions: [ { database_id: starting_node.id, diff --git a/spec/models/flow_type_data_type_link_spec.rb b/spec/models/flow_type_data_type_link_spec.rb new file mode 100644 index 00000000..ba9ca473 --- /dev/null +++ b/spec/models/flow_type_data_type_link_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe FlowTypeDataTypeLink do + subject { create(:flow_type_data_type_link) } + + describe 'associations' do + it { is_expected.to belong_to(:flow_type).inverse_of(:flow_type_data_type_links) } + + it { is_expected.to belong_to(:referenced_data_type).class_name('DataType') } + end +end diff --git a/spec/models/flow_type_setting_data_type_link_spec.rb b/spec/models/flow_type_setting_data_type_link_spec.rb new file mode 100644 index 00000000..8a9bde06 --- /dev/null +++ b/spec/models/flow_type_setting_data_type_link_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe FlowTypeSettingDataTypeLink do + subject { create(:flow_type_setting_data_type_link) } + + describe 'associations' do + it { is_expected.to belong_to(:flow_type_setting).inverse_of(:flow_type_setting_data_type_links) } + + it { is_expected.to belong_to(:referenced_data_type).class_name('DataType') } + end +end diff --git a/spec/models/flow_type_setting_spec.rb b/spec/models/flow_type_setting_spec.rb index dc84d887..af03312a 100644 --- a/spec/models/flow_type_setting_spec.rb +++ b/spec/models/flow_type_setting_spec.rb @@ -7,9 +7,16 @@ describe 'associations' do it { is_expected.to belong_to(:flow_type).inverse_of(:flow_type_settings) } - it { is_expected.to belong_to(:data_type) } it { is_expected.to have_many(:names).class_name('Translation') } it { is_expected.to have_many(:descriptions).class_name('Translation') } + + it { is_expected.to have_many(:flow_type_setting_data_type_links).inverse_of(:flow_type_setting) } + + it do + is_expected.to have_many(:referenced_data_types) + .through(:flow_type_setting_data_type_links) + .source(:referenced_data_type) + end end describe 'validations' do @@ -17,5 +24,8 @@ it { is_expected.to validate_uniqueness_of(:identifier).scoped_to(:flow_type_id) } it { is_expected.to allow_values(:none, :project, 'none', 'project').for(:unique) } it { is_expected.not_to allow_value(:unknown, 'unknown', 0).for(:unique) } + + it { is_expected.to validate_presence_of(:type) } + it { is_expected.to validate_length_of(:type).is_at_most(2000) } end end diff --git a/spec/models/flow_type_spec.rb b/spec/models/flow_type_spec.rb index d8962d3d..99b8b439 100644 --- a/spec/models/flow_type_spec.rb +++ b/spec/models/flow_type_spec.rb @@ -7,14 +7,18 @@ describe 'associations' do it { is_expected.to belong_to(:runtime) } - it { is_expected.to belong_to(:input_type).class_name('DataType').optional } - it { is_expected.to belong_to(:return_type).class_name('DataType').optional } it { is_expected.to have_many(:flow_type_settings).inverse_of(:flow_type) } it { is_expected.to have_many(:aliases).class_name('Translation') } it { is_expected.to have_many(:display_messages).class_name('Translation') } it { is_expected.to have_many(:descriptions).class_name('Translation') } it { is_expected.to have_many(:documentations).class_name('Translation') } it { is_expected.to have_many(:names).class_name('Translation') } + + it { is_expected.to have_many(:flow_type_data_type_links).inverse_of(:flow_type) } + + it do + is_expected.to have_many(:referenced_data_types).through(:flow_type_data_type_links).source(:referenced_data_type) + end end describe 'validations' do @@ -22,6 +26,9 @@ it { is_expected.to validate_uniqueness_of(:identifier).scoped_to(:runtime_id) } it { is_expected.to allow_values(true, false).for(:editable) } + it { is_expected.to validate_length_of(:input_type).is_at_most(2000) } + it { is_expected.to validate_length_of(:return_type).is_at_most(2000) } + describe '#validate_version' do it 'adds an error if version is blank' do flow_type.version = '' diff --git a/spec/models/function_definition_spec.rb b/spec/models/function_definition_spec.rb index 66bb6e06..9a15c964 100644 --- a/spec/models/function_definition_spec.rb +++ b/spec/models/function_definition_spec.rb @@ -7,7 +7,6 @@ describe 'associations' do it { is_expected.to belong_to(:runtime_function_definition) } - 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/generic_combination_strategy_spec.rb b/spec/models/generic_combination_strategy_spec.rb deleted file mode 100644 index 3b9e19c2..00000000 --- a/spec/models/generic_combination_strategy_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe GenericCombinationStrategy do - describe 'associations' do - it { is_expected.to belong_to(:generic_mapper).optional } - 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 deleted file mode 100644 index b2481b8f..00000000 --- a/spec/models/generic_mapper_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -# 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).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(:generic_combination_strategies) - .class_name('GenericCombinationStrategy').inverse_of(:generic_mapper) - } - end -end diff --git a/spec/models/generic_type_spec.rb b/spec/models/generic_type_spec.rb deleted file mode 100644 index 9254edf4..00000000 --- a/spec/models/generic_type_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -# 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) } - it { is_expected.to have_many(:generic_mappers) } - end -end diff --git a/spec/models/node_function_spec.rb b/spec/models/node_function_spec.rb index fde30735..16097a26 100644 --- a/spec/models/node_function_spec.rb +++ b/spec/models/node_function_spec.rb @@ -17,13 +17,6 @@ describe '#ordered_parameters' do let(:runtime) { create(:runtime) } - let(:data_type_identifier) do - create( - :data_type_identifier, - data_type: create(:data_type, runtime: runtime) - ) - end - let(:runtime_function_definition) do create( :runtime_function_definition, @@ -32,22 +25,19 @@ rfd.parameters << create( :runtime_parameter_definition, runtime_function_definition: rfd, - runtime_name: 'param1', - data_type: data_type_identifier + runtime_name: 'param1' ) rfd.parameters << create( :runtime_parameter_definition, runtime_function_definition: rfd, - runtime_name: 'param2', - data_type: data_type_identifier + runtime_name: 'param2' ) rfd.parameters << create( :runtime_parameter_definition, runtime_function_definition: rfd, - runtime_name: 'param3', - data_type: data_type_identifier + runtime_name: 'param3' ) end end @@ -69,7 +59,6 @@ node_function: node, parameter_definition: create( :parameter_definition, - data_type: data_type_identifier, runtime_parameter_definition: runtime_function_definition.parameters[1] ) ) @@ -78,7 +67,6 @@ node_function: node, parameter_definition: create( :parameter_definition, - data_type: data_type_identifier, runtime_parameter_definition: runtime_function_definition.parameters[2] ) ) @@ -87,7 +75,6 @@ node_function: node, parameter_definition: create( :parameter_definition, - data_type: data_type_identifier, runtime_parameter_definition: runtime_function_definition.parameters[0] ) ) diff --git a/spec/models/node_parameter_spec.rb b/spec/models/node_parameter_spec.rb index 48d80194..88791197 100644 --- a/spec/models/node_parameter_spec.rb +++ b/spec/models/node_parameter_spec.rb @@ -4,13 +4,7 @@ RSpec.describe NodeParameter do subject do - create( - :node_parameter, - parameter_definition: create( - :parameter_definition, - data_type: create(:data_type_identifier, data_type: create(:data_type)) - ) - ) + create(:node_parameter) end describe 'associations' do @@ -30,14 +24,7 @@ :node_parameter, literal_value: 1, reference_value: create(:reference_value), - function_value: nil, - parameter_definition: create( - :parameter_definition, - data_type: create( - :data_type_identifier, - data_type: create(:data_type) - ) - ) + function_value: nil ) expect(param).not_to be_valid expect(param.errors[:value]) @@ -49,14 +36,7 @@ :node_parameter, literal_value: nil, reference_value: nil, - function_value: nil, - parameter_definition: create( - :parameter_definition, - data_type: create( - :data_type_identifier, - data_type: create(:data_type) - ) - ) + function_value: nil ) expect(param).to be_valid end diff --git a/spec/models/parameter_definition_spec.rb b/spec/models/parameter_definition_spec.rb index 812cf537..d12a3575 100644 --- a/spec/models/parameter_definition_spec.rb +++ b/spec/models/parameter_definition_spec.rb @@ -3,17 +3,10 @@ require 'rails_helper' RSpec.describe ParameterDefinition do - 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') } + subject { create(:parameter_definition) } describe 'associations' do it { is_expected.to belong_to(:runtime_parameter_definition) } - it { is_expected.to belong_to(:data_type) } 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_function_definition_data_type_link_spec.rb b/spec/models/runtime_function_definition_data_type_link_spec.rb new file mode 100644 index 00000000..ddac1d57 --- /dev/null +++ b/spec/models/runtime_function_definition_data_type_link_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe RuntimeFunctionDefinitionDataTypeLink do + subject { create(:runtime_function_definition_data_type_link) } + + describe 'associations' do + it do + is_expected.to belong_to(:runtime_function_definition).inverse_of(:runtime_function_definition_data_type_links) + end + + it { is_expected.to belong_to(:referenced_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 170da90b..3b2bed95 100644 --- a/spec/models/runtime_function_definition_spec.rb +++ b/spec/models/runtime_function_definition_spec.rb @@ -12,17 +12,8 @@ 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 + it { is_expected.to validate_presence_of(:signature) } + it { is_expected.to validate_length_of(:signature).is_at_most(500) } describe '#validate_version' do it 'adds an error if version is blank' do @@ -54,6 +45,16 @@ .inverse_of(:runtime_function_definition) end + it do + is_expected.to have_many(:runtime_function_definition_data_type_links).inverse_of(:runtime_function_definition) + end + + it do + is_expected.to have_many(:referenced_data_types) + .through(:runtime_function_definition_data_type_links) + .source(:referenced_data_type) + end + 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 f882c4b2..db263096 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, data_type: create(:data_type_identifier, generic_key: 'T')) } + subject { create(:runtime_parameter_definition) } describe 'validations' do it { is_expected.to validate_presence_of(:runtime_name) } @@ -17,7 +17,6 @@ describe 'associations' do it { is_expected.to belong_to(:runtime_function_definition) } - 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/models/runtime_spec.rb b/spec/models/runtime_spec.rb index 7f3cfce1..6517c9ec 100644 --- a/spec/models/runtime_spec.rb +++ b/spec/models/runtime_spec.rb @@ -8,8 +8,6 @@ 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_mappers).inverse_of(:runtime) } it { is_expected.to have_many(:flow_types).inverse_of(:runtime) } it { diff --git a/spec/requests/graphql/mutation/namespace/projects/flows/create_mutation_spec.rb b/spec/requests/graphql/mutation/namespace/projects/flows/create_mutation_spec.rb index 6557a7da..b99cf416 100644 --- a/spec/requests/graphql/mutation/namespace/projects/flows/create_mutation_spec.rb +++ b/spec/requests/graphql/mutation/namespace/projects/flows/create_mutation_spec.rb @@ -62,22 +62,10 @@ let(:flow_type) { create(:flow_type, runtime: runtime) } let(:function_definition) do rfd = create(:runtime_function_definition, runtime: runtime) - rpd = create( - :runtime_parameter_definition, - runtime_function_definition: rfd, - data_type: create( - :data_type_identifier, - data_type: create(:data_type) - ) - ) + rpd = create(:runtime_parameter_definition, runtime_function_definition: rfd) create(:function_definition, runtime_function_definition: rfd).tap do |fd| - create( - :parameter_definition, - runtime_parameter_definition: rpd, - function_definition: fd, - data_type: rpd.data_type - ) + create(:parameter_definition, runtime_parameter_definition: rpd, function_definition: fd) end end let(:input) do diff --git a/spec/requests/graphql/mutation/namespace/projects/flows/update_mutation_spec.rb b/spec/requests/graphql/mutation/namespace/projects/flows/update_mutation_spec.rb index c31b35f6..f857bc96 100644 --- a/spec/requests/graphql/mutation/namespace/projects/flows/update_mutation_spec.rb +++ b/spec/requests/graphql/mutation/namespace/projects/flows/update_mutation_spec.rb @@ -65,23 +65,10 @@ let(:flow) { create(:flow, project: project, flow_type: flow_type) } let(:function_definition) do rfd = create(:runtime_function_definition, runtime: runtime) - rpd = create( - :runtime_parameter_definition, - runtime_function_definition: rfd, - data_type: create( - :data_type_identifier, - runtime: runtime, - data_type: create(:data_type, runtime: runtime) - ) - ) + rpd = create(:runtime_parameter_definition, runtime_function_definition: rfd) create(:function_definition, runtime_function_definition: rfd).tap do |fd| - create( - :parameter_definition, - runtime_parameter_definition: rpd, - function_definition: fd, - data_type: rpd.data_type - ) + create(:parameter_definition, runtime_parameter_definition: rpd, function_definition: fd) end end diff --git a/spec/requests/grpc/sagittarius/data_type_service_spec.rb b/spec/requests/grpc/sagittarius/data_type_service_spec.rb index c83d1372..cfc80e6b 100644 --- a/spec/requests/grpc/sagittarius/data_type_service_spec.rb +++ b/spec/requests/grpc/sagittarius/data_type_service_spec.rb @@ -11,8 +11,8 @@ let(:data_types) do [ { - variant: :PRIMITIVE, identifier: 'positive_number', + type: 'number', name: [ { code: 'de_DE', content: 'Positive Zahl' } ], @@ -23,11 +23,9 @@ { code: 'de_DE', content: 'Zahl: ${0}' } ], rules: [ - Tucana::Shared::DefinitionDataTypeRule.create( - :contains_type, - { data_type_identifier: { generic_key: 'T' } } - ) + Tucana::Shared::DefinitionDataTypeRule.create(:number_range, { from: 1, to: 100 }) ], + linked_data_type_identifiers: [], version: '0.0.0', } ] @@ -45,7 +43,7 @@ data_type = DataType.last expect(data_type.runtime).to eq(runtime) - expect(data_type.variant).to eq('primitive') + expect(data_type.type).to eq('number') expect(data_type.identifier).to eq('positive_number') expect(data_type.names.count).to eq(1) expect(data_type.names.first.code).to eq('de_DE') @@ -57,72 +55,24 @@ expect(data_type.display_messages.first.code).to eq('de_DE') expect(data_type.display_messages.first.content).to eq('Zahl: ${0}') expect(data_type.rules.count).to eq(1) - expect(data_type.rules.first.variant).to eq('contains_type') - expect(data_type.rules.first.config).to eq( - { - 'data_type_identifier' => { 'generic_key' => 'T' }, - 'data_type_identifier_id' => DataTypeIdentifier.find_by(runtime: runtime, generic_key: 'T').id, - } - ) + expect(data_type.rules.first.variant).to eq('number_range') + expect(data_type.rules.first.config).to eq({ 'from' => 1, 'to' => 100, 'steps' => 0 }) end context 'with more rules' do let(:data_types) do [ { - variant: :PRIMITIVE, - identifier: 'parent_type_identifier', - version: '0.0.0', - }, - { - variant: :PRIMITIVE, - identifier: 'some_type', - version: '0.0.0', - }, - { - variant: :PRIMITIVE, identifier: 'positive_number', + type: 'number', name: [ { code: 'de_DE', content: 'Positive Zahl' } ], - alias: [ - { code: 'de_DE', content: 'Positive Nummer' } - ], - display_message: [ - { code: 'de_DE', content: 'Zahl: ${0}' } - ], rules: [ - Tucana::Shared::DefinitionDataTypeRule.create(:contains_key, { - key: 'example_key', - data_type_identifier: { - data_type_identifier: 'some_type', - }, - }), - Tucana::Shared::DefinitionDataTypeRule.create(:contains_type, { - data_type_identifier: { generic_key: 'T' }, - }), - Tucana::Shared::DefinitionDataTypeRule.create(:item_of_collection, { items: [] }), Tucana::Shared::DefinitionDataTypeRule.create(:number_range, { from: 1, to: 100, steps: 1 }), - Tucana::Shared::DefinitionDataTypeRule.create(:regex, { pattern: '^\d+$' }), - Tucana::Shared::DefinitionDataTypeRule.create(:input_types, { - input_types: [{ - data_type_identifier: { - data_type_identifier: 'some_type', - }, - input_identifier: 'input_1', - }], - }), - Tucana::Shared::DefinitionDataTypeRule.create(:return_type, { - data_type_identifier: { - data_type_identifier: 'some_type', - }, - }), - Tucana::Shared::DefinitionDataTypeRule.create(:parent_type, { - parent_type: { - data_type_identifier: 'parent_type_identifier', - }, - }) + Tucana::Shared::DefinitionDataTypeRule.create(:regex, { pattern: '^\d+$' }) ], + linked_data_type_identifiers: [], version: '0.0.0', } ] @@ -131,301 +81,88 @@ it 'creates a correct datatype with all rules' do expect(stub.update(message, authorization(runtime)).success).to be(true) - expect(DataType.last.rules.count).to eq(8) + expect(DataType.last.rules.count).to eq(2) end end - context 'with dependent data types' do - context 'with parent_type rule' do - let(:data_types) do - [ - { - variant: :PRIMITIVE, - identifier: 'small_positive_number', - name: [ - { code: 'de_DE', content: 'Kleine positive Zahl' } - ], - rules: [ - Tucana::Shared::DefinitionDataTypeRule.create(:number_range, { from: 9 }), - Tucana::Shared::DefinitionDataTypeRule.create( - :parent_type, - { parent_type: { - generic_type: { - data_type_identifier: 'positive_number', - generic_mappers: [ - { - source: [ - { - data_type_identifier: 'some_other_dependency', - } - ], - target: 'T', - generic_combinations: [], - } - ], - }, - } } - ) - ], - generic_keys: ['T'], - version: '0.0.0', - }, - - { - variant: :PRIMITIVE, - identifier: 'some_other_dependency', - name: [ - { code: 'de_DE', content: 'Positive Zahl' } - ], - rules: [ - Tucana::Shared::DefinitionDataTypeRule.create(:number_range, { from: 1 }) - ], - version: '0.0.0', - }, - { - variant: :PRIMITIVE, - identifier: 'positive_number', - name: [ - { code: 'de_DE', content: 'Positive Zahl' } - ], - rules: [ - Tucana::Shared::DefinitionDataTypeRule.create(:number_range, { from: 1 }) - ], - version: '0.0.0', - } - ] - end - - it 'creates data types' do - expect(stub.update(message, authorization(runtime)).success).to be(true) - - positive_number = DataType.find_by(identifier: 'positive_number') - small_positive_number = DataType.find_by(identifier: 'small_positive_number') - - 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.generic_type.data_type).to eq(positive_number) - end - end - - context 'with contains_key rule' do - let(:data_types) do - [ - { - variant: :PRIMITIVE, - identifier: 'type1', - rules: [ - Tucana::Shared::DefinitionDataTypeRule.create( - :contains_key, - { - key: 'test', - data_type_identifier: { - generic_type: { - data_type_identifier: 'type2', - generic_mappers: [ - { - source: [ - { - data_type_identifier: 'type3', - } - ], - target: 'T', - generic_combinations: [], - } - ], - }, - }, - } - ) - ], - generic_keys: ['T'], - version: '0.0.0', - }, - - { - variant: :PRIMITIVE, - identifier: 'type2', - version: '0.0.0', - }, - { - variant: :PRIMITIVE, - identifier: 'type3', - version: '0.0.0', - } - ] - end - - it 'creates data types' do - expect(stub.update(message, authorization(runtime)).success).to be(true) - - expect(DataType.find_by(identifier: 'type1')).to be_present - end + context 'with linked data types' do + let(:data_types) do + [ + { + identifier: 'HTTP_METHOD', + type: 'string', + linked_data_type_identifiers: [], + version: '0.0.0', + }, + { + identifier: 'HTTP_URL', + type: 'string', + linked_data_type_identifiers: [], + version: '0.0.0', + }, + { + identifier: 'OBJECT', + type: 'T & {}', + generic_keys: ['T'], + linked_data_type_identifiers: [], + version: '0.0.0', + }, + { + identifier: 'HTTP_REQUEST', + type: '{ method: HTTP_METHOD, url: HTTP_URL, body: T, headers: OBJECT<{}> }', + generic_keys: ['T'], + linked_data_type_identifiers: %w[HTTP_METHOD HTTP_URL OBJECT], + version: '0.0.0', + } + ] end - context 'with contains_type rule' do - let(:data_types) do - [ - { - variant: :PRIMITIVE, - identifier: 'type1', - rules: [ - Tucana::Shared::DefinitionDataTypeRule.create( - :contains_type, - { - data_type_identifier: { - generic_type: { - data_type_identifier: 'type2', - generic_mappers: [ - { - source: [ - { - data_type_identifier: 'type3', - } - ], - target: 'T', - generic_combinations: [], - } - ], - }, - }, - } - ) - ], - generic_keys: ['T'], - version: '0.0.0', - }, - - { - variant: :PRIMITIVE, - identifier: 'type2', - version: '0.0.0', - }, - { - variant: :PRIMITIVE, - identifier: 'type3', - version: '0.0.0', - } - ] - end + it 'creates data types with links' do + expect(stub.update(message, authorization(runtime)).success).to be(true) - it 'creates data types' do - expect(stub.update(message, authorization(runtime)).success).to be(true) + http_method = DataType.find_by(identifier: 'HTTP_METHOD') + http_url = DataType.find_by(identifier: 'HTTP_URL') + object = DataType.find_by(identifier: 'OBJECT') + http_request = DataType.find_by(identifier: 'HTTP_REQUEST') - expect(DataType.find_by(identifier: 'type1')).to be_present - end + expect(http_request).to be_present + expect(http_request.referenced_data_types).to contain_exactly(http_method, http_url, object) end + end - context 'with input_types rule' do - let(:data_types) do - [ - { - variant: :PRIMITIVE, - identifier: 'type1', - rules: [ - Tucana::Shared::DefinitionDataTypeRule.create( - :input_types, - { - input_types: [ - { - data_type_identifier: { - generic_type: { - data_type_identifier: 'type2', - generic_mappers: [ - { - source: [ - { - data_type_identifier: 'type3', - } - ], - target: 'T', - generic_combinations: [], - } - ], - }, - }, - input_identifier: 'input', - } - ], - } - ) - ], - generic_keys: ['T'], - version: '0.0.0', - }, - - { - variant: :PRIMITIVE, - identifier: 'type2', - version: '0.0.0', - }, - { - variant: :PRIMITIVE, - identifier: 'type3', - version: '0.0.0', - } - ] - end - - it 'creates data types' do - expect(stub.update(message, authorization(runtime)).success).to be(true) - - expect(DataType.find_by(identifier: 'type1')).to be_present - end + context 'with dependent data types in wrong order' do + let(:data_types) do + [ + { + identifier: 'HTTP_REQUEST', + type: '{ method: HTTP_METHOD, url: HTTP_URL }', + linked_data_type_identifiers: %w[HTTP_METHOD HTTP_URL], + version: '0.0.0', + }, + { + identifier: 'HTTP_URL', + type: 'string', + linked_data_type_identifiers: [], + version: '0.0.0', + }, + { + identifier: 'HTTP_METHOD', + type: 'string', + linked_data_type_identifiers: [], + version: '0.0.0', + } + ] end - context 'with return_type rule' do - let(:data_types) do - [ - { - variant: :PRIMITIVE, - identifier: 'type1', - rules: [ - Tucana::Shared::DefinitionDataTypeRule.create( - :return_type, - { - data_type_identifier: { - generic_type: { - data_type_identifier: 'type2', - generic_mappers: [ - { - source: [ - { - data_type_identifier: 'type3', - } - ], - target: 'T', - generic_combinations: [], - } - ], - }, - }, - } - ) - ], - generic_keys: ['T'], - version: '0.0.0', - }, - - { - variant: :PRIMITIVE, - identifier: 'type2', - version: '0.0.0', - }, - { - variant: :PRIMITIVE, - identifier: 'type3', - version: '0.0.0', - } - ] - end + it 'sorts and creates data types correctly' do + expect(stub.update(message, authorization(runtime)).success).to be(true) - it 'creates data types' do - expect(stub.update(message, authorization(runtime)).success).to be(true) + http_request = DataType.find_by(identifier: 'HTTP_REQUEST') + http_method = DataType.find_by(identifier: 'HTTP_METHOD') + http_url = DataType.find_by(identifier: 'HTTP_URL') - expect(DataType.find_by(identifier: 'type1')).to be_present - end + expect(http_request).to be_present + expect(http_request.referenced_data_types).to contain_exactly(http_method, http_url) end end diff --git a/spec/requests/grpc/sagittarius/flow_type_service_spec.rb b/spec/requests/grpc/sagittarius/flow_type_service_spec.rb index a6d5409b..da2b9f03 100644 --- a/spec/requests/grpc/sagittarius/flow_type_service_spec.rb +++ b/spec/requests/grpc/sagittarius/flow_type_service_spec.rb @@ -10,54 +10,58 @@ let(:runtime) { create(:runtime, namespace: namespace) } describe 'Update' do - let(:data_type) do - create(:data_type, identifier: 'some_return_type_identifier', runtime: runtime) - end + let!(:http_response_data_type) { create(:data_type, identifier: 'HTTP_RESPONSE', runtime: runtime) } + let!(:rest_adapter_input_data_type) { create(:data_type, identifier: 'REST_ADAPTER_INPUT', runtime: runtime) } + let!(:http_url_data_type) { create(:data_type, identifier: 'HTTP_URL', runtime: runtime) } + let!(:http_method_data_type) { create(:data_type, identifier: 'HTTP_METHOD', runtime: runtime) } let(:flow_types) do [ { - identifier: 'some_flow_type_identifier', + identifier: 'REST', settings: [ { - identifier: 'some_setting_identifier', + identifier: 'HTTP_URL', unique: :PROJECT, - data_type_identifier: create(:data_type, runtime: runtime).identifier, - default_value: Tucana::Shared::Value.from_ruby({ 'value' => 'some default value' }), + type: 'HTTP_URL', + linked_data_type_identifiers: ['HTTP_URL'], name: [ - { code: 'en_US', content: 'Some Setting' } + { code: 'en_US', content: 'URL' } ], description: [ - { code: 'en_US', content: 'This is a setting' } + { code: 'en_US', content: 'Specifies the HTTP URL endpoint.' } ], }, { - identifier: 'without_default', + identifier: 'HTTP_METHOD', unique: :NONE, - data_type_identifier: create(:data_type, runtime: runtime).identifier, - default_value: nil, + type: 'HTTP_METHOD', + linked_data_type_identifiers: ['HTTP_METHOD'], + default_value: Tucana::Shared::Value.from_ruby('GET'), name: [ - { code: 'en_US', content: 'Some Setting' } + { code: 'en_US', content: 'Method' } ], description: [ - { code: 'en_US', content: 'This is a setting' } + { code: 'en_US', content: 'Specifies the HTTP request method.' } ], } ], + input_type: 'REST_ADAPTER_INPUT', + return_type: 'HTTP_RESPONSE', + linked_data_type_identifiers: %w[REST_ADAPTER_INPUT HTTP_RESPONSE], name: [ - { code: 'de_DE', content: 'Keine Ahnung man' } + { code: 'en_US', content: 'Rest Endpoint' } ], description: [ - { code: 'en_US', content: "That's a description" } + { code: 'en_US', content: 'A REST API endpoint' } ], display_message: [ - { code: 'en_US', content: 'Flow Type: ${0}' } + { code: 'en_US', content: 'Trigger Rest-Flow on ${method} with a Request to ${route}' } ], alias: [ - { code: 'de_DE', content: 'Irgendein Flow Typ' } + { code: 'en_US', content: 'http;rest;route' } ], - editable: true, - return_type_identifier: data_type.identifier, + editable: false, version: '0.0.0', } ] @@ -71,41 +75,49 @@ expect(stub.update(message, authorization(runtime)).success).to be(true) flow_type = FlowType.last - expect(flow_type.identifier).to eq('some_flow_type_identifier') + expect(flow_type.identifier).to eq('REST') + expect(flow_type.input_type).to eq('REST_ADAPTER_INPUT') + expect(flow_type.return_type).to eq('HTTP_RESPONSE') + expect(flow_type.editable).to be false + expect(flow_type.version).to eq('0.0.0') + expect(flow_type.referenced_data_types).to contain_exactly(rest_adapter_input_data_type, + http_response_data_type) + expect(flow_type.names.count).to eq(1) - expect(flow_type.names.first.code).to eq('de_DE') - expect(flow_type.names.first.content).to eq('Keine Ahnung man') + expect(flow_type.names.first.code).to eq('en_US') + expect(flow_type.names.first.content).to eq('Rest Endpoint') expect(flow_type.descriptions.count).to eq(1) - expect(flow_type.descriptions.first.code).to eq('en_US') - expect(flow_type.descriptions.first.content).to eq("That's a description") + expect(flow_type.descriptions.first.content).to eq('A REST API endpoint') expect(flow_type.display_messages.count).to eq(1) - expect(flow_type.display_messages.first.code).to eq('en_US') - expect(flow_type.display_messages.first.content).to eq('Flow Type: ${0}') + expect(flow_type.display_messages.first.content).to eq( + 'Trigger Rest-Flow on ${method} with a Request to ${route}' + ) expect(flow_type.aliases.count).to eq(1) - expect(flow_type.aliases.first.code).to eq('de_DE') - expect(flow_type.aliases.first.content).to eq('Irgendein Flow Typ') - - expect(flow_type.editable).to be true - expect(flow_type.return_type.identifier).to eq('some_return_type_identifier') - expect(flow_type.version).to eq('0.0.0') + expect(flow_type.aliases.first.content).to eq('http;rest;route') expect(flow_type.flow_type_settings.count).to eq(2) - setting = flow_type.flow_type_settings.first - expect(setting.identifier).to eq('some_setting_identifier') - expect(setting.unique).to eq('project') - expect(setting.default_value).to eq('value' => 'some default value') - expect(setting.names.count).to eq(1) - expect(setting.names.first.code).to eq('en_US') - expect(setting.names.first.content).to eq('Some Setting') - expect(setting.descriptions.count).to eq(1) - expect(setting.descriptions.first.code).to eq('en_US') - expect(setting.descriptions.first.content).to eq('This is a setting') + + url_setting = flow_type.flow_type_settings.find_by(identifier: 'HTTP_URL') + expect(url_setting.unique).to eq('project') + expect(url_setting.type).to eq('HTTP_URL') + expect(url_setting.default_value).to be_nil + expect(url_setting.names.first.content).to eq('URL') + expect(url_setting.descriptions.first.content).to eq('Specifies the HTTP URL endpoint.') + expect(url_setting.referenced_data_types).to contain_exactly(http_url_data_type) + + method_setting = flow_type.flow_type_settings.find_by(identifier: 'HTTP_METHOD') + expect(method_setting.unique).to eq('none') + expect(method_setting.type).to eq('HTTP_METHOD') + expect(method_setting.default_value).to eq('GET') + expect(method_setting.names.first.content).to eq('Method') + expect(method_setting.descriptions.first.content).to eq('Specifies the HTTP request method.') + expect(method_setting.referenced_data_types).to contain_exactly(http_method_data_type) end - context 'when removing datatypes' do + context 'when removing flowtypes' do let!(:existing_flow_type) { create(:flow_type, runtime: runtime) } let(:flow_types) { [] } 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 7bc68161..ec0ab83b 100644 --- a/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_function_definition_service_spec.rb @@ -10,57 +10,58 @@ 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_base_type) { create(:data_type, runtime: runtime) } + let!(:list_data_type) { create(:data_type, identifier: 'LIST', runtime: runtime) } + let!(:predicate_data_type) { create(:data_type, identifier: 'PREDICATE', runtime: runtime) } let(:runtime_functions) do [ { - runtime_name: 'runtime_function_id', + runtime_name: 'std::list::filter', + signature: '(list: LIST, predicate: PREDICATE): LIST', name: [ - { code: 'de_DE', content: 'Eine Funktion' } + { code: 'en_US', content: 'Filter List' } ], description: [ - { code: 'de_DE', content: 'Eine Funktionsbeschreibung' } + { code: 'en_US', content: 'Filters a list by a predicate' } ], documentation: [ - { code: 'de_DE', content: 'Eine Funktionsdokumentation' } + { code: 'en_US', content: 'Filter documentation' } ], deprecation_message: [ - { code: 'de_DE', content: 'Eine Deprecationsmeldung' } + { code: 'en_US', content: 'Use filter_v2 instead' } ], display_message: [ - { code: 'de_DE', content: 'Eine Funktionsanzeige' } + { code: 'en_US', content: 'Filter elements in ${list} matching ${predicate}' } ], alias: [ - { code: 'de_DE', content: 'Ein Funktionsalias' } + { code: 'en_US', content: 'filter;array;list' } ], - return_type_identifier: { - generic_type: { - data_type_identifier: generic_base_type.identifier, - generic_mappers: [{ source: [{ generic_key: 'T' }], target: 'V', generic_combinations: [] }], - }, - }, - throws_error: true, + throws_error: false, + linked_data_type_identifiers: %w[LIST PREDICATE], runtime_parameter_definitions: [ { - data_type_identifier: { - data_type_identifier: parameter_type.data_type.identifier, - }, - runtime_name: 'some_id', - default_value: Tucana::Shared::Value.from_ruby({ 'key' => 'value' }), + runtime_name: 'list', + default_value: nil, name: [ - { code: 'de_DE', content: 'Ein Parameter' } + { code: 'en_US', content: 'Input List' } ], description: [ - { code: 'de_DE', content: 'Eine Parameterbeschreibung' } + { code: 'en_US', content: 'The list to be filtered' } ], documentation: [ - { code: 'de_DE', content: 'Eine Parameterdokumentation' } + { code: 'en_US', content: 'List documentation' } + ], + }, + { + runtime_name: 'predicate', + default_value: Tucana::Shared::Value.from_ruby({ 'key' => 'value' }), + name: [ + { code: 'en_US', content: 'Filter Predicate' } ], + description: [ + { code: 'en_US', content: 'A function that returns a boolean' } + ], + documentation: [], } ], version: '0.0.0', @@ -75,80 +76,76 @@ 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.sources.first.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(generic_base_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.aliases.first.content).to eq('Ein Funktionsalias') - expect(function.display_messages.first.content).to eq('Eine Funktionsanzeige') - expect(function.throws_error).to be(true) + expect(function.runtime_name).to eq('std::list::filter') + expect(function.signature).to eq('(list: LIST, predicate: PREDICATE): LIST') + expect(function.names.first.content).to eq('Filter List') + expect(function.descriptions.first.content).to eq('Filters a list by a predicate') + expect(function.documentations.first.content).to eq('Filter documentation') + expect(function.deprecation_messages.first.content).to eq('Use filter_v2 instead') + expect(function.aliases.first.content).to eq('filter;array;list') + expect(function.display_messages.first.content).to eq('Filter elements in ${list} matching ${predicate}') + expect(function.throws_error).to be(false) expect(function.version).to eq('0.0.0') - parameter = function.parameters.first - expect(parameter.data_type.data_type.identifier).to eq(parameter_type.data_type.identifier) - 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') - expect(parameter.default_value).to eq({ 'key' => 'value' }) + expect(function.referenced_data_types).to contain_exactly(list_data_type, predicate_data_type) + + expect(function.parameters.count).to eq(2) + list_param = function.parameters.find_by(runtime_name: 'list') + expect(list_param.names.first.content).to eq('Input List') + expect(list_param.descriptions.first.content).to eq('The list to be filtered') + expect(list_param.documentations.first.content).to eq('List documentation') + expect(list_param.default_value).to be_nil + + predicate_param = function.parameters.find_by(runtime_name: 'predicate') + expect(predicate_param.names.first.content).to eq('Filter Predicate') + expect(predicate_param.default_value).to eq({ 'key' => 'value' }) function_definition = FunctionDefinition.first - 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.aliases.first.content).to eq('Ein Funktionsalias') - expect(function_definition.display_messages.first.content).to eq('Eine Funktionsanzeige') - expect(function_definition.return_type.generic_type.reload.data_type.identifier) - .to eq(generic_base_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(function_definition.names.first.content).to eq('Filter List') + expect(function_definition.descriptions.first.content).to eq('Filters a list by a predicate') + expect(function_definition.documentations.first.content).to eq('Filter documentation') + expect(function_definition.aliases.first.content).to eq('filter;array;list') + expect(function_definition.display_messages.first.content).to eq( + 'Filter elements in ${list} matching ${predicate}' + ) + + expect(ParameterDefinition.count).to eq(2) + list_param_def = ParameterDefinition.find_by(runtime_parameter_definition: list_param) + expect(list_param_def.names.first.content).to eq('Input List') + expect(list_param_def.descriptions.first.content).to eq('The list to be filtered') + expect(list_param_def.documentations.first.content).to eq('List documentation') + expect(list_param_def.default_value).to be_nil 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(:list_data_type) { create(:data_type, identifier: 'LIST', runtime: runtime) } let(:existing_runtime_function_definition) do create(:runtime_function_definition, runtime: runtime, - runtime_name: 'runtime_function_id', - names: create(:translation, code: 'en_US', content: 'A Function')) + runtime_name: 'std::list::filter', + names: create(:translation, code: 'en_US', content: 'Filter List')) end let(:runtime_functions) do [ { - runtime_name: 'runtime_function_id', + runtime_name: 'std::list::filter', + signature: '(list: LIST): LIST', name: [ - { code: 'de_DE', content: 'Eine Funktion' } + { code: 'de_DE', content: 'Liste filtern' } ], runtime_parameter_definitions: [ { - data_type_identifier: { - data_type_identifier: data_type.data_type.identifier, - }, - runtime_name: 'runtime_parameter_definition_id', + runtime_name: 'list', name: [ - { code: 'de_DE', content: 'Ein Parameter' } + { code: 'de_DE', content: 'Eingabeliste' } ], } ], + linked_data_type_identifiers: [list_data_type.identifier], version: '0.0.0', } ] @@ -164,12 +161,12 @@ expect(RuntimeFunctionDefinition.count).to eq(1) function = RuntimeFunctionDefinition.last - expect(function.runtime_name).to eq('runtime_function_id') - expect(function.names.first.content).to eq('Eine Funktion') + expect(function.runtime_name).to eq('std::list::filter') + expect(function.signature).to eq('(list: LIST): LIST') + expect(function.names.first.content).to eq('Liste filtern') parameter = function.parameters.first - 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') + expect(parameter.runtime_name).to eq('list') + expect(parameter.names.first.content).to eq('Eingabeliste') expect(FunctionDefinition.count).to eq(1) expect(ParameterDefinition.count).to eq(1) @@ -178,17 +175,14 @@ context 'when deleting' do let(:runtime) { create(:runtime) } - let(:data_type) { create(:data_type, runtime: runtime) } let!(:existing_runtime_function_definition) do create(:runtime_function_definition, runtime: runtime) 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)), - runtime_function_definition: existing_runtime_function_definition) + create(:runtime_parameter_definition, + runtime_function_definition: existing_runtime_function_definition) end let(:message) do @@ -200,10 +194,12 @@ [ { runtime_name: existing_runtime_function_definition.runtime_name, + signature: '() => void', name: [ { code: 'de_DE', content: 'Eine Funktion' } ], runtime_parameter_definitions: [], + linked_data_type_identifiers: [], version: '0.0.0', } ] 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 deleted file mode 100644 index 8c083d7d..00000000 --- a/spec/services/namespaces/projects/flows/validation/data_type/data_type_identifier_validation_service_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -# 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 - - let(:current_user) { create(:user) } - let(:runtime) { create(:runtime) } - let(:namespace_project) { create(:namespace_project, primary_runtime: runtime) } - let(:node) do - create( - :node_function, - function_definition: create( - :function_definition, - runtime_function_definition: create( - :runtime_function_definition, - generic_keys: ['T'], - runtime: runtime - ) - ) - ) - end - let(:parameter) do - create( - :node_parameter, - parameter_definition: create( - :parameter_definition, - runtime_parameter_definition: 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_empty } - 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 include(have_attributes(error_code: :data_type_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 - - it { expect(service_response).to be_empty } - end - - context 'when T is contained in the function definition' do - let(:node) do - create( - :node_function, - function_definition: create( - :function_definition, - runtime_function_definition: create( - :runtime_function_definition, - generic_keys: ['T'], - runtime: runtime - ) - ) - ) - end - - it { expect(service_response).to be_empty } - end - - context 'when T is not contained in the function definition' do - let(:node) do - create( - :node_function, - function_definition: create( - :function_definition, - runtime_function_definition: create( - :runtime_function_definition, - generic_keys: [], - runtime: runtime - ) - ) - ) - end - - it { expect(service_response).to include(have_attributes(error_code: :data_type_identifier_generic_key_not_found)) } - end -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 deleted file mode 100644 index 73999dfc..00000000 --- a/spec/services/namespaces/projects/flows/validation/data_type/data_type_rule_validation_service_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -# 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) } - 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 be_empty } - 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 include(have_attributes(error_code: :data_type_rule_model_invalid)) - 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 deleted file mode 100644 index b168b7eb..00000000 --- a/spec/services/namespaces/projects/flows/validation/data_type/data_type_validation_service_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Namespaces::Projects::Flows::Validation::DataType::DataTypeValidationService do - 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 be_empty } - end - - context 'when data_type.runtime != runtime' do - let(:data_type) { create(:data_type) } - - it 'returns an error' do - expect(service_response).to include(have_attributes(error_code: :data_type_runtime_mismatch)) - end - end - - context 'when rules are set' do - let(:data_type) { create(:data_type, runtime: runtime, rules: [create(:data_type_rule)]) } - - it { expect(service_response).to be_empty } - end -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 deleted file mode 100644 index 9e8d3194..00000000 --- a/spec/services/namespaces/projects/flows/validation/flow_setting_validation_service_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Namespaces::Projects::Flows::Validation::FlowSettingValidationService do - 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 be_empty } - end - - context 'when setting is invalid' do - let(:setting) { build(:flow_setting, flow: flow) } - - before do - allow(setting).to receive_messages(invalid?: true, errors: ActiveModel::Errors.new(setting)) - end - - it 'returns an error' do - expect(service_response).to include(have_attributes(error_code: :flow_setting_model_invalid)) - expect(setting).to have_received(:invalid?) - # debug, payload -> 2 times - expect(setting).to have_received(:errors).exactly(2).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 deleted file mode 100644 index eecd3b54..00000000 --- a/spec/services/namespaces/projects/flows/validation/flow_type_validation_service_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Namespaces::Projects::Flows::Validation::FlowTypeValidationService do - 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 } } - 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 be_empty } - 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 include(have_attributes(error_code: :flow_type_runtime_mismatch)) - end - 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 deleted file mode 100644 index 43d3c3bb..00000000 --- a/spec/services/namespaces/projects/flows/validation/node_function/generic_mapper_validation_service_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -# 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 - - 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 - data_type_identifier = create( - :data_type_identifier, - generic_type: create( - :generic_type, - data_type: create(:data_type), - generic_mappers: [generic_mapper] - ) - ) - create( - :node_parameter, - parameter_definition: create( - :parameter_definition, - data_type: data_type_identifier - ), - literal_value: nil, - function_value: create(:node_function) - ) - end - let(:node) do - create( - :node_function, - function_definition: create( - :function_definition, - runtime_function_definition: 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_empty } - 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 deleted file mode 100644 index d13f0ac5..00000000 --- a/spec/services/namespaces/projects/flows/validation/node_function/reference_value_validation_service_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -# 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 - - 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, - function_definition: create( - :function_definition, - runtime_function_definition: create(:runtime_function_definition, runtime: runtime) - ), - node_parameters: [ - create( - :node_parameter, - parameter_definition: create( - :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, - function_definition: create( - :function_definition, - runtime_function_definition: create(:runtime_function_definition, runtime: runtime) - ), - node_parameters: [ - create( - :node_parameter, - parameter_definition: create( - :parameter_definition, - data_type: data_type_identifier - ), - literal_value: nil, - function_value: create( - :node_function, - node_parameters: [ - create( - :node_parameter, - parameter_definition: create( - :parameter_definition, - data_type: data_type_identifier - ) - ) - ] - ) - ), - create( - :node_parameter, - parameter_definition: create( - :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, data_type: create(:data_type, runtime: runtime), runtime: runtime) - end - let(:reference_value) do - create(:reference_value, - node_function: create(:node_function)) - end - - it { is_expected.to be_empty } -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 deleted file mode 100644 index 8787f2a4..00000000 --- a/spec/services/namespaces/projects/flows/validation/validation_service_spec.rb +++ /dev/null @@ -1,93 +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(:current_user) { create(:user) } - let(:runtime) { create(:runtime) } - let(:namespace_project) { create(:namespace_project).tap { |np| np.primary_runtime = runtime } } - let(:flow) do - create(:flow, flow_type: create(:flow_type, - runtime: runtime, - input_type: create(:data_type, runtime: runtime), - return_type: create(:data_type, runtime: runtime)), - project: namespace_project) - end - - let(:node) do - create(:node_function, flow: flow, runtime_function: create(:runtime_function_definition, runtime: runtime)) - end - - 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, runtime: runtime)) - 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, runtime: runtime)) - 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, runtime: runtime), input_type: create(:data_type, runtime: runtime)) - 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 - - 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 - - it 'returns an error' do - expect(service_response.payload[:details]).to include(have_attributes(error_code: :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(:flow) do - create(:flow, project: namespace_project, flow_type: create(:flow_type, runtime: runtime)) - end - let(:starting_node) do - create(:node_function, runtime_function: create(:runtime_function_definition, runtime: runtime), flow: flow) - end - - context 'with simplest flow' do - it { is_expected.to be_success } - it { expect(service_response.payload).to eq(flow) } - end - end -end diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb index 9b3fea08..b9297f2b 100644 --- a/spec/support/helpers/graphql_helpers.rb +++ b/spec/support/helpers/graphql_helpers.rb @@ -84,7 +84,6 @@ def error_query details { ...on ActiveModelError { attribute type } ...on MessageError { message } - ...on FlowValidationError { errorCode severity details { attribute type } } } } )