From bb04aa22a7a1a8773d04a95c2f41e3e59adc5877 Mon Sep 17 00:00:00 2001 From: Niklas van Schrick Date: Sat, 9 Aug 2025 23:37:52 +0200 Subject: [PATCH] Add query for function and parameter definitions --- app/graphql/types/function_definition_type.rb | 25 +++++++++++++++++++ .../types/parameter_definition_type.rb | 21 ++++++++++++++++ .../types/runtime_function_definition_type.rb | 4 +++ app/models/function_definition.rb | 2 ++ app/models/parameter_definition.rb | 12 +++++++++ app/policies/function_definition_policy.rb | 5 ++++ app/policies/parameter_definition_policy.rb | 5 ++++ .../update_service.rb | 9 ++++--- ...tion_definition_to_parameter_definition.rb | 9 +++++++ db/schema_migrations/20250808184711 | 1 + db/structure.sql | 8 +++++- docs/graphql/object/functiondefinition.md | 19 ++++++++++++++ .../object/functiondefinitionconnection.md | 15 +++++++++++ docs/graphql/object/functiondefinitionedge.md | 13 ++++++++++ docs/graphql/object/parameterdefinition.md | 18 +++++++++++++ .../object/parameterdefinitionconnection.md | 15 +++++++++++ .../graphql/object/parameterdefinitionedge.md | 13 ++++++++++ .../object/runtimefunctiondefinition.md | 1 + docs/graphql/scalar/functiondefinitionid.md | 5 ++++ docs/graphql/scalar/parameterdefinitionid.md | 5 ++++ spec/factories/parameter_definitions.rb | 5 ++++ .../types/function_definition_type_spec.rb | 22 ++++++++++++++++ .../types/parameter_definition_type_spec.rb | 21 ++++++++++++++++ .../runtime_function_definition_type_spec.rb | 18 +++++++++++++ .../runtime_parameter_definition_type_spec.rb | 17 +++++++++++++ 25 files changed, 284 insertions(+), 4 deletions(-) create mode 100644 app/graphql/types/function_definition_type.rb create mode 100644 app/graphql/types/parameter_definition_type.rb create mode 100644 app/policies/function_definition_policy.rb create mode 100644 app/policies/parameter_definition_policy.rb create mode 100644 db/migrate/20250808184711_add_function_definition_to_parameter_definition.rb create mode 100644 db/schema_migrations/20250808184711 create mode 100644 docs/graphql/object/functiondefinition.md create mode 100644 docs/graphql/object/functiondefinitionconnection.md create mode 100644 docs/graphql/object/functiondefinitionedge.md create mode 100644 docs/graphql/object/parameterdefinition.md create mode 100644 docs/graphql/object/parameterdefinitionconnection.md create mode 100644 docs/graphql/object/parameterdefinitionedge.md create mode 100644 docs/graphql/scalar/functiondefinitionid.md create mode 100644 docs/graphql/scalar/parameterdefinitionid.md create mode 100644 spec/graphql/types/function_definition_type_spec.rb create mode 100644 spec/graphql/types/parameter_definition_type_spec.rb create mode 100644 spec/graphql/types/runtime_function_definition_type_spec.rb create mode 100644 spec/graphql/types/runtime_parameter_definition_type_spec.rb diff --git a/app/graphql/types/function_definition_type.rb b/app/graphql/types/function_definition_type.rb new file mode 100644 index 00000000..456abb77 --- /dev/null +++ b/app/graphql/types/function_definition_type.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Types + class FunctionDefinitionType < Types::BaseObject + description 'Represents a function definition' + + authorize :read_function_definition + + 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' + + field :descriptions, Types::TranslationType.connection_type, null: true, description: 'Description of the function' + field :names, Types::TranslationType.connection_type, null: true, description: 'Name of the function' + + field :documentations, Types::TranslationType.connection_type, + null: true, + description: 'Documentation of the function' + + id_field FunctionDefinition + timestamps + end +end diff --git a/app/graphql/types/parameter_definition_type.rb b/app/graphql/types/parameter_definition_type.rb new file mode 100644 index 00000000..9f97d890 --- /dev/null +++ b/app/graphql/types/parameter_definition_type.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Types + class ParameterDefinitionType < Types::BaseObject + description 'Represents a parameter definition' + + authorize :read_parameter_definition + + field :data_type, Types::DataTypeIdentifierType, null: true, description: 'Data type of the parameter' + + field :descriptions, Types::TranslationType.connection_type, null: true, description: 'Description of the parameter' + field :names, Types::TranslationType.connection_type, null: true, description: 'Name of the parameter' + + field :documentations, Types::TranslationType.connection_type, + null: true, + description: 'Documentation of the parameter' + + id_field ParameterDefinition + timestamps + end +end diff --git a/app/graphql/types/runtime_function_definition_type.rb b/app/graphql/types/runtime_function_definition_type.rb index 97dd5f95..1b24fab8 100644 --- a/app/graphql/types/runtime_function_definition_type.rb +++ b/app/graphql/types/runtime_function_definition_type.rb @@ -6,6 +6,10 @@ class RuntimeFunctionDefinitionType < Types::BaseObject authorize :read_flow + field :function_definitions, Types::FunctionDefinitionType.connection_type, + null: true, + description: 'Function definitions of the Node Function' + id_field RuntimeParameterDefinition timestamps end diff --git a/app/models/function_definition.rb b/app/models/function_definition.rb index 389961a7..28f991f4 100644 --- a/app/models/function_definition.rb +++ b/app/models/function_definition.rb @@ -4,6 +4,8 @@ class FunctionDefinition < ApplicationRecord belongs_to :runtime_function_definition belongs_to :return_type, class_name: 'DataTypeIdentifier', optional: true + has_many :parameter_definitions, inverse_of: :function_definition + has_many :names, -> { by_purpose(:name) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :descriptions, -> { by_purpose(:description) }, class_name: 'Translation', as: :owner, inverse_of: :owner has_many :documentations, -> { by_purpose(:documentation) }, class_name: 'Translation', as: :owner, inverse_of: :owner diff --git a/app/models/parameter_definition.rb b/app/models/parameter_definition.rb index 1ae25b5d..7eb011fc 100644 --- a/app/models/parameter_definition.rb +++ b/app/models/parameter_definition.rb @@ -4,7 +4,19 @@ class ParameterDefinition < ApplicationRecord belongs_to :runtime_parameter_definition belongs_to :data_type, class_name: 'DataTypeIdentifier' + belongs_to :function_definition, inverse_of: :parameter_definitions + 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 + + validate :function_definition_matches_definition + + def function_definition_matches_definition + parameter_function_definition_id = runtime_parameter_definition&.runtime_function_definition_id + function_definition_id = function_definition&.runtime_function_definition_id + return if parameter_function_definition_id == function_definition_id + + errors.add(:function_definition, :runtime_function_definition_mismatch) + end end diff --git a/app/policies/function_definition_policy.rb b/app/policies/function_definition_policy.rb new file mode 100644 index 00000000..abdd47d7 --- /dev/null +++ b/app/policies/function_definition_policy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class FunctionDefinitionPolicy < BasePolicy + delegate { subject.runtime_function_definition } +end diff --git a/app/policies/parameter_definition_policy.rb b/app/policies/parameter_definition_policy.rb new file mode 100644 index 00000000..f39def5a --- /dev/null +++ b/app/policies/parameter_definition_policy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ParameterDefinitionPolicy < BasePolicy + delegate { subject.runtime_parameter_definition } +end diff --git a/app/services/runtimes/runtime_function_definitions/update_service.rb b/app/services/runtimes/runtime_function_definitions/update_service.rb index 4fce9d9f..7786e8ac 100644 --- a/app/services/runtimes/runtime_function_definitions/update_service.rb +++ b/app/services/runtimes/runtime_function_definitions/update_service.rb @@ -37,8 +37,6 @@ def update_runtime_function_definition(runtime_function_definition, t) runtime_name: runtime_function_definition.runtime_name ) db_object.removed_at = nil - db_object.parameters = update_parameters(db_object, runtime_function_definition.runtime_parameter_definitions, - db_object.parameters, t) db_object.return_type = if runtime_function_definition.return_type_identifier.present? find_data_type_identifier(runtime_function_definition.return_type_identifier, runtime_function_definition.generic_mappers, t) @@ -51,7 +49,6 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.deprecation_messages) db_object.error_types = update_error_types(runtime_function_definition.error_type_identifiers, db_object, t) - db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object, t) if db_object.function_definitions.empty? definition = FunctionDefinition.new @@ -64,6 +61,11 @@ def update_runtime_function_definition(runtime_function_definition, t) db_object.function_definitions << definition end + + db_object.parameters = update_parameters(db_object, runtime_function_definition.runtime_parameter_definitions, + db_object.parameters, t) + db_object.generic_mappers = update_mappers(runtime_function_definition.generic_mappers, db_object, t) + db_object.save db_object end @@ -199,6 +201,7 @@ def update_parameters(runtime_function_definition, parameters, db_parameters, t) 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 db_param.parameter_definitions << definition end diff --git a/db/migrate/20250808184711_add_function_definition_to_parameter_definition.rb b/db/migrate/20250808184711_add_function_definition_to_parameter_definition.rb new file mode 100644 index 00000000..6e53d1a6 --- /dev/null +++ b/db/migrate/20250808184711_add_function_definition_to_parameter_definition.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddFunctionDefinitionToParameterDefinition < Code0::ZeroTrack::Database::Migration[1.0] + def change + # rubocop:disable Rails/NotNullColumn -- backwards compatibility intentionally ignored + add_reference :parameter_definitions, :function_definition, null: false, foreign_key: { on_delete: :cascade } + # rubocop:enable Rails/NotNullColumn + end +end diff --git a/db/schema_migrations/20250808184711 b/db/schema_migrations/20250808184711 new file mode 100644 index 00000000..eb1b76c2 --- /dev/null +++ b/db/schema_migrations/20250808184711 @@ -0,0 +1 @@ +d3649d3eb21c55852c948235ae16319daf78f7260be8393a2718b63c27fb4dd4 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index f13e4163..2020d8da 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -645,7 +645,8 @@ 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 + data_type_id bigint, + function_definition_id bigint NOT NULL ); CREATE SEQUENCE parameter_definitions_id_seq @@ -1243,6 +1244,8 @@ CREATE UNIQUE INDEX "index_organizations_on_LOWER_name" ON organizations USING b 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); CREATE INDEX index_reference_paths_on_reference_value_id ON reference_paths USING btree (reference_value_id); @@ -1296,6 +1299,9 @@ ALTER TABLE ONLY node_parameters ALTER TABLE ONLY data_types ADD CONSTRAINT fk_rails_118c914ed0 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; +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; diff --git a/docs/graphql/object/functiondefinition.md b/docs/graphql/object/functiondefinition.md new file mode 100644 index 00000000..937c0011 --- /dev/null +++ b/docs/graphql/object/functiondefinition.md @@ -0,0 +1,19 @@ +--- +title: FunctionDefinition +--- + +Represents a function definition + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this FunctionDefinition was created | +| `descriptions` | [`TranslationConnection`](../object/translationconnection.md) | Description of the function | +| `documentations` | [`TranslationConnection`](../object/translationconnection.md) | Documentation of the function | +| `id` | [`FunctionDefinitionID!`](../scalar/functiondefinitionid.md) | Global ID of this FunctionDefinition | +| `names` | [`TranslationConnection`](../object/translationconnection.md) | Name of the function | +| `parameterDefinitions` | [`ParameterDefinitionConnection`](../object/parameterdefinitionconnection.md) | Parameters of the function | +| `returnType` | [`DataTypeIdentifier`](../object/datatypeidentifier.md) | Return type of the function | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this FunctionDefinition was last updated | + diff --git a/docs/graphql/object/functiondefinitionconnection.md b/docs/graphql/object/functiondefinitionconnection.md new file mode 100644 index 00000000..232c13a7 --- /dev/null +++ b/docs/graphql/object/functiondefinitionconnection.md @@ -0,0 +1,15 @@ +--- +title: FunctionDefinitionConnection +--- + +The connection type for FunctionDefinition. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `count` | [`Int!`](../scalar/int.md) | Total count of collection. | +| `edges` | [`[FunctionDefinitionEdge]`](../object/functiondefinitionedge.md) | A list of edges. | +| `nodes` | [`[FunctionDefinition]`](../object/functiondefinition.md) | A list of nodes. | +| `pageInfo` | [`PageInfo!`](../object/pageinfo.md) | Information to aid in pagination. | + diff --git a/docs/graphql/object/functiondefinitionedge.md b/docs/graphql/object/functiondefinitionedge.md new file mode 100644 index 00000000..cb71e1e4 --- /dev/null +++ b/docs/graphql/object/functiondefinitionedge.md @@ -0,0 +1,13 @@ +--- +title: FunctionDefinitionEdge +--- + +An edge in a connection. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `cursor` | [`String!`](../scalar/string.md) | A cursor for use in pagination. | +| `node` | [`FunctionDefinition`](../object/functiondefinition.md) | The item at the end of the edge. | + diff --git a/docs/graphql/object/parameterdefinition.md b/docs/graphql/object/parameterdefinition.md new file mode 100644 index 00000000..c0f32135 --- /dev/null +++ b/docs/graphql/object/parameterdefinition.md @@ -0,0 +1,18 @@ +--- +title: ParameterDefinition +--- + +Represents a parameter definition + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this ParameterDefinition was created | +| `dataType` | [`DataTypeIdentifier`](../object/datatypeidentifier.md) | Data type of the parameter | +| `descriptions` | [`TranslationConnection`](../object/translationconnection.md) | Description of the parameter | +| `documentations` | [`TranslationConnection`](../object/translationconnection.md) | Documentation of the parameter | +| `id` | [`ParameterDefinitionID!`](../scalar/parameterdefinitionid.md) | Global ID of this ParameterDefinition | +| `names` | [`TranslationConnection`](../object/translationconnection.md) | Name of the parameter | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this ParameterDefinition was last updated | + diff --git a/docs/graphql/object/parameterdefinitionconnection.md b/docs/graphql/object/parameterdefinitionconnection.md new file mode 100644 index 00000000..d5bee2e1 --- /dev/null +++ b/docs/graphql/object/parameterdefinitionconnection.md @@ -0,0 +1,15 @@ +--- +title: ParameterDefinitionConnection +--- + +The connection type for ParameterDefinition. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `count` | [`Int!`](../scalar/int.md) | Total count of collection. | +| `edges` | [`[ParameterDefinitionEdge]`](../object/parameterdefinitionedge.md) | A list of edges. | +| `nodes` | [`[ParameterDefinition]`](../object/parameterdefinition.md) | A list of nodes. | +| `pageInfo` | [`PageInfo!`](../object/pageinfo.md) | Information to aid in pagination. | + diff --git a/docs/graphql/object/parameterdefinitionedge.md b/docs/graphql/object/parameterdefinitionedge.md new file mode 100644 index 00000000..b52c2e21 --- /dev/null +++ b/docs/graphql/object/parameterdefinitionedge.md @@ -0,0 +1,13 @@ +--- +title: ParameterDefinitionEdge +--- + +An edge in a connection. + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `cursor` | [`String!`](../scalar/string.md) | A cursor for use in pagination. | +| `node` | [`ParameterDefinition`](../object/parameterdefinition.md) | The item at the end of the edge. | + diff --git a/docs/graphql/object/runtimefunctiondefinition.md b/docs/graphql/object/runtimefunctiondefinition.md index 22fa9294..360330cb 100644 --- a/docs/graphql/object/runtimefunctiondefinition.md +++ b/docs/graphql/object/runtimefunctiondefinition.md @@ -9,6 +9,7 @@ Represents a Node Function definition | Name | Type | Description | |------|------|-------------| | `createdAt` | [`Time!`](../scalar/time.md) | Time when this RuntimeFunctionDefinition was created | +| `functionDefinitions` | [`FunctionDefinitionConnection`](../object/functiondefinitionconnection.md) | Function definitions of the Node Function | | `id` | [`RuntimeParameterDefinitionID!`](../scalar/runtimeparameterdefinitionid.md) | Global ID of this RuntimeFunctionDefinition | | `updatedAt` | [`Time!`](../scalar/time.md) | Time when this RuntimeFunctionDefinition was last updated | diff --git a/docs/graphql/scalar/functiondefinitionid.md b/docs/graphql/scalar/functiondefinitionid.md new file mode 100644 index 00000000..63e59947 --- /dev/null +++ b/docs/graphql/scalar/functiondefinitionid.md @@ -0,0 +1,5 @@ +--- +title: FunctionDefinitionID +--- + +A unique identifier for all FunctionDefinition entities of the application diff --git a/docs/graphql/scalar/parameterdefinitionid.md b/docs/graphql/scalar/parameterdefinitionid.md new file mode 100644 index 00000000..2a4c3aa5 --- /dev/null +++ b/docs/graphql/scalar/parameterdefinitionid.md @@ -0,0 +1,5 @@ +--- +title: ParameterDefinitionID +--- + +A unique identifier for all ParameterDefinition entities of the application diff --git a/spec/factories/parameter_definitions.rb b/spec/factories/parameter_definitions.rb index bb322505..8f41d2d1 100644 --- a/spec/factories/parameter_definitions.rb +++ b/spec/factories/parameter_definitions.rb @@ -4,5 +4,10 @@ factory :parameter_definition do runtime_parameter_definition data_type + + function_definition do + association :function_definition, + runtime_function_definition: runtime_parameter_definition.runtime_function_definition + end end end diff --git a/spec/graphql/types/function_definition_type_spec.rb b/spec/graphql/types/function_definition_type_spec.rb new file mode 100644 index 00000000..4ca74448 --- /dev/null +++ b/spec/graphql/types/function_definition_type_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe SagittariusSchema.types['FunctionDefinition'] do + let(:fields) do + %w[ + id + returnType + parameterDefinitions + names + descriptions + documentations + createdAt + updatedAt + ] + end + + it { expect(described_class.graphql_name).to eq('FunctionDefinition') } + it { expect(described_class).to have_graphql_fields(fields) } + it { expect(described_class).to require_graphql_authorizations(:read_function_definition) } +end diff --git a/spec/graphql/types/parameter_definition_type_spec.rb b/spec/graphql/types/parameter_definition_type_spec.rb new file mode 100644 index 00000000..3903cac2 --- /dev/null +++ b/spec/graphql/types/parameter_definition_type_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe SagittariusSchema.types['ParameterDefinition'] do + let(:fields) do + %w[ + id + dataType + descriptions + names + documentations + createdAt + updatedAt + ] + end + + it { expect(described_class.graphql_name).to eq('ParameterDefinition') } + it { expect(described_class).to have_graphql_fields(fields) } + it { expect(described_class).to require_graphql_authorizations(:read_parameter_definition) } +end diff --git a/spec/graphql/types/runtime_function_definition_type_spec.rb b/spec/graphql/types/runtime_function_definition_type_spec.rb new file mode 100644 index 00000000..7cb9e921 --- /dev/null +++ b/spec/graphql/types/runtime_function_definition_type_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe SagittariusSchema.types['RuntimeFunctionDefinition'] do + let(:fields) do + %w[ + id + functionDefinitions + createdAt + updatedAt + ] + end + + it { expect(described_class.graphql_name).to eq('RuntimeFunctionDefinition') } + it { expect(described_class).to have_graphql_fields(fields) } + it { expect(described_class).to require_graphql_authorizations(:read_flow) } +end diff --git a/spec/graphql/types/runtime_parameter_definition_type_spec.rb b/spec/graphql/types/runtime_parameter_definition_type_spec.rb new file mode 100644 index 00000000..b087e41a --- /dev/null +++ b/spec/graphql/types/runtime_parameter_definition_type_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe SagittariusSchema.types['RuntimeParameterDefinition'] do + let(:fields) do + %w[ + id + createdAt + updatedAt + ] + end + + it { expect(described_class.graphql_name).to eq('RuntimeParameterDefinition') } + it { expect(described_class).to have_graphql_fields(fields) } + it { expect(described_class).to require_graphql_authorizations(:read_flow) } +end