ecoportal-api-graphql 1.3.17 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +763 -11
- data/lib/ecoportal/api/common/graphql/http_client.rb +85 -2
- data/lib/ecoportal/api/common/graphql/model/diffable/leaf_diff_service.rb +97 -0
- data/lib/ecoportal/api/common/graphql/model/diffable.rb +1 -0
- data/lib/ecoportal/api/graphql/base/action.rb +1 -1
- data/lib/ecoportal/api/graphql/base/action_event.rb +23 -0
- data/lib/ecoportal/api/graphql/base/action_event_page.rb +16 -0
- data/lib/ecoportal/api/graphql/base/activity.rb +38 -0
- data/lib/ecoportal/api/graphql/base/activity_log.rb +38 -0
- data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +12 -7
- data/lib/ecoportal/api/graphql/base/auth_log.rb +24 -0
- data/lib/ecoportal/api/graphql/base/authorization_result.rb +20 -0
- data/lib/ecoportal/api/graphql/base/contractor_entity/member_changes.rb +17 -5
- data/lib/ecoportal/api/graphql/base/file_container.rb +12 -4
- data/lib/ecoportal/api/graphql/base/location_classification_type.rb +2 -0
- data/lib/ecoportal/api/graphql/base/location_structure.rb +3 -0
- data/lib/ecoportal/api/graphql/base/minimal_dashboard.rb +25 -0
- data/lib/ecoportal/api/graphql/base/organization.rb +2 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +25 -2
- data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +46 -7
- data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +5 -2
- data/lib/ecoportal/api/graphql/base/page/data_field/people.rb +50 -12
- data/lib/ecoportal/api/graphql/base/page/data_field.rb +12 -18
- data/lib/ecoportal/api/graphql/base/page/phased/stage.rb +51 -0
- data/lib/ecoportal/api/graphql/base/permissions.rb +15 -0
- data/lib/ecoportal/api/graphql/base/person_member_changelog.rb +23 -0
- data/lib/ecoportal/api/graphql/base/preset_view.rb +135 -0
- data/lib/ecoportal/api/graphql/base/register.rb +5 -0
- data/lib/ecoportal/api/graphql/base/template/change_log_entry.rb +118 -0
- data/lib/ecoportal/api/graphql/base/template.rb +2 -0
- data/lib/ecoportal/api/graphql/base.rb +9 -0
- data/lib/ecoportal/api/graphql/builder/contractor_entity.rb +10 -0
- data/lib/ecoportal/api/graphql/builder/page.rb +0 -16
- data/lib/ecoportal/api/graphql/builder/template.rb +46 -0
- data/lib/ecoportal/api/graphql/builder/template_builder.rb +21 -2
- data/lib/ecoportal/api/graphql/compat/pages.rb +7 -2
- data/lib/ecoportal/api/graphql/compat/response.rb +14 -0
- data/lib/ecoportal/api/graphql/concerns/threadable.rb +58 -0
- data/lib/ecoportal/api/graphql/concerns.rb +1 -0
- data/lib/ecoportal/api/graphql/connection/action.rb +1 -1
- data/lib/ecoportal/api/graphql/connection/action_category.rb +1 -1
- data/lib/ecoportal/api/graphql/connection/activity.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/activity_log.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/auth_log.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/contractor_entity.rb +1 -1
- data/lib/ecoportal/api/graphql/connection/minimal_dashboard.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/page.rb +1 -1
- data/lib/ecoportal/api/graphql/connection/pages_workflow_command.rb +1 -1
- data/lib/ecoportal/api/graphql/connection/person_member.rb +1 -1
- data/lib/ecoportal/api/graphql/connection/person_member_changelog.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/preview_page.rb +1 -1
- data/lib/ecoportal/api/graphql/connection/template_change_log.rb +19 -0
- data/lib/ecoportal/api/graphql/connection.rb +6 -0
- data/lib/ecoportal/api/graphql/diff/change.rb +7 -2
- data/lib/ecoportal/api/graphql/diff/command_synthesizer.rb +19 -1
- data/lib/ecoportal/api/graphql/diff/pairing/signals.rb +21 -1
- data/lib/ecoportal/api/graphql/diff/version_diff.rb +13 -6
- data/lib/ecoportal/api/graphql/file_upload/client.rb +198 -139
- data/lib/ecoportal/api/graphql/fragment/activity.rb +84 -0
- data/lib/ecoportal/api/graphql/fragment/activity_log.rb +75 -0
- data/lib/ecoportal/api/graphql/fragment/auth_log.rb +29 -0
- data/lib/ecoportal/api/graphql/fragment/authorization_result.rb +14 -0
- data/lib/ecoportal/api/graphql/fragment/location_node.rb +1 -0
- data/lib/ecoportal/api/graphql/fragment/minimal_dashboard.rb +31 -0
- data/lib/ecoportal/api/graphql/fragment/page.rb +1 -0
- data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +23 -0
- data/lib/ecoportal/api/graphql/fragment/permissions.rb +96 -0
- data/lib/ecoportal/api/graphql/fragment/person_member_changelog.rb +33 -0
- data/lib/ecoportal/api/graphql/fragment/template_change_log.rb +102 -0
- data/lib/ecoportal/api/graphql/fragment.rb +8 -0
- data/lib/ecoportal/api/graphql/input/action/update.rb +12 -0
- data/lib/ecoportal/api/graphql/input/contractor_entity/manager_settings.rb +20 -0
- data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +6 -27
- data/lib/ecoportal/api/graphql/input/contractor_entity.rb +1 -0
- data/lib/ecoportal/api/graphql/input/date_range.rb +16 -0
- data/lib/ecoportal/api/graphql/input/location_structure/apply_commands.rb +2 -2
- data/lib/ecoportal/api/graphql/input/location_structure/draft/add_commands.rb +2 -2
- data/lib/ecoportal/api/graphql/input/location_structure/insert_command.rb +8 -0
- data/lib/ecoportal/api/graphql/input/location_structure/update_command.rb +6 -2
- data/lib/ecoportal/api/graphql/input/page/review_task.rb +14 -1
- data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -1
- data/lib/ecoportal/api/graphql/input/workflow_command/add_checklist_field_item.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +10 -9
- data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +11 -5
- data/lib/ecoportal/api/graphql/input/workflow_command/add_smart_fill_config.rb +23 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/add_viewable_field.rb +45 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/archive_public_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/create_public_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_checklist_field_item.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +17 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +5 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_public_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +6 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_smart_fill_config.rb +21 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_advanced_settings.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_basic_settings.rb +32 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_container_uid.rb +45 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/{edit_page_creator_permissions.rb → edit_template_creator_permissions.rb} +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_descriptions.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/action_list.rb +31 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/contractor_entities.rb +6 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +9 -1
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +15 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/file.rb +21 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +27 -3
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +9 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/manage_copy_page_configuration.rb +47 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/move_section_to_stage.rb +33 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/move_viewable_field.rb +33 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_checklist_field_item.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_smart_fill_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_viewable_field.rb +21 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command.rb +48 -5
- data/lib/ecoportal/api/graphql/input.rb +1 -0
- data/lib/ecoportal/api/graphql/interface/base_page.rb +50 -3
- data/lib/ecoportal/api/graphql/interface/location_structure/command.rb +2 -1
- data/lib/ecoportal/api/graphql/logic/base_query.rb +72 -5
- data/lib/ecoportal/api/graphql/logic/connection.rb +17 -0
- data/lib/ecoportal/api/graphql/logic/input.rb +127 -0
- data/lib/ecoportal/api/graphql/model/action_event.rb +14 -0
- data/lib/ecoportal/api/graphql/model/action_event_page.rb +10 -0
- data/lib/ecoportal/api/graphql/model/activity.rb +14 -0
- data/lib/ecoportal/api/graphql/model/activity_log.rb +31 -0
- data/lib/ecoportal/api/graphql/model/auth_log.rb +11 -0
- data/lib/ecoportal/api/graphql/model/authorization_result.rb +12 -0
- data/lib/ecoportal/api/graphql/model/minimal_dashboard.rb +14 -0
- data/lib/ecoportal/api/graphql/model/organization.rb +36 -0
- data/lib/ecoportal/api/graphql/model/page/phased.rb +17 -0
- data/lib/ecoportal/api/graphql/model/permissions.rb +185 -0
- data/lib/ecoportal/api/graphql/model/person_member.rb +7 -0
- data/lib/ecoportal/api/graphql/model/person_member_changelog.rb +15 -0
- data/lib/ecoportal/api/graphql/model/template/change_log_entry.rb +19 -0
- data/lib/ecoportal/api/graphql/model/template.rb +4 -1
- data/lib/ecoportal/api/graphql/model.rb +9 -0
- data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +20 -10
- data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +25 -10
- data/lib/ecoportal/api/graphql/mutation/contractor_entity/update_manager_settings.rb +37 -0
- data/lib/ecoportal/api/graphql/mutation/contractor_entity.rb +1 -0
- data/lib/ecoportal/api/graphql/mutation/file_container/upload.rb +78 -0
- data/lib/ecoportal/api/graphql/mutation/file_container.rb +15 -0
- data/lib/ecoportal/api/graphql/mutation/template/update_related_page.rb +79 -0
- data/lib/ecoportal/api/graphql/mutation/template.rb +1 -0
- data/lib/ecoportal/api/graphql/mutation.rb +1 -1
- data/lib/ecoportal/api/graphql/payload/contractor_entity/manager_settings.rb +20 -0
- data/lib/ecoportal/api/graphql/payload/contractor_entity.rb +1 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_jobs.rb +2 -2
- data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_workflows.rb +2 -2
- data/lib/ecoportal/api/graphql/payload/template/update_related_page.rb +15 -0
- data/lib/ecoportal/api/graphql/payload/template.rb +1 -0
- data/lib/ecoportal/api/graphql/payload/upload.rb +12 -0
- data/lib/ecoportal/api/graphql/payload.rb +1 -0
- data/lib/ecoportal/api/graphql/query/activity_logs.rb +78 -0
- data/lib/ecoportal/api/graphql/query/auth_logs.rb +51 -0
- data/lib/ecoportal/api/graphql/query/dashboard_search.rb +57 -0
- data/lib/ecoportal/api/graphql/query/location_structure.rb +2 -0
- data/lib/ecoportal/api/graphql/query/location_structures.rb +2 -0
- data/lib/ecoportal/api/graphql/query/page.rb +6 -1
- data/lib/ecoportal/api/graphql/query/page_activities.rb +56 -0
- data/lib/ecoportal/api/graphql/query/permissions.rb +35 -0
- data/lib/ecoportal/api/graphql/query/person_member_changelogs.rb +53 -0
- data/lib/ecoportal/api/graphql/query/person_members.rb +76 -0
- data/lib/ecoportal/api/graphql/query/template_change_log.rb +118 -0
- data/lib/ecoportal/api/graphql/query.rb +8 -0
- data/lib/ecoportal/api/graphql_version.rb +1 -1
- metadata +83 -14
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +0 -28
- data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +0 -36
- data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +0 -40
- data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +0 -13
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Input
|
|
5
|
+
class WorkflowCommand
|
|
6
|
+
# `WorkflowMoveSectionToStageInput` (20260929) -- moves an existing section from one
|
|
7
|
+
# stage to another, optionally placed relative to an anchor section. Unlike
|
|
8
|
+
# `reorderSection` (same stage), the source and target stages are both required.
|
|
9
|
+
module MoveSectionToStage
|
|
10
|
+
SCHEMA_VERSION = '20260929'.freeze
|
|
11
|
+
VALID_KEYS = %i[sourceStageId targetStageId sectionId anchorId anchorPosition].freeze
|
|
12
|
+
ANCHOR_POSITIONS = AddViewableField::ANCHOR_POSITIONS
|
|
13
|
+
|
|
14
|
+
def self.build(source_stage_id:, target_stage_id:, section_id:, **kwargs)
|
|
15
|
+
position = kwargs[:anchorPosition]
|
|
16
|
+
unless position.nil? || ANCHOR_POSITIONS.include?(position.to_s)
|
|
17
|
+
raise ArgumentError,
|
|
18
|
+
"Invalid anchorPosition #{position.inspect}: " \
|
|
19
|
+
"expected one of #{ANCHOR_POSITIONS.join(', ')}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
{
|
|
23
|
+
sourceStageId: source_stage_id,
|
|
24
|
+
targetStageId: target_stage_id,
|
|
25
|
+
sectionId: section_id
|
|
26
|
+
}.merge(kwargs.slice(:anchorId, :anchorPosition).compact)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Input
|
|
5
|
+
class WorkflowCommand
|
|
6
|
+
# `WorkflowMoveViewableFieldInput` — reorders a viewable field on a People data field.
|
|
7
|
+
# Same shape as AddViewableField minus `schemaFieldType` (the field already exists, so
|
|
8
|
+
# its type is known server-side). See AddViewableField for why these three commands
|
|
9
|
+
# replaced the removed `people.add/removeViewableFields` arrays.
|
|
10
|
+
module MoveViewableField
|
|
11
|
+
SCHEMA_VERSION = '20260725'.freeze
|
|
12
|
+
VALID_KEYS = %i[dataFieldId schemaFieldId anchorId anchorPosition].freeze
|
|
13
|
+
ANCHOR_POSITIONS = AddViewableField::ANCHOR_POSITIONS
|
|
14
|
+
|
|
15
|
+
def self.build(data_field_id:, schema_field_id:, **kwargs)
|
|
16
|
+
position = kwargs[:anchorPosition]
|
|
17
|
+
unless position.nil? || ANCHOR_POSITIONS.include?(position.to_s)
|
|
18
|
+
raise ArgumentError,
|
|
19
|
+
"Invalid anchorPosition #{position.inspect}: " \
|
|
20
|
+
"expected one of #{ANCHOR_POSITIONS.join(', ')}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
{
|
|
24
|
+
dataFieldId: data_field_id,
|
|
25
|
+
schemaFieldId: schema_field_id
|
|
26
|
+
}.merge(kwargs.slice(:anchorId, :anchorPosition).compact)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Input
|
|
5
|
+
class WorkflowCommand
|
|
6
|
+
# 20260713
|
|
7
|
+
module RemoveChecklistFieldItem
|
|
8
|
+
SCHEMA_VERSION = '20260713'.freeze
|
|
9
|
+
VALID_KEYS = %i[dataFieldId itemId].freeze
|
|
10
|
+
|
|
11
|
+
def self.build(**kwargs)
|
|
12
|
+
kwargs.slice(*VALID_KEYS).compact
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Input
|
|
5
|
+
class WorkflowCommand
|
|
6
|
+
# 20260713
|
|
7
|
+
module RemoveSmartFillConfig
|
|
8
|
+
SCHEMA_VERSION = '20260713'.freeze
|
|
9
|
+
VALID_KEYS = %i[dataFieldId].freeze
|
|
10
|
+
|
|
11
|
+
def self.build(**kwargs)
|
|
12
|
+
kwargs.slice(*VALID_KEYS).compact
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Input
|
|
5
|
+
class WorkflowCommand
|
|
6
|
+
# `WorkflowRemoveViewableFieldInput` — removes a viewable field from a People data
|
|
7
|
+
# field. Both keys are required (`ID!`). Replaces the removed
|
|
8
|
+
# `people.removeViewableFields` array — see AddViewableField.
|
|
9
|
+
module RemoveViewableField
|
|
10
|
+
SCHEMA_VERSION = '20260725'.freeze
|
|
11
|
+
VALID_KEYS = %i[dataFieldId schemaFieldId].freeze
|
|
12
|
+
|
|
13
|
+
def self.build(data_field_id:, schema_field_id:)
|
|
14
|
+
{ dataFieldId: data_field_id, schemaFieldId: schema_field_id }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -4,8 +4,9 @@ module Ecoportal
|
|
|
4
4
|
module Input
|
|
5
5
|
class WorkflowCommand
|
|
6
6
|
module ReorderForces
|
|
7
|
-
SCHEMA_VERSION = '
|
|
8
|
-
|
|
7
|
+
SCHEMA_VERSION = '20260713'.freeze
|
|
8
|
+
# 20260713: `after`/`before` replaced by anchor-based positioning.
|
|
9
|
+
VALID_KEYS = %i[forceId anchorId anchorPosition].freeze
|
|
9
10
|
|
|
10
11
|
def self.build(**kwargs)
|
|
11
12
|
kwargs.slice(*VALID_KEYS).compact
|
|
@@ -4,8 +4,9 @@ module Ecoportal
|
|
|
4
4
|
module Input
|
|
5
5
|
class WorkflowCommand
|
|
6
6
|
module ReorderSection
|
|
7
|
-
SCHEMA_VERSION = '
|
|
8
|
-
|
|
7
|
+
SCHEMA_VERSION = '20260713'.freeze
|
|
8
|
+
# 20260713: `after`/`before` replaced by anchor-based positioning.
|
|
9
|
+
VALID_KEYS = %i[sectionId stageId anchorId anchorPosition].freeze
|
|
9
10
|
|
|
10
11
|
def self.build(**kwargs)
|
|
11
12
|
kwargs.slice(*VALID_KEYS).compact
|
|
@@ -6,9 +6,19 @@ module Ecoportal
|
|
|
6
6
|
SCHEMA_VERSION = '20260605'.freeze
|
|
7
7
|
|
|
8
8
|
COMMAND_MAP = {
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
# Template settings (20260713 — supersede the removed page-level editPage/editPageCreatorPermissions)
|
|
10
|
+
editTemplateBasicSettings: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditTemplateBasicSettings',
|
|
11
|
+
editTemplateAdvancedSettings: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditTemplateAdvancedSettings',
|
|
12
|
+
editTemplateCreatorPermissions: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditTemplateCreatorPermissions',
|
|
13
|
+
editTemplateDescriptions: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditTemplateDescriptions',
|
|
14
|
+
# Cross-version template identity (the series key) — see the input class for the
|
|
15
|
+
# publish-swap rule that makes it usable as an entity id across versions.
|
|
16
|
+
editTemplateContainerUid: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditTemplateContainerUid',
|
|
17
|
+
createPublicConfig: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::CreatePublicConfig',
|
|
18
|
+
editPublicConfig: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditPublicConfig',
|
|
19
|
+
archivePublicConfig: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::ArchivePublicConfig',
|
|
20
|
+
# Copy-page configuration (20260819)
|
|
21
|
+
manageCopyPageConfiguration: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::ManageCopyPageConfiguration',
|
|
12
22
|
# Stage structural
|
|
13
23
|
addStage: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::AddStage',
|
|
14
24
|
removeStage: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::RemoveStage',
|
|
@@ -33,6 +43,7 @@ module Ecoportal
|
|
|
33
43
|
collapseSection: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::CollapseSection',
|
|
34
44
|
expandSection: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::ExpandSection',
|
|
35
45
|
reorderSection: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::ReorderSection',
|
|
46
|
+
moveSectionToStage: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::MoveSectionToStage',
|
|
36
47
|
# Task
|
|
37
48
|
addTask: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::AddTask',
|
|
38
49
|
removeTask: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::RemoveTask',
|
|
@@ -91,6 +102,19 @@ module Ecoportal
|
|
|
91
102
|
removeField: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::RemoveField',
|
|
92
103
|
# Field config
|
|
93
104
|
editFieldConfiguration: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditFieldConfiguration',
|
|
105
|
+
# Viewable fields on People data fields (20260725) — replaced the REMOVED
|
|
106
|
+
# `people.addViewableFields`/`removeViewableFields` arrays; see AddViewableField.
|
|
107
|
+
addViewableField: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::AddViewableField',
|
|
108
|
+
moveViewableField: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::MoveViewableField',
|
|
109
|
+
removeViewableField: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::RemoveViewableField',
|
|
110
|
+
# Checklist field items (20260713)
|
|
111
|
+
addChecklistFieldItem: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::AddChecklistFieldItem',
|
|
112
|
+
editChecklistFieldItem: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditChecklistFieldItem',
|
|
113
|
+
removeChecklistFieldItem: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::RemoveChecklistFieldItem',
|
|
114
|
+
# Smart-fill config (20260713 — extracted from field-config inputs)
|
|
115
|
+
addSmartFillConfig: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::AddSmartFillConfig',
|
|
116
|
+
editSmartFillConfig: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditSmartFillConfig',
|
|
117
|
+
removeSmartFillConfig: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::RemoveSmartFillConfig',
|
|
94
118
|
# Select options
|
|
95
119
|
addSelectFieldOption: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::AddSelectFieldOption',
|
|
96
120
|
editSelectFieldOption: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::EditSelectFieldOption',
|
|
@@ -147,8 +171,21 @@ module Ecoportal
|
|
|
147
171
|
end
|
|
148
172
|
end
|
|
149
173
|
|
|
150
|
-
require_relative 'workflow_command/
|
|
151
|
-
require_relative 'workflow_command/
|
|
174
|
+
require_relative 'workflow_command/edit_template_basic_settings'
|
|
175
|
+
require_relative 'workflow_command/edit_template_advanced_settings'
|
|
176
|
+
require_relative 'workflow_command/edit_template_creator_permissions'
|
|
177
|
+
require_relative 'workflow_command/edit_template_descriptions'
|
|
178
|
+
require_relative 'workflow_command/edit_template_container_uid'
|
|
179
|
+
require_relative 'workflow_command/create_public_config'
|
|
180
|
+
require_relative 'workflow_command/edit_public_config'
|
|
181
|
+
require_relative 'workflow_command/archive_public_config'
|
|
182
|
+
require_relative 'workflow_command/manage_copy_page_configuration'
|
|
183
|
+
require_relative 'workflow_command/add_checklist_field_item'
|
|
184
|
+
require_relative 'workflow_command/edit_checklist_field_item'
|
|
185
|
+
require_relative 'workflow_command/remove_checklist_field_item'
|
|
186
|
+
require_relative 'workflow_command/add_smart_fill_config'
|
|
187
|
+
require_relative 'workflow_command/edit_smart_fill_config'
|
|
188
|
+
require_relative 'workflow_command/remove_smart_fill_config'
|
|
152
189
|
require_relative 'workflow_command/add_stage'
|
|
153
190
|
require_relative 'workflow_command/remove_stage'
|
|
154
191
|
require_relative 'workflow_command/edit_stage'
|
|
@@ -237,9 +274,15 @@ require_relative 'workflow_command/remove_binding'
|
|
|
237
274
|
require_relative 'workflow_command/add_linked_helper'
|
|
238
275
|
require_relative 'workflow_command/edit_linked_helper'
|
|
239
276
|
require_relative 'workflow_command/remove_linked_helper'
|
|
277
|
+
require_relative 'workflow_command/add_viewable_field'
|
|
278
|
+
require_relative 'workflow_command/move_viewable_field'
|
|
279
|
+
require_relative 'workflow_command/move_section_to_stage'
|
|
280
|
+
require_relative 'workflow_command/remove_viewable_field'
|
|
281
|
+
require_relative 'workflow_command/field_config/action_list'
|
|
240
282
|
require_relative 'workflow_command/field_config/contractor_entities'
|
|
241
283
|
require_relative 'workflow_command/field_config/cross_reference'
|
|
242
284
|
require_relative 'workflow_command/field_config/date'
|
|
285
|
+
require_relative 'workflow_command/field_config/file'
|
|
243
286
|
require_relative 'workflow_command/field_config/gauge'
|
|
244
287
|
require_relative 'workflow_command/field_config/image_gallery'
|
|
245
288
|
require_relative 'workflow_command/field_config/location_field'
|
|
@@ -16,6 +16,7 @@ require_relative 'input/contractor_entity'
|
|
|
16
16
|
require_relative 'input/action'
|
|
17
17
|
require_relative 'input/page'
|
|
18
18
|
require_relative 'input/delta_input'
|
|
19
|
+
require_relative 'input/date_range'
|
|
19
20
|
require_relative 'input/search_conf'
|
|
20
21
|
|
|
21
22
|
require_relative 'input/register'
|
|
@@ -6,6 +6,12 @@ module Ecoportal
|
|
|
6
6
|
include Concerns::PageCompat
|
|
7
7
|
include Concerns::DataFieldAccess
|
|
8
8
|
|
|
9
|
+
# Page-level leaf arrays (`otherTags`, whole-set `locations`) are cascaded
|
|
10
|
+
# attributes the default DiffService cannot see. LeafDiffService diffs them
|
|
11
|
+
# inline (full-set replace) while still cascading into real nested models
|
|
12
|
+
# (e.g. a phased page's `stages`). See Diffable::LeafDiffService.
|
|
13
|
+
DIFF_CLASS = Ecoportal::API::Common::GraphQL::Model::Diffable::LeafDiffService
|
|
14
|
+
|
|
9
15
|
passkey :id
|
|
10
16
|
passthrough :name, :uid
|
|
11
17
|
passthrough :icon
|
|
@@ -15,7 +21,6 @@ module Ecoportal
|
|
|
15
21
|
# class_resolver :force_class, 'Ecoportal::API::GraphQL::Base::Force'
|
|
16
22
|
# class_resolver :task_class, 'Ecoportal::API::GraphQL::Interface::Task'
|
|
17
23
|
# class_resolver :theme_class, 'Ecoportal::API::GraphQL::Base::Theme'
|
|
18
|
-
# class_resolver :template_class, 'Ecoportal::API::GraphQL::Base::Template'
|
|
19
24
|
# class_resolver :register_class, 'Ecoportal::API::GraphQL::Base::Register'
|
|
20
25
|
class_resolver :organization_class, 'Ecoportal::API::GraphQL::Base::Organization'
|
|
21
26
|
|
|
@@ -32,6 +37,20 @@ module Ecoportal
|
|
|
32
37
|
Array(doc['locations']).map { |l| l.is_a?(Hash) ? l['id'] : l }.compact
|
|
33
38
|
end
|
|
34
39
|
|
|
40
|
+
# Compiled tag set (client-side build of the backend-only "compiled_tags").
|
|
41
|
+
# This base implementation covers a non-phased page (and is the fallback for a
|
|
42
|
+
# phased page with no stages): there are no per-stage tags, so the set is just the
|
|
43
|
+
# page-level components, de-duplicated:
|
|
44
|
+
#
|
|
45
|
+
# all_tags = Unique(baseTags + otherTags + location_ids)
|
|
46
|
+
#
|
|
47
|
+
# Model::Page::Phased overrides this to take the union across its stages' #all_tags.
|
|
48
|
+
# Returns a de-duplicated Array of tag strings.
|
|
49
|
+
def all_tags
|
|
50
|
+
(Array(baseTags) + Array(otherTags) + Array(location_ids)).
|
|
51
|
+
compact.uniq
|
|
52
|
+
end
|
|
53
|
+
|
|
35
54
|
def location_ids=(ids)
|
|
36
55
|
doc['locations'] = Array(ids).map { |id_val| { 'id' => id_val } }
|
|
37
56
|
end
|
|
@@ -41,7 +60,6 @@ module Ecoportal
|
|
|
41
60
|
# embeds_one :taskPriority, klass: 'BasePage::TaskPriorityEnum', read_only: true
|
|
42
61
|
passthrough :taskPriority
|
|
43
62
|
|
|
44
|
-
|
|
45
63
|
passthrough :patchVer
|
|
46
64
|
|
|
47
65
|
passboolean :draft, :archived
|
|
@@ -78,7 +96,36 @@ module Ecoportal
|
|
|
78
96
|
# the CreateFromTemplateInput preview. nil for fetched/persisted pages.
|
|
79
97
|
attr_accessor :_compat_source_template_id
|
|
80
98
|
|
|
81
|
-
#
|
|
99
|
+
# The narrow `Template` type (NOT the template page — see Base::Template for the
|
|
100
|
+
# asymmetry). Populated only for template pages; nil for records. Carries
|
|
101
|
+
# `templateContainerUid`, the cross-version series key.
|
|
102
|
+
class_resolver :template_class, 'Ecoportal::API::GraphQL::Model::Template::Information'
|
|
103
|
+
|
|
104
|
+
# Deliberately NOT `embeds_one ..., read_only: true`, and this is not a style choice:
|
|
105
|
+
# `read_only` does not keep a mutated child out of the parent's diff. With `embeds_one`,
|
|
106
|
+
# `page.template.templateContainerUid = 'x'` yields
|
|
107
|
+
# `as_update => { id:, template: { templateContainerUid: 'x' } }` — but `UpdatePageInput`
|
|
108
|
+
# has NO `template` member, so that would push a key `updatePage` cannot accept. The
|
|
109
|
+
# only writer for the series key is the `editTemplateContainerUid` workflow command.
|
|
110
|
+
#
|
|
111
|
+
# So this follows the same on-demand read-only pattern as `#forces` above, over a COPY of
|
|
112
|
+
# the sub-doc: the returned model is a genuine dead end — writes to it cannot reach
|
|
113
|
+
# `doc`, cannot dirty the page, and cannot leak into an update.
|
|
114
|
+
def template
|
|
115
|
+
return nil unless (raw = doc['template'])
|
|
116
|
+
|
|
117
|
+
@template ||= template_class.new(
|
|
118
|
+
Ecoportal::API::Common::GraphQL::HashHelpers.deep_dup(raw)
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Convenience reader for the cross-version series key — nil unless this page is a
|
|
123
|
+
# template AND the read selected `template { templateContainerUid }` (CommonPageUnion
|
|
124
|
+
# does). Many versions may share one uid; only one may be published at a time.
|
|
125
|
+
def templateContainerUid
|
|
126
|
+
template&.templateContainerUid
|
|
127
|
+
end
|
|
128
|
+
|
|
82
129
|
# embeds_many :registers, klass: :register_class, read_only: true
|
|
83
130
|
# embeds_one :organization, klass: :organization_class, read_only: true
|
|
84
131
|
|
|
@@ -140,14 +140,81 @@ module Ecoportal
|
|
|
140
140
|
raw_response[:data] = response
|
|
141
141
|
end
|
|
142
142
|
end
|
|
143
|
-
rescue *DETAIL_ERRORS =>
|
|
144
|
-
|
|
145
|
-
puts "Internal Error with these params:\n"
|
|
146
|
-
pp query_params
|
|
147
|
-
pp block
|
|
143
|
+
rescue *DETAIL_ERRORS => err
|
|
144
|
+
report_query_failure(err, query_params)
|
|
148
145
|
raise
|
|
149
146
|
end
|
|
150
147
|
|
|
148
|
+
# Reports WHERE a query failed, on stderr, and re-raises untouched.
|
|
149
|
+
#
|
|
150
|
+
# ★ This replaces an unconditional `pp kargs` / `pp query_params` / `pp block`
|
|
151
|
+
# to STDOUT. That dump was NOT debug litter — it existed because graphlient
|
|
152
|
+
# masks the origin of a failure: `Client#parse`/`#execute` do
|
|
153
|
+
# `raise Graphlient::Errors::ClientError, e.message`, which leaves graphlient's
|
|
154
|
+
# own `inner_exception` nil AND replaces the backtrace, discarding the source
|
|
155
|
+
# location `graphql-client` deliberately sets via
|
|
156
|
+
# `set_backtrace(["#{filename}:#{line}"])`. With that gone there was no other
|
|
157
|
+
# way to see which query blew up. (Tracked upstream; see
|
|
158
|
+
# the repo's internal docs.)
|
|
159
|
+
#
|
|
160
|
+
# But the location was never actually destroyed. Ruby populates `.cause`
|
|
161
|
+
# automatically when you raise inside a rescue, so the original error — with the
|
|
162
|
+
# location intact — is one hop away. Verified by execution:
|
|
163
|
+
#
|
|
164
|
+
# err.inner_exception => nil (graphlient's api, broken)
|
|
165
|
+
# err.backtrace.first => ".../client.rb:20" (the raise site, useless)
|
|
166
|
+
# err.cause.backtrace.first => "app/queries/x.rb:198" (the QUERY site)
|
|
167
|
+
#
|
|
168
|
+
# So this reports MORE of what the dump was for (the failing query's own source
|
|
169
|
+
# location) and LESS of what it should never have emitted: `query_params` holds
|
|
170
|
+
# GraphQL variables — page ids, emails, field values — and printing them to
|
|
171
|
+
# stdout put customer data into CI logs. Variables are now shown only when the
|
|
172
|
+
# client's existing `deep_logging` flag is on (see `dump_variables?` for why NOT
|
|
173
|
+
# the logger level). `pp block` is dropped outright: inspecting a Proc never
|
|
174
|
+
# identified anything.
|
|
175
|
+
#
|
|
176
|
+
# Emitted with `warn` (stderr, and suppressible via the Warning module) rather than
|
|
177
|
+
# `puts`, so tools that pipe query results keep a clean stdout. Tracked as Q-43.
|
|
178
|
+
def report_query_failure(err, query_params = nil)
|
|
179
|
+
origin = err.cause
|
|
180
|
+
lines = ["[#{self.class.name || self.class}] #{err.class}: #{failure_message(err)}"]
|
|
181
|
+
lines << " origin: #{origin.class}" if origin
|
|
182
|
+
lines << " at: #{origin.backtrace.first}" if origin&.backtrace&.first
|
|
183
|
+
lines << " params: #{query_params.inspect}" if dump_variables?
|
|
184
|
+
|
|
185
|
+
warn(lines.join("\n"))
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# graphlient's `GraphQLError#to_s` / `ExecutionError#to_s` format from
|
|
189
|
+
# `errors.details` and render an EMPTY string when that is empty — and because
|
|
190
|
+
# they override `to_s`, the fallback text their constructors pass to `super` is
|
|
191
|
+
# unreachable. An exception with a blank message is invisible in a log, so say
|
|
192
|
+
# so rather than printing nothing.
|
|
193
|
+
def failure_message(err)
|
|
194
|
+
msg = err.message.to_s
|
|
195
|
+
return msg unless msg.empty?
|
|
196
|
+
|
|
197
|
+
"(blank — #{err.class} renders its message from errors.details, which was empty)"
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Opt-in via the client's EXISTING `deep_logging` flag ("whether or not batch
|
|
201
|
+
# responses should be logged") — the same class of thing as dumping variables,
|
|
202
|
+
# and it defaults to false. No new env var and no new config knob.
|
|
203
|
+
#
|
|
204
|
+
# ⚠ Do NOT gate this on `logger.debug?`, which is the obvious-looking choice and
|
|
205
|
+
# is wrong: `HttpClient`'s default logger is `::Logger.new(IO::NULL)`, and a
|
|
206
|
+
# fresh Logger's level is DEBUG (0) — so `logger.debug?` is `true` out of the
|
|
207
|
+
# box and variables would leak by default, which is the whole thing being fixed.
|
|
208
|
+
# A spec pins this.
|
|
209
|
+
def dump_variables?
|
|
210
|
+
http = client&.http_client
|
|
211
|
+
return false unless http.respond_to?(:deep_logging?, true)
|
|
212
|
+
|
|
213
|
+
!!http.send(:deep_logging?)
|
|
214
|
+
rescue StandardError
|
|
215
|
+
false
|
|
216
|
+
end
|
|
217
|
+
|
|
151
218
|
def request(*path)
|
|
152
219
|
response = yield
|
|
153
220
|
wrap_response(response, path)
|
|
@@ -18,6 +18,23 @@ module Ecoportal
|
|
|
18
18
|
embeds_many :nodes, klass: :node_class
|
|
19
19
|
embeds_one :pageInfo, klass: Base::PageInfo
|
|
20
20
|
|
|
21
|
+
# Bind a connection subclass to its concrete node type.
|
|
22
|
+
#
|
|
23
|
+
# The base `embeds_many :nodes, klass: :node_class` builds a SINGLE dynamic
|
|
24
|
+
# `CollectionModel` ("nodes::node_class") that every subclass inherits and shares.
|
|
25
|
+
# The v2 collection layer memoizes the resolved class on that shared collection
|
|
26
|
+
# (items_klass.rb:62-63), so the FIRST connection instantiated in a process poisons
|
|
27
|
+
# every other connection's instance `nodes` typing (e.g. a MinimalDashboard connection
|
|
28
|
+
# returning AuthLog nodes). Declaring `embeds_many :nodes` per subclass with the concrete
|
|
29
|
+
# class gives each subclass its OWN collection ("nodes::Model::X") bound to a real Class —
|
|
30
|
+
# no shared symbol, nothing to memoize wrongly.
|
|
31
|
+
#
|
|
32
|
+
# Use `nodes_of Model::X` in a subclass instead of `class_resolver :node_class, Model::X`.
|
|
33
|
+
def self.nodes_of(klass)
|
|
34
|
+
class_resolver :node_class, klass
|
|
35
|
+
embeds_many :nodes, klass: klass
|
|
36
|
+
end
|
|
37
|
+
|
|
21
38
|
def empty?
|
|
22
39
|
count < 1
|
|
23
40
|
end
|
|
@@ -5,6 +5,133 @@ module Ecoportal
|
|
|
5
5
|
class Input < Logic::BaseModel
|
|
6
6
|
passthrough :clientMutationId
|
|
7
7
|
|
|
8
|
+
# Declarative set-diff macro for id-list fields that the schema exposes as
|
|
9
|
+
# `IdDiffInput { additions: [ID!], removals: [ID!] }` on the *update* mutation.
|
|
10
|
+
#
|
|
11
|
+
# Mixed into any Input class (whether it inherits from {Logic::Input} or from a
|
|
12
|
+
# `Base::` data model) via `extend`. {Logic::Input} extends it for its own subclasses;
|
|
13
|
+
# data-model Input classes call `extend Logic::Input::IdDiffFields` explicitly.
|
|
14
|
+
#
|
|
15
|
+
# Usage:
|
|
16
|
+
# class Update < Base::ContractorEntity
|
|
17
|
+
# extend Logic::Input::IdDiffFields
|
|
18
|
+
# id_diff_fields :associatedPeopleIds, :leadContractorIds
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# It installs (or augments) a `from_model` that, for each declared field, computes the
|
|
22
|
+
# delta DIRECTLY from the READ model's `doc[key]` vs `original_doc[key]` arrays:
|
|
23
|
+
# additions = current - original
|
|
24
|
+
# removals = original - current
|
|
25
|
+
# A field is omitted when unchanged. The delta is computed directly (NOT via the
|
|
26
|
+
# cascaded DiffService) because these array fields are dropped from the flat diff and
|
|
27
|
+
# the read model is `root!` (so its doc/original_doc resolve without cascade side effects).
|
|
28
|
+
module IdDiffFields
|
|
29
|
+
# @return [Array<Symbol>] the fields declared for set-diff on this class.
|
|
30
|
+
def id_diff_fields_list
|
|
31
|
+
@id_diff_fields_list ||= []
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Declares the id-list fields that must be reshaped into IdDiff `{ additions:, removals: }`.
|
|
35
|
+
# @param fields [Array<Symbol>] field names (as they appear in the read model's doc).
|
|
36
|
+
# @return [void]
|
|
37
|
+
def id_diff_fields(*fields)
|
|
38
|
+
id_diff_fields_list.concat(fields.flatten.map(&:to_sym)).uniq!
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Computes the IdDiff-shaped deltas for the declared fields and merges them into +diff+.
|
|
42
|
+
# @param model [Common::GraphQL::Model] the subject (read) model.
|
|
43
|
+
# @param diff [Hash, nil] the base mutation input hash to augment (may be nil).
|
|
44
|
+
# @return [Hash, nil] +diff+ with per-field `{ additions:, removals: }` merged in,
|
|
45
|
+
# or the original value when nothing changed.
|
|
46
|
+
def merge_id_diffs(model, diff)
|
|
47
|
+
id_diff_fields_list.each do |field|
|
|
48
|
+
key = field.to_s
|
|
49
|
+
current = Array(model.doc[key])
|
|
50
|
+
original = Array(model.original_doc[key])
|
|
51
|
+
next if current == original
|
|
52
|
+
|
|
53
|
+
diff ||= {}
|
|
54
|
+
diff[:id] ||= model.id if model.respond_to?(:id)
|
|
55
|
+
diff[field] = { additions: current - original, removals: original - current }
|
|
56
|
+
end
|
|
57
|
+
diff
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Reshaping `from_model`: base diff (via {Logic::Input.from_model}) + set-diff deltas.
|
|
61
|
+
# @param model [Common::GraphQL::Model] the subject model.
|
|
62
|
+
# @return [Hash, nil] the mutation input hash, or nil when there are no changes.
|
|
63
|
+
def from_model(model, **kargs)
|
|
64
|
+
diff = Logic::Input.from_model(model, **kargs)
|
|
65
|
+
merge_id_diffs(model, diff)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Declarative FULL-ARRAY macro for id-list fields that the schema exposes as a plain
|
|
70
|
+
# `[ID!]` on the *update* mutation (NOT `IdDiffInput`). The server expects the COMPLETE
|
|
71
|
+
# current array, replacing the stored value wholesale — there is no additions/removals
|
|
72
|
+
# delta shape. This is the counterpart to {IdDiffFields}.
|
|
73
|
+
#
|
|
74
|
+
# Mixed into any Input class via `extend`, exactly like {IdDiffFields}. Data-model Input
|
|
75
|
+
# classes call `extend Logic::Input::FullArrayFields` explicitly.
|
|
76
|
+
#
|
|
77
|
+
# Usage:
|
|
78
|
+
# class Update < Base::Action
|
|
79
|
+
# extend Logic::Input::FullArrayFields
|
|
80
|
+
# full_array_fields :assignedPersonMemberIds, :locationIds, :fileContainerIds
|
|
81
|
+
# end
|
|
82
|
+
#
|
|
83
|
+
# It installs (or augments) a `from_model` that, for each declared field, emits the FULL
|
|
84
|
+
# current array taken DIRECTLY from the READ model's `doc[key]` whenever it differs from
|
|
85
|
+
# `original_doc[key]`. A field is omitted when unchanged. The value is read directly (NOT
|
|
86
|
+
# via the cascaded DiffService) because these array fields are dropped from the flat diff
|
|
87
|
+
# and the read model is `root!`.
|
|
88
|
+
#
|
|
89
|
+
# Schema evidence (live introspection 20260605, UpdateActionInput):
|
|
90
|
+
# assignedPersonMemberIds : [ID!]
|
|
91
|
+
# locationIds : [ID!]
|
|
92
|
+
# fileContainerIds : [ID!]
|
|
93
|
+
# None are `IdDiffInput` — hence full-array, not delta.
|
|
94
|
+
module FullArrayFields
|
|
95
|
+
# @return [Array<Symbol>] the fields declared for full-array emission on this class.
|
|
96
|
+
def full_array_fields_list
|
|
97
|
+
@full_array_fields_list ||= []
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Declares the id-list fields that must be emitted as their COMPLETE current array.
|
|
101
|
+
# @param fields [Array<Symbol>] field names (as they appear in the read model's doc).
|
|
102
|
+
# @return [void]
|
|
103
|
+
def full_array_fields(*fields)
|
|
104
|
+
full_array_fields_list.concat(fields.flatten.map(&:to_sym)).uniq!
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Emits the full current array for each changed declared field and merges it into +diff+.
|
|
108
|
+
# @param model [Common::GraphQL::Model] the subject (read) model.
|
|
109
|
+
# @param diff [Hash, nil] the base mutation input hash to augment (may be nil).
|
|
110
|
+
# @return [Hash, nil] +diff+ with per-field full arrays merged in, or the original
|
|
111
|
+
# value when nothing changed.
|
|
112
|
+
def merge_full_arrays(model, diff)
|
|
113
|
+
full_array_fields_list.each do |field|
|
|
114
|
+
key = field.to_s
|
|
115
|
+
current = Array(model.doc[key])
|
|
116
|
+
original = Array(model.original_doc[key])
|
|
117
|
+
next if current == original
|
|
118
|
+
|
|
119
|
+
diff ||= {}
|
|
120
|
+
diff[:id] ||= model.id if model.respond_to?(:id)
|
|
121
|
+
diff[field] = current
|
|
122
|
+
end
|
|
123
|
+
diff
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Reshaping `from_model`: base diff (via {Logic::Input.from_model}) + full arrays.
|
|
127
|
+
# @param model [Common::GraphQL::Model] the subject model.
|
|
128
|
+
# @return [Hash, nil] the mutation input hash, or nil when there are no changes.
|
|
129
|
+
def from_model(model, **kargs)
|
|
130
|
+
diff = Logic::Input.from_model(model, **kargs)
|
|
131
|
+
merge_full_arrays(model, diff)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
8
135
|
class << self
|
|
9
136
|
# Builds a mutation input hash from a model's diff.
|
|
10
137
|
# Subclasses override this to reshape fields (e.g. array → IdDiffInput).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Model
|
|
5
|
+
class ActionEvent < Base::ActionEvent
|
|
6
|
+
# assignedPersonMembers: [PreviewPersonMember!]! — Model::PersonMember's
|
|
7
|
+
# read fields are a compatible superset.
|
|
8
|
+
embeds_many :assignedPersonMembers, klass: Model::PersonMember
|
|
9
|
+
embeds_many :pages, klass: "Ecoportal::API::GraphQL::Model::ActionEventPage"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Model
|
|
5
|
+
# Concrete read model for a page activity/history entry. Adds the
|
|
6
|
+
# relational embeds on top of the common interface fields in Base::Activity.
|
|
7
|
+
class Activity < Base::Activity
|
|
8
|
+
embeds_one :personMember, klass: Model::PersonMember, nullable: true
|
|
9
|
+
embeds_one :user, klass: Model::User, nullable: true
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|