From a93e3d33470810608bbdcbf06e324f20f238e533 Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 21 May 2026 20:24:18 +0200 Subject: [PATCH 1/3] feat: added migration for propper runtime status --- ...a_runtime_statuses_into_concrete_tables.rb | 71 +++++++ db/structure.sql | 200 +++++++++++++----- 2 files changed, 214 insertions(+), 57 deletions(-) create mode 100644 db/migrate/20260520121000_split_tucana_runtime_statuses_into_concrete_tables.rb diff --git a/db/migrate/20260520121000_split_tucana_runtime_statuses_into_concrete_tables.rb b/db/migrate/20260520121000_split_tucana_runtime_statuses_into_concrete_tables.rb new file mode 100644 index 00000000..4e5a3176 --- /dev/null +++ b/db/migrate/20260520121000_split_tucana_runtime_statuses_into_concrete_tables.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +class SplitTucanaRuntimeStatusesIntoConcreteTables < Code0::ZeroTrack::Database::Migration[1.0] + def change + create_table :adapter_runtime_statuses do |t| + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + t.integer :status, null: false, default: 0 + t.datetime_with_timezone :last_heartbeat + t.text :identifier, null: false + + t.index %i[runtime_id identifier], unique: true + + t.timestamps_with_timezone + end + + create_table :adapter_status_configurations do |t| + t.references :adapter_runtime_status, null: false, + foreign_key: { to_table: :adapter_runtime_statuses, on_delete: :cascade } + t.text :flow_type_identifiers, array: true, null: false, default: [] + t.text :endpoint + + t.timestamps_with_timezone + end + + create_table :execution_runtime_statuses do |t| + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + t.integer :status, null: false, default: 0 + t.datetime_with_timezone :last_heartbeat + t.text :identifier, null: false + + t.index %i[runtime_id identifier], unique: true + + t.timestamps_with_timezone + end + + create_table :action_statuses do |t| + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + t.integer :status, null: false, default: 0 + t.datetime_with_timezone :last_heartbeat + t.text :identifier, null: false + + t.index %i[runtime_id identifier], unique: true + + t.timestamps_with_timezone + end + + create_table :action_status_configurations do |t| + t.references :action_status, null: false, foreign_key: { to_table: :action_statuses, on_delete: :cascade } + t.text :flow_type_identifiers, array: true, null: false, default: [] + t.text :endpoint + + t.timestamps_with_timezone + end + + drop_table :runtime_status_configurations do |t| + t.references :runtime_status, null: false, + foreign_key: { to_table: :runtime_statuses, on_delete: :cascade } + t.text :endpoint, null: false + t.timestamps_with_timezone + end + + drop_table :runtime_statuses do |t| + t.references :runtime, null: false, foreign_key: { to_table: :runtimes, on_delete: :cascade } + t.integer :status, null: false, default: 0 + t.integer :status_type, null: false, default: 0 + t.datetime_with_timezone :last_heartbeat + t.text :identifier, null: false + t.timestamps_with_timezone + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 0375537b..e1c01735 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -56,6 +56,80 @@ CREATE SEQUENCE active_storage_variant_records_id_seq ALTER SEQUENCE active_storage_variant_records_id_seq OWNED BY active_storage_variant_records.id; +CREATE TABLE action_status_configurations ( + id bigint NOT NULL, + action_status_id bigint NOT NULL, + flow_type_identifiers text[] DEFAULT '{}'::text[] NOT NULL, + endpoint text, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE action_status_configurations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE action_status_configurations_id_seq OWNED BY action_status_configurations.id; + +CREATE TABLE action_statuses ( + id bigint NOT NULL, + runtime_id bigint NOT NULL, + status integer DEFAULT 0 NOT NULL, + last_heartbeat timestamp with time zone, + identifier text NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE action_statuses_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE action_statuses_id_seq OWNED BY action_statuses.id; + +CREATE TABLE adapter_runtime_statuses ( + id bigint NOT NULL, + runtime_id bigint NOT NULL, + status integer DEFAULT 0 NOT NULL, + last_heartbeat timestamp with time zone, + identifier text NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE adapter_runtime_statuses_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE adapter_runtime_statuses_id_seq OWNED BY adapter_runtime_statuses.id; + +CREATE TABLE adapter_status_configurations ( + id bigint NOT NULL, + adapter_runtime_status_id bigint NOT NULL, + flow_type_identifiers text[] DEFAULT '{}'::text[] NOT NULL, + endpoint text, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE adapter_status_configurations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE adapter_status_configurations_id_seq OWNED BY adapter_status_configurations.id; + CREATE TABLE application_settings ( id bigint NOT NULL, setting integer NOT NULL, @@ -182,6 +256,25 @@ CREATE SEQUENCE data_types_id_seq ALTER SEQUENCE data_types_id_seq OWNED BY data_types.id; +CREATE TABLE execution_runtime_statuses ( + id bigint NOT NULL, + runtime_id bigint NOT NULL, + status integer DEFAULT 0 NOT NULL, + last_heartbeat timestamp with time zone, + identifier text NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE execution_runtime_statuses_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE execution_runtime_statuses_id_seq OWNED BY execution_runtime_statuses.id; + CREATE TABLE flow_data_type_links ( id bigint NOT NULL, flow_id bigint NOT NULL, @@ -882,43 +975,6 @@ CREATE SEQUENCE runtime_parameter_definitions_id_seq ALTER SEQUENCE runtime_parameter_definitions_id_seq OWNED BY runtime_parameter_definitions.id; -CREATE TABLE runtime_status_configurations ( - id bigint NOT NULL, - runtime_status_id bigint NOT NULL, - endpoint text NOT NULL, - created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL -); - -CREATE SEQUENCE runtime_status_configurations_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -ALTER SEQUENCE runtime_status_configurations_id_seq OWNED BY runtime_status_configurations.id; - -CREATE TABLE runtime_statuses ( - id bigint NOT NULL, - runtime_id bigint NOT NULL, - status integer DEFAULT 0 NOT NULL, - status_type integer DEFAULT 0 NOT NULL, - last_heartbeat timestamp with time zone, - identifier text NOT NULL, - created_at timestamp with time zone NOT NULL, - updated_at timestamp with time zone NOT NULL -); - -CREATE SEQUENCE runtime_statuses_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -ALTER SEQUENCE runtime_statuses_id_seq OWNED BY runtime_statuses.id; - CREATE TABLE runtimes ( id bigint NOT NULL, name text NOT NULL, @@ -1036,6 +1092,14 @@ ALTER TABLE ONLY active_storage_blobs ALTER COLUMN id SET DEFAULT nextval('activ ALTER TABLE ONLY active_storage_variant_records ALTER COLUMN id SET DEFAULT nextval('active_storage_variant_records_id_seq'::regclass); +ALTER TABLE ONLY action_status_configurations ALTER COLUMN id SET DEFAULT nextval('action_status_configurations_id_seq'::regclass); + +ALTER TABLE ONLY action_statuses ALTER COLUMN id SET DEFAULT nextval('action_statuses_id_seq'::regclass); + +ALTER TABLE ONLY adapter_runtime_statuses ALTER COLUMN id SET DEFAULT nextval('adapter_runtime_statuses_id_seq'::regclass); + +ALTER TABLE ONLY adapter_status_configurations ALTER COLUMN id SET DEFAULT nextval('adapter_status_configurations_id_seq'::regclass); + ALTER TABLE ONLY application_settings ALTER COLUMN id SET DEFAULT nextval('application_settings_id_seq'::regclass); ALTER TABLE ONLY audit_events ALTER COLUMN id SET DEFAULT nextval('audit_events_id_seq'::regclass); @@ -1048,6 +1112,8 @@ ALTER TABLE ONLY data_type_rules ALTER COLUMN id SET DEFAULT nextval('data_type_ ALTER TABLE ONLY data_types ALTER COLUMN id SET DEFAULT nextval('data_types_id_seq'::regclass); +ALTER TABLE ONLY execution_runtime_statuses ALTER COLUMN id SET DEFAULT nextval('execution_runtime_statuses_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); @@ -1110,10 +1176,6 @@ ALTER TABLE ONLY runtime_modules ALTER COLUMN id SET DEFAULT nextval('runtime_mo ALTER TABLE ONLY runtime_parameter_definitions ALTER COLUMN id SET DEFAULT nextval('runtime_parameter_definitions_id_seq'::regclass); -ALTER TABLE ONLY runtime_status_configurations ALTER COLUMN id SET DEFAULT nextval('runtime_status_configurations_id_seq'::regclass); - -ALTER TABLE ONLY runtime_statuses ALTER COLUMN id SET DEFAULT nextval('runtime_statuses_id_seq'::regclass); - ALTER TABLE ONLY runtimes ALTER COLUMN id SET DEFAULT nextval('runtimes_id_seq'::regclass); ALTER TABLE ONLY translations ALTER COLUMN id SET DEFAULT nextval('translations_id_seq'::regclass); @@ -1133,6 +1195,18 @@ ALTER TABLE ONLY active_storage_blobs ALTER TABLE ONLY active_storage_variant_records ADD CONSTRAINT active_storage_variant_records_pkey PRIMARY KEY (id); +ALTER TABLE ONLY action_status_configurations + ADD CONSTRAINT action_status_configurations_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY action_statuses + ADD CONSTRAINT action_statuses_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY adapter_runtime_statuses + ADD CONSTRAINT adapter_runtime_statuses_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY adapter_status_configurations + ADD CONSTRAINT adapter_status_configurations_pkey PRIMARY KEY (id); + ALTER TABLE ONLY application_settings ADD CONSTRAINT application_settings_pkey PRIMARY KEY (id); @@ -1154,6 +1228,9 @@ ALTER TABLE ONLY data_type_rules ALTER TABLE ONLY data_types ADD CONSTRAINT data_types_pkey PRIMARY KEY (id); +ALTER TABLE ONLY execution_runtime_statuses + ADD CONSTRAINT execution_runtime_statuses_pkey PRIMARY KEY (id); + ALTER TABLE ONLY flow_data_type_links ADD CONSTRAINT flow_data_type_links_pkey PRIMARY KEY (id); @@ -1262,12 +1339,6 @@ ALTER TABLE ONLY runtime_modules ALTER TABLE ONLY runtime_parameter_definitions ADD CONSTRAINT runtime_parameter_definitions_pkey PRIMARY KEY (id); -ALTER TABLE ONLY runtime_status_configurations - ADD CONSTRAINT runtime_status_configurations_pkey PRIMARY KEY (id); - -ALTER TABLE ONLY runtime_statuses - ADD CONSTRAINT runtime_statuses_pkey PRIMARY KEY (id); - ALTER TABLE ONLY runtimes ADD CONSTRAINT runtimes_pkey PRIMARY KEY (id); @@ -1332,6 +1403,14 @@ CREATE UNIQUE INDEX index_active_storage_blobs_on_key ON active_storage_blobs US CREATE UNIQUE INDEX index_active_storage_variant_records_uniqueness ON active_storage_variant_records USING btree (blob_id, variation_digest); +CREATE INDEX index_action_status_configurations_on_action_status_id ON action_status_configurations USING btree (action_status_id); + +CREATE UNIQUE INDEX index_action_statuses_on_runtime_id_and_identifier ON action_statuses USING btree (runtime_id, identifier); + +CREATE UNIQUE INDEX index_adapter_runtime_statuses_on_runtime_id_and_identifier ON adapter_runtime_statuses USING btree (runtime_id, identifier); + +CREATE INDEX index_adapter_status_configurations_on_adapter_runtime_status_id ON adapter_status_configurations USING btree (adapter_runtime_status_id); + CREATE UNIQUE INDEX index_application_settings_on_setting ON application_settings USING btree (setting); CREATE INDEX index_audit_events_on_author_id ON audit_events USING btree (author_id); @@ -1342,6 +1421,8 @@ CREATE INDEX index_data_type_rules_on_data_type_id ON data_type_rules USING btre CREATE UNIQUE INDEX index_data_types_on_runtime_id_and_identifier ON data_types USING btree (runtime_id, identifier); +CREATE UNIQUE INDEX index_execution_runtime_statuses_on_runtime_id_and_identifier ON execution_runtime_statuses USING btree (runtime_id, identifier); + CREATE INDEX index_flow_settings_on_flow_id ON flow_settings USING btree (flow_id); CREATE UNIQUE INDEX index_flow_type_settings_on_flow_type_id_and_identifier ON flow_type_settings USING btree (flow_type_id, identifier); @@ -1462,10 +1543,6 @@ CREATE INDEX index_reference_values_on_node_parameter_id ON reference_values USI CREATE UNIQUE INDEX index_runtime_flow_types_on_runtime_id_and_identifier ON runtime_flow_types USING btree (runtime_id, identifier); -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); - CREATE INDEX index_runtimes_on_namespace_id ON runtimes USING btree (namespace_id); CREATE UNIQUE INDEX index_runtimes_on_token ON runtimes USING btree (token); @@ -1488,6 +1565,21 @@ 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 action_status_configurations + ADD CONSTRAINT fk_action_status_configurations_action_status FOREIGN KEY (action_status_id) REFERENCES action_statuses(id) ON DELETE CASCADE; + +ALTER TABLE ONLY action_statuses + ADD CONSTRAINT fk_action_statuses_runtime FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + +ALTER TABLE ONLY adapter_runtime_statuses + ADD CONSTRAINT fk_adapter_runtime_statuses_runtime FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + +ALTER TABLE ONLY adapter_status_configurations + ADD CONSTRAINT fk_adapter_status_configurations_adapter_runtime_status FOREIGN KEY (adapter_runtime_status_id) REFERENCES adapter_runtime_statuses(id) ON DELETE CASCADE; + +ALTER TABLE ONLY execution_runtime_statuses + ADD CONSTRAINT fk_execution_runtime_statuses_runtime FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; + ALTER TABLE ONLY node_parameters ADD CONSTRAINT fk_rails_0d79310cfa FOREIGN KEY (node_function_id) REFERENCES node_functions(id) ON DELETE CASCADE; @@ -1524,9 +1616,6 @@ ALTER TABLE ONLY runtime_flow_type_data_type_links ALTER TABLE ONLY licenses ADD CONSTRAINT fk_rails_38f693332d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; -ALTER TABLE ONLY runtime_statuses - ADD CONSTRAINT fk_rails_3af887feb9 FOREIGN KEY (runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE; - ALTER TABLE ONLY parameter_definitions ADD CONSTRAINT fk_rails_3b02763f84 FOREIGN KEY (runtime_parameter_definition_id) REFERENCES runtime_parameter_definitions(id) ON DELETE CASCADE; @@ -1650,9 +1739,6 @@ ALTER TABLE ONLY namespace_project_runtime_assignments ALTER TABLE ONLY runtime_function_definitions ADD CONSTRAINT fk_rails_d2d9392ab1 FOREIGN KEY (runtime_module_id) REFERENCES runtime_modules(id) ON DELETE CASCADE; -ALTER TABLE ONLY runtime_status_configurations - ADD CONSTRAINT fk_rails_d3eeb850ed FOREIGN KEY (runtime_status_id) REFERENCES runtime_statuses(id) ON DELETE CASCADE; - ALTER TABLE ONLY namespace_projects ADD CONSTRAINT fk_rails_d4f50e2f00 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; From 4ec63c20a7276cc1f0c7b97434471a1a63d3be96 Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 21 May 2026 20:24:45 +0200 Subject: [PATCH 2/3] feat: adjusted services with latest runtime stauts --- ...tion_status_configuration_endpoint_type.rb | 17 +++++ app/graphql/types/action_status_type.rb | 33 ++++++++++ .../types/adapter_runtime_status_type.rb | 33 ++++++++++ ...pter_status_configuration_endpoint_type.rb | 17 +++++ .../types/execution_runtime_status_type.rb | 29 ++++++++ ...time_status_configuration_endpoint_type.rb | 14 ---- .../runtime_status_configuration_type.rb | 5 +- .../types/runtime_status_status_enum.rb | 1 + app/graphql/types/runtime_status_type.rb | 36 ++++------ app/graphql/types/runtime_status_type_enum.rb | 1 + app/graphql/types/runtime_type.rb | 2 +- app/grpc/runtime_status_handler.rb | 4 +- app/models/action_status.rb | 11 ++++ app/models/action_status_configuration.rb | 5 ++ app/models/adapter_runtime_status.rb | 11 ++++ app/models/adapter_status_configuration.rb | 5 ++ app/models/concerns/runtime_status_fields.rb | 23 +++++++ app/models/execution_runtime_status.rb | 5 ++ app/models/runtime.rb | 12 +++- app/models/runtime_status.rb | 37 ----------- app/models/runtime_status_configuration.rb | 8 --- .../action_status_configuration_policy.rb | 5 ++ ...atus_policy.rb => action_status_policy.rb} | 2 +- app/policies/adapter_runtime_status_policy.rb | 5 ++ .../adapter_status_configuration_policy.rb | 5 ++ .../execution_runtime_status_policy.rb | 5 ++ .../runtime_status_configuration_policy.rb | 5 -- .../grpc/runtime_status_update_service.rb | 45 +++++++++---- docs/graphql/enum/runtimestatusstatus.md | 1 + docs/graphql/enum/runtimestatustype.md | 1 + docs/graphql/object/actionstatus.md | 18 +++++ .../actionstatusconfigurationendpoint.md | 15 +++++ docs/graphql/object/adapterruntimestatus.md | 18 +++++ .../adapterstatusconfigurationendpoint.md | 15 +++++ docs/graphql/object/executionruntimestatus.md | 17 +++++ docs/graphql/object/runtimestatus.md | 18 ----- .../runtimestatusconfigurationendpoint.md | 14 ---- .../graphql/object/runtimestatusconnection.md | 2 +- docs/graphql/object/runtimestatusedge.md | 2 +- .../scalar/actionstatusconfigurationid.md | 5 ++ docs/graphql/scalar/actionstatusid.md | 5 ++ docs/graphql/scalar/adapterruntimestatusid.md | 5 ++ .../scalar/adapterstatusconfigurationid.md | 5 ++ .../scalar/executionruntimestatusid.md | 5 ++ .../scalar/runtimestatusconfigurationid.md | 5 -- docs/graphql/scalar/runtimestatusid.md | 5 -- docs/graphql/union/runtimestatus.md | 11 ++++ .../union/runtimestatusconfiguration.md | 3 +- .../factories/action_status_configurations.rb | 9 +++ .../{runtime_status.rb => action_statuses.rb} | 3 +- spec/factories/adapter_runtime_statuses.rb | 10 +++ .../adapter_status_configurations.rb | 9 +++ spec/factories/execution_runtime_statuses.rb | 10 +++ .../factories/runtime_status_configuration.rb | 8 --- .../graphql/types/runtime_status_type_spec.rb | 23 +++---- .../action_status_configuration_spec.rb | 11 ++++ spec/models/action_status_spec.rb | 20 ++++++ spec/models/adapter_runtime_status_spec.rb | 20 ++++++ .../adapter_status_configuration_spec.rb | 11 ++++ spec/models/execution_runtime_status_spec.rb | 11 ++++ spec/models/runtime_spec.rb | 4 +- spec/models/runtime_status_spec.rb | 36 ---------- .../runtime_status_service_spec.rb | 66 ++++++++++++++----- 63 files changed, 574 insertions(+), 228 deletions(-) create mode 100644 app/graphql/types/action_status_configuration_endpoint_type.rb create mode 100644 app/graphql/types/action_status_type.rb create mode 100644 app/graphql/types/adapter_runtime_status_type.rb create mode 100644 app/graphql/types/adapter_status_configuration_endpoint_type.rb create mode 100644 app/graphql/types/execution_runtime_status_type.rb delete mode 100644 app/graphql/types/runtime_status_configuration_endpoint_type.rb create mode 100644 app/models/action_status.rb create mode 100644 app/models/action_status_configuration.rb create mode 100644 app/models/adapter_runtime_status.rb create mode 100644 app/models/adapter_status_configuration.rb create mode 100644 app/models/concerns/runtime_status_fields.rb create mode 100644 app/models/execution_runtime_status.rb delete mode 100644 app/models/runtime_status.rb delete mode 100644 app/models/runtime_status_configuration.rb create mode 100644 app/policies/action_status_configuration_policy.rb rename app/policies/{runtime_status_policy.rb => action_status_policy.rb} (62%) create mode 100644 app/policies/adapter_runtime_status_policy.rb create mode 100644 app/policies/adapter_status_configuration_policy.rb create mode 100644 app/policies/execution_runtime_status_policy.rb delete mode 100644 app/policies/runtime_status_configuration_policy.rb create mode 100644 docs/graphql/object/actionstatus.md create mode 100644 docs/graphql/object/actionstatusconfigurationendpoint.md create mode 100644 docs/graphql/object/adapterruntimestatus.md create mode 100644 docs/graphql/object/adapterstatusconfigurationendpoint.md create mode 100644 docs/graphql/object/executionruntimestatus.md delete mode 100644 docs/graphql/object/runtimestatus.md delete mode 100644 docs/graphql/object/runtimestatusconfigurationendpoint.md create mode 100644 docs/graphql/scalar/actionstatusconfigurationid.md create mode 100644 docs/graphql/scalar/actionstatusid.md create mode 100644 docs/graphql/scalar/adapterruntimestatusid.md create mode 100644 docs/graphql/scalar/adapterstatusconfigurationid.md create mode 100644 docs/graphql/scalar/executionruntimestatusid.md delete mode 100644 docs/graphql/scalar/runtimestatusconfigurationid.md delete mode 100644 docs/graphql/scalar/runtimestatusid.md create mode 100644 docs/graphql/union/runtimestatus.md create mode 100644 spec/factories/action_status_configurations.rb rename spec/factories/{runtime_status.rb => action_statuses.rb} (75%) create mode 100644 spec/factories/adapter_runtime_statuses.rb create mode 100644 spec/factories/adapter_status_configurations.rb create mode 100644 spec/factories/execution_runtime_statuses.rb delete mode 100644 spec/factories/runtime_status_configuration.rb create mode 100644 spec/models/action_status_configuration_spec.rb create mode 100644 spec/models/action_status_spec.rb create mode 100644 spec/models/adapter_runtime_status_spec.rb create mode 100644 spec/models/adapter_status_configuration_spec.rb create mode 100644 spec/models/execution_runtime_status_spec.rb delete mode 100644 spec/models/runtime_status_spec.rb diff --git a/app/graphql/types/action_status_configuration_endpoint_type.rb b/app/graphql/types/action_status_configuration_endpoint_type.rb new file mode 100644 index 00000000..5d3fc8f3 --- /dev/null +++ b/app/graphql/types/action_status_configuration_endpoint_type.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Types + class ActionStatusConfigurationEndpointType < Types::BaseObject + description 'Detailed information about an action status' + + authorize :read_runtime + + field :endpoint, String, null: true, description: 'The endpoint URL of the action' + field :flow_type_identifiers, [String], + null: false, + description: 'The flow type identifiers handled by this configuration' + + id_field ActionStatusConfiguration + timestamps + end +end diff --git a/app/graphql/types/action_status_type.rb b/app/graphql/types/action_status_type.rb new file mode 100644 index 00000000..84a0cb4d --- /dev/null +++ b/app/graphql/types/action_status_type.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Types + class ActionStatusType < Types::BaseObject + description 'An action status information entry' + + authorize :read_runtime + + field :configurations, Types::RuntimeStatusConfigurationType.connection_type, + null: false, + description: 'The detailed configuration entries for this action status', + method: :action_status_configurations + field :identifier, String, + null: false, + description: 'The unique identifier for this action status' + field :last_heartbeat, Types::TimeType, + null: true, + description: 'The timestamp of the last heartbeat received from the runtime' + field :status, Types::RuntimeStatusStatusEnum, + null: false, + description: 'The current action status' + field :type, Types::RuntimeStatusTypeEnum, + null: false, + description: 'The type of runtime status information' + + def type + :action + end + + id_field ActionStatus + timestamps + end +end diff --git a/app/graphql/types/adapter_runtime_status_type.rb b/app/graphql/types/adapter_runtime_status_type.rb new file mode 100644 index 00000000..db863d14 --- /dev/null +++ b/app/graphql/types/adapter_runtime_status_type.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Types + class AdapterRuntimeStatusType < Types::BaseObject + description 'An adapter runtime status information entry' + + authorize :read_runtime + + field :configurations, Types::RuntimeStatusConfigurationType.connection_type, + null: false, + description: 'The detailed configuration entries for this adapter status', + method: :adapter_status_configurations + field :identifier, String, + null: false, + description: 'The unique identifier for this adapter status' + field :last_heartbeat, Types::TimeType, + null: true, + description: 'The timestamp of the last heartbeat received from the runtime' + field :status, Types::RuntimeStatusStatusEnum, + null: false, + description: 'The current adapter status' + field :type, Types::RuntimeStatusTypeEnum, + null: false, + description: 'The type of runtime status information' + + def type + :adapter + end + + id_field AdapterRuntimeStatus + timestamps + end +end diff --git a/app/graphql/types/adapter_status_configuration_endpoint_type.rb b/app/graphql/types/adapter_status_configuration_endpoint_type.rb new file mode 100644 index 00000000..fccceac8 --- /dev/null +++ b/app/graphql/types/adapter_status_configuration_endpoint_type.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Types + class AdapterStatusConfigurationEndpointType < Types::BaseObject + description 'Detailed information about an adapter status' + + authorize :read_runtime + + field :endpoint, String, null: true, description: 'The endpoint URL of the adapter' + field :flow_type_identifiers, [String], + null: false, + description: 'The flow type identifiers handled by this configuration' + + id_field ::AdapterStatusConfiguration + timestamps + end +end diff --git a/app/graphql/types/execution_runtime_status_type.rb b/app/graphql/types/execution_runtime_status_type.rb new file mode 100644 index 00000000..5bb5a318 --- /dev/null +++ b/app/graphql/types/execution_runtime_status_type.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Types + class ExecutionRuntimeStatusType < Types::BaseObject + description 'An execution runtime status information entry' + + authorize :read_runtime + + field :identifier, String, + null: false, + description: 'The unique identifier for this execution status' + field :last_heartbeat, Types::TimeType, + null: true, + description: 'The timestamp of the last heartbeat received from the runtime' + field :status, Types::RuntimeStatusStatusEnum, + null: false, + description: 'The current execution status' + field :type, Types::RuntimeStatusTypeEnum, + null: false, + description: 'The type of runtime status information' + + def type + :execution + end + + id_field ExecutionRuntimeStatus + timestamps + end +end diff --git a/app/graphql/types/runtime_status_configuration_endpoint_type.rb b/app/graphql/types/runtime_status_configuration_endpoint_type.rb deleted file mode 100644 index efa2c069..00000000 --- a/app/graphql/types/runtime_status_configuration_endpoint_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module Types - class RuntimeStatusConfigurationEndpointType < Types::BaseObject - description 'Detailed information about a runtime status' - - authorize :read_runtime - - field :endpoint, String, null: false, description: 'The endpoint URL of the runtime' - - id_field ::RuntimeStatusConfiguration - timestamps - end -end diff --git a/app/graphql/types/runtime_status_configuration_type.rb b/app/graphql/types/runtime_status_configuration_type.rb index 52fa7966..61d60cd4 100644 --- a/app/graphql/types/runtime_status_configuration_type.rb +++ b/app/graphql/types/runtime_status_configuration_type.rb @@ -4,10 +4,11 @@ module Types class RuntimeStatusConfigurationType < Types::BaseUnion description 'Detailed configuration about a runtime status, either: endpoint, ...' - possible_types Types::RuntimeStatusConfigurationEndpointType + possible_types Types::ActionStatusConfigurationEndpointType, Types::AdapterStatusConfigurationEndpointType def self.resolve_type(object, _context) - return Types::RuntimeStatusConfigurationEndpointType if object.endpoint.present? + return Types::AdapterStatusConfigurationEndpointType if object.is_a?(AdapterStatusConfiguration) + return Types::ActionStatusConfigurationEndpointType if object.is_a?(ActionStatusConfiguration) raise "Unknown RuntimeStatusInformation type: #{object.class.name}" end diff --git a/app/graphql/types/runtime_status_status_enum.rb b/app/graphql/types/runtime_status_status_enum.rb index 2eb2c7c5..23d1584d 100644 --- a/app/graphql/types/runtime_status_status_enum.rb +++ b/app/graphql/types/runtime_status_status_enum.rb @@ -4,6 +4,7 @@ module Types class RuntimeStatusStatusEnum < Types::BaseEnum description 'The enum status of the detailed status' + value :UNKNOWN, 'The runtime status is unknown', value: 'unknown' value :NOT_RESPONDING, 'The runtime is not responding to heartbeats', value: 'not_responding' value :NOT_READY, 'The runtime is not ready to compute stuff', value: 'not_ready' value :RUNNING, 'The runtime is running and healthy', value: 'running' diff --git a/app/graphql/types/runtime_status_type.rb b/app/graphql/types/runtime_status_type.rb index 60996717..0389f8ae 100644 --- a/app/graphql/types/runtime_status_type.rb +++ b/app/graphql/types/runtime_status_type.rb @@ -1,30 +1,22 @@ # frozen_string_literal: true module Types - class RuntimeStatusType < Types::BaseObject + class RuntimeStatusType < Types::BaseUnion description 'A runtime status information entry' - authorize :read_runtime + possible_types Types::ActionStatusType, Types::AdapterRuntimeStatusType, Types::ExecutionRuntimeStatusType - field :configurations, Types::RuntimeStatusConfigurationType.connection_type, - null: false, - description: 'The detailed configuration entries for this runtime status (only for adapters)', - method: :runtime_status_configurations - field :identifier, String, - null: false, - description: 'The unique identifier for this runtime status' - field :last_heartbeat, Types::TimeType, - null: true, - description: 'The timestamp of the last heartbeat received from the runtime' - field :status, Types::RuntimeStatusStatusEnum, - null: false, - description: 'The current status of the runtime (e.g. running, stopped)' - field :type, Types::RuntimeStatusTypeEnum, - null: false, - description: 'The type of runtime status information (e.g. adapter, execution)', - method: :status_type - - id_field RuntimeStatus - timestamps + def self.resolve_type(object, _context) + case object + when ActionStatus + Types::ActionStatusType + when AdapterRuntimeStatus + Types::AdapterRuntimeStatusType + when ExecutionRuntimeStatus + Types::ExecutionRuntimeStatusType + else + raise "Unknown RuntimeStatus type: #{object.class.name}" + end + end end end diff --git a/app/graphql/types/runtime_status_type_enum.rb b/app/graphql/types/runtime_status_type_enum.rb index fb0ee092..8878906d 100644 --- a/app/graphql/types/runtime_status_type_enum.rb +++ b/app/graphql/types/runtime_status_type_enum.rb @@ -5,6 +5,7 @@ class RuntimeStatusTypeEnum < Types::BaseEnum description 'The type of runtime status' value :ADAPTER, 'Indicates that the runtime status is related to an adapter.', value: 'adapter' + value :ACTION, 'Indicates that the runtime status is related to an action.', value: 'action' value :EXECUTION, 'Indicates that the runtime status is related to an execution.', value: 'execution' end end diff --git a/app/graphql/types/runtime_type.rb b/app/graphql/types/runtime_type.rb index 02f089d5..6d518fa9 100644 --- a/app/graphql/types/runtime_type.rb +++ b/app/graphql/types/runtime_type.rb @@ -17,7 +17,7 @@ class RuntimeType < Types::BaseObject field :statuses, Types::RuntimeStatusType.connection_type, null: false, description: 'Statuses of the runtime', - method: :runtime_statuses + method: :statuses field :token, String, null: true, description: 'Token belonging to the runtime, only present on creation' expose_abilities %i[ diff --git a/app/grpc/runtime_status_handler.rb b/app/grpc/runtime_status_handler.rb index 09920634..dfd4ca4c 100644 --- a/app/grpc/runtime_status_handler.rb +++ b/app/grpc/runtime_status_handler.rb @@ -11,6 +11,8 @@ def update(request, _call) request.adapter_runtime_status when :execution_runtime_status request.execution_runtime_status + when :action_status + request.action_status else return Tucana::Sagittarius::RuntimeStatusUpdateResponse.new(success: false) end @@ -20,7 +22,7 @@ def update(request, _call) status_info: status_info ).execute - logger.debug("RuntimeFunctionHandler#update response: #{response.inspect}") + logger.debug("RuntimeStatusHandler#update response: #{response.inspect}") Tucana::Sagittarius::RuntimeStatusUpdateResponse.new(success: response.success?) end diff --git a/app/models/action_status.rb b/app/models/action_status.rb new file mode 100644 index 00000000..c9cefcb7 --- /dev/null +++ b/app/models/action_status.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class ActionStatus < ApplicationRecord + include RuntimeStatusFields + + has_many :action_status_configurations, inverse_of: :action_status, dependent: :destroy + + def configurations + action_status_configurations + end +end diff --git a/app/models/action_status_configuration.rb b/app/models/action_status_configuration.rb new file mode 100644 index 00000000..678378e8 --- /dev/null +++ b/app/models/action_status_configuration.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ActionStatusConfiguration < ApplicationRecord + belongs_to :action_status, inverse_of: :action_status_configurations +end diff --git a/app/models/adapter_runtime_status.rb b/app/models/adapter_runtime_status.rb new file mode 100644 index 00000000..dbb8f468 --- /dev/null +++ b/app/models/adapter_runtime_status.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class AdapterRuntimeStatus < ApplicationRecord + include RuntimeStatusFields + + has_many :adapter_status_configurations, inverse_of: :adapter_runtime_status, dependent: :destroy + + def configurations + adapter_status_configurations + end +end diff --git a/app/models/adapter_status_configuration.rb b/app/models/adapter_status_configuration.rb new file mode 100644 index 00000000..a43f97d1 --- /dev/null +++ b/app/models/adapter_status_configuration.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class AdapterStatusConfiguration < ApplicationRecord + belongs_to :adapter_runtime_status, inverse_of: :adapter_status_configurations +end diff --git a/app/models/concerns/runtime_status_fields.rb b/app/models/concerns/runtime_status_fields.rb new file mode 100644 index 00000000..ca01ff5b --- /dev/null +++ b/app/models/concerns/runtime_status_fields.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module RuntimeStatusFields + extend ActiveSupport::Concern + + STATUS_TYPES = { + unknown: 0, + not_responding: 1, + not_ready: 2, + running: 3, + stopped: 4, + }.with_indifferent_access + + included do + belongs_to :runtime, inverse_of: model_name.collection.to_sym + + enum :status, STATUS_TYPES, default: :unknown + + validates :identifier, presence: true, + allow_blank: false, + uniqueness: { case_sensitive: false, scope: :runtime_id } + end +end diff --git a/app/models/execution_runtime_status.rb b/app/models/execution_runtime_status.rb new file mode 100644 index 00000000..a8ded4b4 --- /dev/null +++ b/app/models/execution_runtime_status.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ExecutionRuntimeStatus < ApplicationRecord + include RuntimeStatusFields +end diff --git a/app/models/runtime.rb b/app/models/runtime.rb index 9cb85dd8..2faef5ec 100644 --- a/app/models/runtime.rb +++ b/app/models/runtime.rb @@ -7,7 +7,17 @@ class Runtime < ApplicationRecord token_attr :token, prefix: 's_rt_', length: 48 - has_many :runtime_statuses, inverse_of: :runtime + has_many :adapter_runtime_statuses, inverse_of: :runtime + has_many :execution_runtime_statuses, inverse_of: :runtime + has_many :action_statuses, inverse_of: :runtime + + def statuses + [ + *adapter_runtime_statuses, + *execution_runtime_statuses, + *action_statuses + ].sort_by(&:created_at) + end has_many :project_assignments, class_name: 'NamespaceProjectRuntimeAssignment', inverse_of: :runtime has_many :projects, class_name: 'NamespaceProject', through: :project_assignments, source: :namespace_project, diff --git a/app/models/runtime_status.rb b/app/models/runtime_status.rb deleted file mode 100644 index 4144c9ff..00000000 --- a/app/models/runtime_status.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -class RuntimeStatus < ApplicationRecord - belongs_to :runtime, inverse_of: :runtime_statuses - has_many :runtime_status_configurations, inverse_of: :runtime_status - - STATUS_TYPES = { - not_responding: 0, - not_ready: 1, - running: 2, - stopped: 3, - }.with_indifferent_access - - enum :status, STATUS_TYPES, default: :stopped - - STATUS_TYPE_TYPES = { - adapter: 0, - execution: 1, - }.with_indifferent_access - - enum :status_type, STATUS_TYPE_TYPES - - validates :identifier, presence: true, - allow_blank: false, - uniqueness: { case_sensitive: false, scope: :runtime_id } - - validate :runtime_status_configurations_only_for_adapter - - private - - def runtime_status_configurations_only_for_adapter - return if adapter? - return if runtime_status_configurations.empty? - - errors.add(:runtime_status_configurations, :only_allowed_for_adapters) - end -end diff --git a/app/models/runtime_status_configuration.rb b/app/models/runtime_status_configuration.rb deleted file mode 100644 index a1bbb17f..00000000 --- a/app/models/runtime_status_configuration.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -class RuntimeStatusConfiguration < ApplicationRecord - belongs_to :runtime_status, inverse_of: :runtime_status_configurations - - validates :endpoint, presence: true, - allow_blank: false -end diff --git a/app/policies/action_status_configuration_policy.rb b/app/policies/action_status_configuration_policy.rb new file mode 100644 index 00000000..f3136629 --- /dev/null +++ b/app/policies/action_status_configuration_policy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ActionStatusConfigurationPolicy < BasePolicy + delegate { subject.action_status } +end diff --git a/app/policies/runtime_status_policy.rb b/app/policies/action_status_policy.rb similarity index 62% rename from app/policies/runtime_status_policy.rb rename to app/policies/action_status_policy.rb index 37f1b947..8e3064c6 100644 --- a/app/policies/runtime_status_policy.rb +++ b/app/policies/action_status_policy.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -class RuntimeStatusPolicy < BasePolicy +class ActionStatusPolicy < BasePolicy delegate { subject.runtime } end diff --git a/app/policies/adapter_runtime_status_policy.rb b/app/policies/adapter_runtime_status_policy.rb new file mode 100644 index 00000000..a210d1b4 --- /dev/null +++ b/app/policies/adapter_runtime_status_policy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class AdapterRuntimeStatusPolicy < BasePolicy + delegate { subject.runtime } +end diff --git a/app/policies/adapter_status_configuration_policy.rb b/app/policies/adapter_status_configuration_policy.rb new file mode 100644 index 00000000..709b2bac --- /dev/null +++ b/app/policies/adapter_status_configuration_policy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class AdapterStatusConfigurationPolicy < BasePolicy + delegate { subject.adapter_runtime_status } +end diff --git a/app/policies/execution_runtime_status_policy.rb b/app/policies/execution_runtime_status_policy.rb new file mode 100644 index 00000000..e3fd3544 --- /dev/null +++ b/app/policies/execution_runtime_status_policy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ExecutionRuntimeStatusPolicy < BasePolicy + delegate { subject.runtime } +end diff --git a/app/policies/runtime_status_configuration_policy.rb b/app/policies/runtime_status_configuration_policy.rb deleted file mode 100644 index 80b1b324..00000000 --- a/app/policies/runtime_status_configuration_policy.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -class RuntimeStatusConfigurationPolicy < BasePolicy - delegate { subject.runtime_status } -end diff --git a/app/services/runtimes/grpc/runtime_status_update_service.rb b/app/services/runtimes/grpc/runtime_status_update_service.rb index e024dcd1..7530548d 100644 --- a/app/services/runtimes/grpc/runtime_status_update_service.rb +++ b/app/services/runtimes/grpc/runtime_status_update_service.rb @@ -25,19 +25,11 @@ def execute ) end - db_status = runtime.runtime_statuses.find_or_initialize_by(identifier: status_info.identifier) - - db_status.last_heartbeat = Time.zone.at(status_info.timestamp.to_i) - db_status.status_type = if status_info.is_a?(Tucana::Shared::AdapterRuntimeStatus) - :adapter - else - :execution - end + db_status = status_relation.find_or_initialize_by(identifier: status_info.identifier) + db_status.last_heartbeat = Time.zone.at(status_info.timestamp.to_i / 1000.0) db_status.status = status_info.status.downcase - update_configurations(db_status, status_info, t) if status_info.is_a?(Tucana::Shared::AdapterRuntimeStatus) - unless db_status.save t.rollback_and_return! ServiceResponse.error( message: 'Failed to save runtime status', @@ -46,28 +38,53 @@ def execute ) end + update_configurations(db_status, t) + return ServiceResponse.success(message: 'Updated runtime status') end end private - def update_configurations(db_status, status_info, t) - db_configs = db_status.runtime_status_configurations.first(status_info.configurations.size) + def status_relation + case status_info + when Tucana::Shared::AdapterRuntimeStatus + runtime.adapter_runtime_statuses + when Tucana::Shared::ExecutionRuntimeStatus + runtime.execution_runtime_statuses + when Tucana::Shared::ActionStatus + runtime.action_statuses + end + end + + def update_configurations(db_status, t) + case status_info + when Tucana::Shared::AdapterRuntimeStatus + update_configuration_records(db_status.adapter_status_configurations, t) + when Tucana::Shared::ActionStatus + update_configuration_records(db_status.action_status_configurations, t) + end + end + + def update_configuration_records(relation, t) + db_configs = relation.to_a status_info.configurations.each_with_index do |config, index| - db_configs[index] ||= db_status.runtime_status_configurations.build + db_configs[index] ||= relation.build db_configs[index].endpoint = config.endpoint + db_configs[index].flow_type_identifiers = config.flow_type_identifiers.to_a next if db_configs[index].save t.rollback_and_return! ServiceResponse.error( message: 'Failed to save runtime status configuration', error_code: :invalid_runtime_status_configuration, - details: db_configs.errors + details: db_configs[index].errors ) end + + db_configs.drop(status_info.configurations.size).each(&:destroy) end end end diff --git a/docs/graphql/enum/runtimestatusstatus.md b/docs/graphql/enum/runtimestatusstatus.md index 0b95fe30..43b28021 100644 --- a/docs/graphql/enum/runtimestatusstatus.md +++ b/docs/graphql/enum/runtimestatusstatus.md @@ -10,3 +10,4 @@ The enum status of the detailed status | `NOT_RESPONDING` | The runtime is not responding to heartbeats | | `RUNNING` | The runtime is running and healthy | | `STOPPED` | The runtime has been stopped | +| `UNKNOWN` | The runtime status is unknown | diff --git a/docs/graphql/enum/runtimestatustype.md b/docs/graphql/enum/runtimestatustype.md index 01431bfb..d355c025 100644 --- a/docs/graphql/enum/runtimestatustype.md +++ b/docs/graphql/enum/runtimestatustype.md @@ -6,5 +6,6 @@ The type of runtime status | Value | Description | |-------|-------------| +| `ACTION` | Indicates that the runtime status is related to an action. | | `ADAPTER` | Indicates that the runtime status is related to an adapter. | | `EXECUTION` | Indicates that the runtime status is related to an execution. | diff --git a/docs/graphql/object/actionstatus.md b/docs/graphql/object/actionstatus.md new file mode 100644 index 00000000..b1c478e5 --- /dev/null +++ b/docs/graphql/object/actionstatus.md @@ -0,0 +1,18 @@ +--- +title: ActionStatus +--- + +An action status information entry + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `configurations` | [`RuntimeStatusConfigurationConnection!`](../object/runtimestatusconfigurationconnection.md) | The detailed configuration entries for this action status | +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this ActionStatus was created | +| `id` | [`ActionStatusID!`](../scalar/actionstatusid.md) | Global ID of this ActionStatus | +| `identifier` | [`String!`](../scalar/string.md) | The unique identifier for this action status | +| `lastHeartbeat` | [`Time`](../scalar/time.md) | The timestamp of the last heartbeat received from the runtime | +| `status` | [`RuntimeStatusStatus!`](../enum/runtimestatusstatus.md) | The current action status | +| `type` | [`RuntimeStatusType!`](../enum/runtimestatustype.md) | The type of runtime status information | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this ActionStatus was last updated | diff --git a/docs/graphql/object/actionstatusconfigurationendpoint.md b/docs/graphql/object/actionstatusconfigurationendpoint.md new file mode 100644 index 00000000..8fa01c57 --- /dev/null +++ b/docs/graphql/object/actionstatusconfigurationendpoint.md @@ -0,0 +1,15 @@ +--- +title: ActionStatusConfigurationEndpoint +--- + +Detailed information about an action status + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this ActionStatusConfigurationEndpoint was created | +| `endpoint` | [`String`](../scalar/string.md) | The endpoint URL of the action | +| `flowTypeIdentifiers` | [`[String!]!`](../scalar/string.md) | The flow type identifiers handled by this configuration | +| `id` | [`ActionStatusConfigurationID!`](../scalar/actionstatusconfigurationid.md) | Global ID of this ActionStatusConfigurationEndpoint | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this ActionStatusConfigurationEndpoint was last updated | diff --git a/docs/graphql/object/adapterruntimestatus.md b/docs/graphql/object/adapterruntimestatus.md new file mode 100644 index 00000000..d3daf16e --- /dev/null +++ b/docs/graphql/object/adapterruntimestatus.md @@ -0,0 +1,18 @@ +--- +title: AdapterRuntimeStatus +--- + +An adapter runtime status information entry + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `configurations` | [`RuntimeStatusConfigurationConnection!`](../object/runtimestatusconfigurationconnection.md) | The detailed configuration entries for this adapter status | +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this AdapterRuntimeStatus was created | +| `id` | [`AdapterRuntimeStatusID!`](../scalar/adapterruntimestatusid.md) | Global ID of this AdapterRuntimeStatus | +| `identifier` | [`String!`](../scalar/string.md) | The unique identifier for this adapter status | +| `lastHeartbeat` | [`Time`](../scalar/time.md) | The timestamp of the last heartbeat received from the runtime | +| `status` | [`RuntimeStatusStatus!`](../enum/runtimestatusstatus.md) | The current adapter status | +| `type` | [`RuntimeStatusType!`](../enum/runtimestatustype.md) | The type of runtime status information | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this AdapterRuntimeStatus was last updated | diff --git a/docs/graphql/object/adapterstatusconfigurationendpoint.md b/docs/graphql/object/adapterstatusconfigurationendpoint.md new file mode 100644 index 00000000..37252cac --- /dev/null +++ b/docs/graphql/object/adapterstatusconfigurationendpoint.md @@ -0,0 +1,15 @@ +--- +title: AdapterStatusConfigurationEndpoint +--- + +Detailed information about an adapter status + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this AdapterStatusConfigurationEndpoint was created | +| `endpoint` | [`String`](../scalar/string.md) | The endpoint URL of the adapter | +| `flowTypeIdentifiers` | [`[String!]!`](../scalar/string.md) | The flow type identifiers handled by this configuration | +| `id` | [`AdapterStatusConfigurationID!`](../scalar/adapterstatusconfigurationid.md) | Global ID of this AdapterStatusConfigurationEndpoint | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this AdapterStatusConfigurationEndpoint was last updated | diff --git a/docs/graphql/object/executionruntimestatus.md b/docs/graphql/object/executionruntimestatus.md new file mode 100644 index 00000000..d2e8424b --- /dev/null +++ b/docs/graphql/object/executionruntimestatus.md @@ -0,0 +1,17 @@ +--- +title: ExecutionRuntimeStatus +--- + +An execution runtime status information entry + +## Fields without arguments + +| Name | Type | Description | +|------|------|-------------| +| `createdAt` | [`Time!`](../scalar/time.md) | Time when this ExecutionRuntimeStatus was created | +| `id` | [`ExecutionRuntimeStatusID!`](../scalar/executionruntimestatusid.md) | Global ID of this ExecutionRuntimeStatus | +| `identifier` | [`String!`](../scalar/string.md) | The unique identifier for this execution status | +| `lastHeartbeat` | [`Time`](../scalar/time.md) | The timestamp of the last heartbeat received from the runtime | +| `status` | [`RuntimeStatusStatus!`](../enum/runtimestatusstatus.md) | The current execution status | +| `type` | [`RuntimeStatusType!`](../enum/runtimestatustype.md) | The type of runtime status information | +| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this ExecutionRuntimeStatus was last updated | diff --git a/docs/graphql/object/runtimestatus.md b/docs/graphql/object/runtimestatus.md deleted file mode 100644 index 73b85783..00000000 --- a/docs/graphql/object/runtimestatus.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: RuntimeStatus ---- - -A runtime status information entry - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `configurations` | [`RuntimeStatusConfigurationConnection!`](../object/runtimestatusconfigurationconnection.md) | The detailed configuration entries for this runtime status (only for adapters) | -| `createdAt` | [`Time!`](../scalar/time.md) | Time when this RuntimeStatus was created | -| `id` | [`RuntimeStatusID!`](../scalar/runtimestatusid.md) | Global ID of this RuntimeStatus | -| `identifier` | [`String!`](../scalar/string.md) | The unique identifier for this runtime status | -| `lastHeartbeat` | [`Time`](../scalar/time.md) | The timestamp of the last heartbeat received from the runtime | -| `status` | [`RuntimeStatusStatus!`](../enum/runtimestatusstatus.md) | The current status of the runtime (e.g. running, stopped) | -| `type` | [`RuntimeStatusType!`](../enum/runtimestatustype.md) | The type of runtime status information (e.g. adapter, execution) | -| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this RuntimeStatus was last updated | diff --git a/docs/graphql/object/runtimestatusconfigurationendpoint.md b/docs/graphql/object/runtimestatusconfigurationendpoint.md deleted file mode 100644 index 579e7b06..00000000 --- a/docs/graphql/object/runtimestatusconfigurationendpoint.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: RuntimeStatusConfigurationEndpoint ---- - -Detailed information about a runtime status - -## Fields without arguments - -| Name | Type | Description | -|------|------|-------------| -| `createdAt` | [`Time!`](../scalar/time.md) | Time when this RuntimeStatusConfigurationEndpoint was created | -| `endpoint` | [`String!`](../scalar/string.md) | The endpoint URL of the runtime | -| `id` | [`RuntimeStatusConfigurationID!`](../scalar/runtimestatusconfigurationid.md) | Global ID of this RuntimeStatusConfigurationEndpoint | -| `updatedAt` | [`Time!`](../scalar/time.md) | Time when this RuntimeStatusConfigurationEndpoint was last updated | diff --git a/docs/graphql/object/runtimestatusconnection.md b/docs/graphql/object/runtimestatusconnection.md index 6dc179d6..a8e3ff8e 100644 --- a/docs/graphql/object/runtimestatusconnection.md +++ b/docs/graphql/object/runtimestatusconnection.md @@ -10,5 +10,5 @@ The connection type for RuntimeStatus. |------|------|-------------| | `count` | [`Int!`](../scalar/int.md) | Total count of collection. | | `edges` | [`[RuntimeStatusEdge]`](../object/runtimestatusedge.md) | A list of edges. | -| `nodes` | [`[RuntimeStatus]`](../object/runtimestatus.md) | A list of nodes. | +| `nodes` | [`[RuntimeStatus]`](../union/runtimestatus.md) | A list of nodes. | | `pageInfo` | [`PageInfo!`](../object/pageinfo.md) | Information to aid in pagination. | diff --git a/docs/graphql/object/runtimestatusedge.md b/docs/graphql/object/runtimestatusedge.md index 6be43c00..c10c8ef3 100644 --- a/docs/graphql/object/runtimestatusedge.md +++ b/docs/graphql/object/runtimestatusedge.md @@ -9,4 +9,4 @@ An edge in a connection. | Name | Type | Description | |------|------|-------------| | `cursor` | [`String!`](../scalar/string.md) | A cursor for use in pagination. | -| `node` | [`RuntimeStatus`](../object/runtimestatus.md) | The item at the end of the edge. | +| `node` | [`RuntimeStatus`](../union/runtimestatus.md) | The item at the end of the edge. | diff --git a/docs/graphql/scalar/actionstatusconfigurationid.md b/docs/graphql/scalar/actionstatusconfigurationid.md new file mode 100644 index 00000000..462047f5 --- /dev/null +++ b/docs/graphql/scalar/actionstatusconfigurationid.md @@ -0,0 +1,5 @@ +--- +title: ActionStatusConfigurationID +--- + +A unique identifier for all ActionStatusConfiguration entities of the application diff --git a/docs/graphql/scalar/actionstatusid.md b/docs/graphql/scalar/actionstatusid.md new file mode 100644 index 00000000..c75e083e --- /dev/null +++ b/docs/graphql/scalar/actionstatusid.md @@ -0,0 +1,5 @@ +--- +title: ActionStatusID +--- + +A unique identifier for all ActionStatus entities of the application diff --git a/docs/graphql/scalar/adapterruntimestatusid.md b/docs/graphql/scalar/adapterruntimestatusid.md new file mode 100644 index 00000000..415db1bd --- /dev/null +++ b/docs/graphql/scalar/adapterruntimestatusid.md @@ -0,0 +1,5 @@ +--- +title: AdapterRuntimeStatusID +--- + +A unique identifier for all AdapterRuntimeStatus entities of the application diff --git a/docs/graphql/scalar/adapterstatusconfigurationid.md b/docs/graphql/scalar/adapterstatusconfigurationid.md new file mode 100644 index 00000000..bdd6d528 --- /dev/null +++ b/docs/graphql/scalar/adapterstatusconfigurationid.md @@ -0,0 +1,5 @@ +--- +title: AdapterStatusConfigurationID +--- + +A unique identifier for all AdapterStatusConfiguration entities of the application diff --git a/docs/graphql/scalar/executionruntimestatusid.md b/docs/graphql/scalar/executionruntimestatusid.md new file mode 100644 index 00000000..bf8bccc9 --- /dev/null +++ b/docs/graphql/scalar/executionruntimestatusid.md @@ -0,0 +1,5 @@ +--- +title: ExecutionRuntimeStatusID +--- + +A unique identifier for all ExecutionRuntimeStatus entities of the application diff --git a/docs/graphql/scalar/runtimestatusconfigurationid.md b/docs/graphql/scalar/runtimestatusconfigurationid.md deleted file mode 100644 index 9b34bd34..00000000 --- a/docs/graphql/scalar/runtimestatusconfigurationid.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: RuntimeStatusConfigurationID ---- - -A unique identifier for all RuntimeStatusConfiguration entities of the application diff --git a/docs/graphql/scalar/runtimestatusid.md b/docs/graphql/scalar/runtimestatusid.md deleted file mode 100644 index 1ae3b817..00000000 --- a/docs/graphql/scalar/runtimestatusid.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: RuntimeStatusID ---- - -A unique identifier for all RuntimeStatus entities of the application diff --git a/docs/graphql/union/runtimestatus.md b/docs/graphql/union/runtimestatus.md new file mode 100644 index 00000000..42cffff3 --- /dev/null +++ b/docs/graphql/union/runtimestatus.md @@ -0,0 +1,11 @@ +--- +title: RuntimeStatus +--- + +A runtime status information entry + +## Possible types + +- [`ActionStatus`](../object/actionstatus.md) +- [`AdapterRuntimeStatus`](../object/adapterruntimestatus.md) +- [`ExecutionRuntimeStatus`](../object/executionruntimestatus.md) diff --git a/docs/graphql/union/runtimestatusconfiguration.md b/docs/graphql/union/runtimestatusconfiguration.md index 145bff9b..7d321a9e 100644 --- a/docs/graphql/union/runtimestatusconfiguration.md +++ b/docs/graphql/union/runtimestatusconfiguration.md @@ -6,4 +6,5 @@ Detailed configuration about a runtime status, either: endpoint, ... ## Possible types -- [`RuntimeStatusConfigurationEndpoint`](../object/runtimestatusconfigurationendpoint.md) +- [`ActionStatusConfigurationEndpoint`](../object/actionstatusconfigurationendpoint.md) +- [`AdapterStatusConfigurationEndpoint`](../object/adapterstatusconfigurationendpoint.md) diff --git a/spec/factories/action_status_configurations.rb b/spec/factories/action_status_configurations.rb new file mode 100644 index 00000000..43d40fd1 --- /dev/null +++ b/spec/factories/action_status_configurations.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :action_status_configuration do + action_status + flow_type_identifiers { [] } + endpoint { nil } + end +end diff --git a/spec/factories/runtime_status.rb b/spec/factories/action_statuses.rb similarity index 75% rename from spec/factories/runtime_status.rb rename to spec/factories/action_statuses.rb index c77839b2..ebd7c5a5 100644 --- a/spec/factories/runtime_status.rb +++ b/spec/factories/action_statuses.rb @@ -1,10 +1,9 @@ # frozen_string_literal: true FactoryBot.define do - factory :runtime_status do + factory :action_status do status { :stopped } last_heartbeat { Time.zone.today } - status_type { :adapter } identifier { SecureRandom.uuid } runtime end diff --git a/spec/factories/adapter_runtime_statuses.rb b/spec/factories/adapter_runtime_statuses.rb new file mode 100644 index 00000000..b55d7108 --- /dev/null +++ b/spec/factories/adapter_runtime_statuses.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :adapter_runtime_status do + status { :stopped } + last_heartbeat { Time.zone.today } + identifier { SecureRandom.uuid } + runtime + end +end diff --git a/spec/factories/adapter_status_configurations.rb b/spec/factories/adapter_status_configurations.rb new file mode 100644 index 00000000..0539ba63 --- /dev/null +++ b/spec/factories/adapter_status_configurations.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :adapter_status_configuration do + adapter_runtime_status + flow_type_identifiers { [] } + endpoint { 'http://example.com' } + end +end diff --git a/spec/factories/execution_runtime_statuses.rb b/spec/factories/execution_runtime_statuses.rb new file mode 100644 index 00000000..ad03a174 --- /dev/null +++ b/spec/factories/execution_runtime_statuses.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :execution_runtime_status do + status { :stopped } + last_heartbeat { Time.zone.today } + identifier { SecureRandom.uuid } + runtime + end +end diff --git a/spec/factories/runtime_status_configuration.rb b/spec/factories/runtime_status_configuration.rb deleted file mode 100644 index 5e9f4f97..00000000 --- a/spec/factories/runtime_status_configuration.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :runtime_status_configuration do - runtime_status - endpoint { 'http://example.com' } - end -end diff --git a/spec/graphql/types/runtime_status_type_spec.rb b/spec/graphql/types/runtime_status_type_spec.rb index f5651a8f..da252551 100644 --- a/spec/graphql/types/runtime_status_type_spec.rb +++ b/spec/graphql/types/runtime_status_type_spec.rb @@ -3,20 +3,13 @@ require 'rails_helper' RSpec.describe SagittariusSchema.types['RuntimeStatus'] do - let(:fields) do - %w[ - id - status - configurations - lastHeartbeat - type - identifier - createdAt - updatedAt - ] - end - it { expect(described_class.graphql_name).to eq('RuntimeStatus') } - it { expect(described_class).to have_graphql_fields(fields) } - it { expect(described_class).to require_graphql_authorizations(:read_runtime) } + + it 'includes all concrete runtime status objects' do + expect(described_class.possible_types).to include( + Types::ActionStatusType, + Types::AdapterRuntimeStatusType, + Types::ExecutionRuntimeStatusType + ) + end end diff --git a/spec/models/action_status_configuration_spec.rb b/spec/models/action_status_configuration_spec.rb new file mode 100644 index 00000000..cf8b398c --- /dev/null +++ b/spec/models/action_status_configuration_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ActionStatusConfiguration do + subject { create(:action_status_configuration) } + + describe 'associations' do + it { is_expected.to belong_to(:action_status).inverse_of(:action_status_configurations) } + end +end diff --git a/spec/models/action_status_spec.rb b/spec/models/action_status_spec.rb new file mode 100644 index 00000000..1a08f6b6 --- /dev/null +++ b/spec/models/action_status_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ActionStatus do + subject(:action_status) { create(:action_status) } + + describe 'associations' do + it { is_expected.to belong_to(:runtime).inverse_of(:action_statuses) } + it { is_expected.to have_many(:action_status_configurations).inverse_of(:action_status) } + end + + describe '#configurations' do + it 'returns action status configurations' do + configuration = create(:action_status_configuration, action_status: action_status) + + expect(action_status.configurations).to contain_exactly(configuration) + end + end +end diff --git a/spec/models/adapter_runtime_status_spec.rb b/spec/models/adapter_runtime_status_spec.rb new file mode 100644 index 00000000..984071c0 --- /dev/null +++ b/spec/models/adapter_runtime_status_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe AdapterRuntimeStatus do + subject(:adapter_runtime_status) { create(:adapter_runtime_status) } + + describe 'associations' do + it { is_expected.to belong_to(:runtime).inverse_of(:adapter_runtime_statuses) } + it { is_expected.to have_many(:adapter_status_configurations).inverse_of(:adapter_runtime_status) } + end + + describe '#configurations' do + it 'returns adapter status configurations' do + configuration = create(:adapter_status_configuration, adapter_runtime_status: adapter_runtime_status) + + expect(adapter_runtime_status.configurations).to contain_exactly(configuration) + end + end +end diff --git a/spec/models/adapter_status_configuration_spec.rb b/spec/models/adapter_status_configuration_spec.rb new file mode 100644 index 00000000..8d0f2900 --- /dev/null +++ b/spec/models/adapter_status_configuration_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe AdapterStatusConfiguration do + subject { create(:adapter_status_configuration) } + + describe 'associations' do + it { is_expected.to belong_to(:adapter_runtime_status).inverse_of(:adapter_status_configurations) } + end +end diff --git a/spec/models/execution_runtime_status_spec.rb b/spec/models/execution_runtime_status_spec.rb new file mode 100644 index 00000000..be5d8409 --- /dev/null +++ b/spec/models/execution_runtime_status_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ExecutionRuntimeStatus do + subject { create(:execution_runtime_status) } + + describe 'associations' do + it { is_expected.to belong_to(:runtime).inverse_of(:execution_runtime_statuses) } + end +end diff --git a/spec/models/runtime_spec.rb b/spec/models/runtime_spec.rb index e365c36c..89158e84 100644 --- a/spec/models/runtime_spec.rb +++ b/spec/models/runtime_spec.rb @@ -23,7 +23,9 @@ .inverse_of(:runtimes) } - it { is_expected.to have_many(:runtime_statuses).inverse_of(:runtime) } + it { is_expected.to have_many(:adapter_runtime_statuses).inverse_of(:runtime) } + it { is_expected.to have_many(:execution_runtime_statuses).inverse_of(:runtime) } + it { is_expected.to have_many(:action_statuses).inverse_of(:runtime) } end describe 'validations' do diff --git a/spec/models/runtime_status_spec.rb b/spec/models/runtime_status_spec.rb deleted file mode 100644 index 8a6038df..00000000 --- a/spec/models/runtime_status_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe RuntimeStatus do - subject(:runtime_status) { create(:runtime_status) } - - describe 'associations' do - it { is_expected.to have_many(:runtime_status_configurations).inverse_of(:runtime_status) } - it { is_expected.to belong_to(:runtime).inverse_of(:runtime_statuses) } - end - - describe 'validations' do - context 'when status configuration exists' do - before do - create(:runtime_status_configuration, runtime_status: runtime_status) - end - - context 'when type is :adapter' do - before { runtime_status.status_type = :adapter } - - it 'is valid' do - expect(runtime_status).to be_valid - end - end - - context 'when type is :execution' do - before { runtime_status.status_type = :execution } - - it 'is invalid' do - expect(runtime_status).not_to be_valid - end - end - end - end -end diff --git a/spec/requests/grpc/sagittarius/runtime_status_service_spec.rb b/spec/requests/grpc/sagittarius/runtime_status_service_spec.rb index e27407b3..1e4fde35 100644 --- a/spec/requests/grpc/sagittarius/runtime_status_service_spec.rb +++ b/spec/requests/grpc/sagittarius/runtime_status_service_spec.rb @@ -9,14 +9,17 @@ describe 'Update' do let(:runtime) { create(:runtime) } + let(:timestamp) { Time.current.change(usec: 0) } + let(:to_update_status) do Tucana::Shared::AdapterRuntimeStatus.new( status: Tucana::Shared::AdapterRuntimeStatus::Status::RUNNING, - timestamp: Time.now.to_i, + timestamp: timestamp.to_i * 1000, identifier: 'adapter_status_1', configurations: [ Tucana::Shared::AdapterStatusConfiguration.new( - endpoint: 'http://localhost:3000' + endpoint: 'http://localhost:3000', + flow_type_identifiers: %w[HTTP WEBHOOK] ) ] ) @@ -28,28 +31,30 @@ it 'creates a correct status' do expect(stub.update(message, authorization(runtime)).success).to be(true) - db_status = RuntimeStatus.last + db_status = AdapterRuntimeStatus.last expect(db_status.runtime).to eq(runtime) expect(db_status.identifier).to eq('adapter_status_1') - expect(db_status.status_type).to eq('adapter') expect(db_status.status).to eq('running') - expect(db_status.runtime_status_configurations.count).to eq(1) - expect(db_status.runtime_status_configurations.first.endpoint).to eq('http://localhost:3000') + expect(db_status.last_heartbeat.to_i).to eq(timestamp.to_i) + expect(db_status.adapter_status_configurations.count).to eq(1) + expect(db_status.adapter_status_configurations.first.endpoint).to eq('http://localhost:3000') + expect(db_status.adapter_status_configurations.first.flow_type_identifiers).to eq(%w[HTTP WEBHOOK]) end context 'when old configuration exists before' do before do - create(:runtime_status_configuration, endpoint: 'http://old-endpoint.com', - runtime_status: create(:runtime_status, - runtime: runtime, - identifier: 'adapter_status_1')) + create(:adapter_status_configuration, endpoint: 'http://old-endpoint.com', + adapter_runtime_status: create(:adapter_runtime_status, + runtime: runtime, + identifier: 'adapter_status_1')) end it 'updates the existing configuration' do expect(stub.update(message, authorization(runtime)).success).to be(true) - expect(RuntimeStatusConfiguration.count).to eq(1) - config = RuntimeStatusConfiguration.last + expect(AdapterStatusConfiguration.count).to eq(1) + config = AdapterStatusConfiguration.last expect(config.endpoint).to eq('http://localhost:3000') + expect(config.flow_type_identifiers).to eq(%w[HTTP WEBHOOK]) end end @@ -57,7 +62,7 @@ let(:to_update_status) do Tucana::Shared::ExecutionRuntimeStatus.new( status: Tucana::Shared::ExecutionRuntimeStatus::Status::RUNNING, - timestamp: Time.now.to_i, + timestamp: timestamp.to_i * 1000, identifier: 'execution_status_1' ) end @@ -68,11 +73,42 @@ it 'creates a correct status' do expect(stub.update(message, authorization(runtime)).success).to be(true) - db_status = RuntimeStatus.last + db_status = ExecutionRuntimeStatus.last expect(db_status.runtime).to eq(runtime) expect(db_status.identifier).to eq('execution_status_1') - expect(db_status.status_type).to eq('execution') expect(db_status.status).to eq('running') + expect(db_status.last_heartbeat.to_i).to eq(timestamp.to_i) + end + end + + context 'when action status' do + let(:to_update_status) do + Tucana::Shared::ActionStatus.new( + status: Tucana::Shared::ActionStatus::Status::RUNNING, + timestamp: timestamp.to_i * 1000, + identifier: 'action_status_1', + configurations: [ + Tucana::Shared::ActionStatusConfiguration.new( + flow_type_identifiers: %w[ACTION] + ) + ] + ) + end + + let(:message) do + Tucana::Sagittarius::RuntimeStatusUpdateRequest.new(action_status: to_update_status) + end + + it 'creates a correct status' do + expect(stub.update(message, authorization(runtime)).success).to be(true) + db_status = ActionStatus.last + expect(db_status.runtime).to eq(runtime) + expect(db_status.identifier).to eq('action_status_1') + expect(db_status.status).to eq('running') + expect(db_status.last_heartbeat.to_i).to eq(timestamp.to_i) + expect(db_status.action_status_configurations.count).to eq(1) + expect(db_status.action_status_configurations.first.endpoint).to be_nil + expect(db_status.action_status_configurations.first.flow_type_identifiers).to eq(%w[ACTION]) end end end From 0ab24ac1142cd92f5e3b942f53d0388a11db0700 Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 21 May 2026 20:33:24 +0200 Subject: [PATCH 3/3] ref: made rubocop happy --- app/graphql/types/runtime_type.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/graphql/types/runtime_type.rb b/app/graphql/types/runtime_type.rb index 6d518fa9..d54e48b6 100644 --- a/app/graphql/types/runtime_type.rb +++ b/app/graphql/types/runtime_type.rb @@ -16,8 +16,7 @@ class RuntimeType < Types::BaseObject field :status, Types::RuntimeConnectionStatusEnum, null: false, description: 'The status of the runtime' field :statuses, Types::RuntimeStatusType.connection_type, null: false, - description: 'Statuses of the runtime', - method: :statuses + description: 'Statuses of the runtime' field :token, String, null: true, description: 'Token belonging to the runtime, only present on creation' expose_abilities %i[