ecoportal-api-graphql 1.3.17 → 2.0.0
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 +384 -15
- data/LICENSE +21 -21
- data/README.md +24 -24
- data/lib/ecoportal/api/common/graphql/CLAUDE.md +36 -0
- data/lib/ecoportal/api/common/graphql/auth_service.rb +115 -115
- data/lib/ecoportal/api/common/graphql/class_helpers.rb +46 -46
- data/lib/ecoportal/api/common/graphql/client.rb +69 -69
- data/lib/ecoportal/api/common/graphql/hash_helpers.rb +105 -105
- data/lib/ecoportal/api/common/graphql/model/CLAUDE.md +28 -0
- data/lib/ecoportal/api/common/graphql/model/as_input.rb +54 -54
- data/lib/ecoportal/api/common/graphql/model/diffable/classic_diff_service.rb +49 -49
- data/lib/ecoportal/api/common/graphql/model/diffable/diff_service.rb +188 -188
- data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff.rb +55 -55
- data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff_nesting.rb +295 -295
- 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/common/graphql/model.rb +17 -17
- data/lib/ecoportal/api/common/graphql/patches.rb +1 -1
- data/lib/ecoportal/api/common/graphql/query_integration.rb +45 -45
- data/lib/ecoportal/api/common/graphql.rb +16 -16
- data/lib/ecoportal/api/common.graphql.rb +8 -8
- data/lib/ecoportal/api/graphql/CLAUDE.md +37 -0
- data/lib/ecoportal/api/graphql/base/CLAUDE.md +50 -0
- data/lib/ecoportal/api/graphql/base/action.rb +1 -1
- data/lib/ecoportal/api/graphql/base/action_category.rb +15 -15
- 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 +13 -8
- 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/contractor_entity.rb +24 -24
- data/lib/ecoportal/api/graphql/base/date_time.rb +12 -12
- data/lib/ecoportal/api/graphql/base/delta_result.rb +16 -16
- data/lib/ecoportal/api/graphql/base/field.rb +12 -12
- data/lib/ecoportal/api/graphql/base/file_attachment.rb +15 -15
- 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_node.rb +14 -14
- data/lib/ecoportal/api/graphql/base/location_structure/draft/structure.rb +37 -37
- data/lib/ecoportal/api/graphql/base/location_structure/draft.rb +93 -93
- 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/actions_list.rb +9 -9
- data/lib/ecoportal/api/graphql/base/page/data_field/ai_summary.rb +18 -18
- data/lib/ecoportal/api/graphql/base/page/data_field/checklist.rb +29 -29
- data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +1 -1
- data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +25 -2
- data/lib/ecoportal/api/graphql/base/page/data_field/cross_reference.rb +1 -1
- data/lib/ecoportal/api/graphql/base/page/data_field/date_field.rb +23 -23
- data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +46 -7
- data/lib/ecoportal/api/graphql/base/page/data_field/geo.rb +24 -24
- data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +6 -3
- data/lib/ecoportal/api/graphql/base/page/data_field/law.rb +8 -8
- data/lib/ecoportal/api/graphql/base/page/data_field/mailbox.rb +9 -9
- data/lib/ecoportal/api/graphql/base/page/data_field/people.rb +50 -12
- data/lib/ecoportal/api/graphql/base/page/data_field/plain_text.rb +17 -17
- data/lib/ecoportal/api/graphql/base/page/data_field/rich_text.rb +26 -26
- data/lib/ecoportal/api/graphql/base/page/data_field/signature.rb +9 -9
- data/lib/ecoportal/api/graphql/base/page/data_field/smart_fill.rb +17 -17
- data/lib/ecoportal/api/graphql/base/page/data_field/table.rb +9 -9
- data/lib/ecoportal/api/graphql/base/page/data_field/tag_field.rb +21 -21
- data/lib/ecoportal/api/graphql/base/page/data_field.rb +12 -18
- data/lib/ecoportal/api/graphql/base/page/phased.rb +15 -15
- data/lib/ecoportal/api/graphql/base/page/section.rb +48 -48
- data/lib/ecoportal/api/graphql/base/page_info.rb +12 -12
- data/lib/ecoportal/api/graphql/base/pages_workflow/operation_interface.rb +39 -39
- data/lib/ecoportal/api/graphql/base/pages_workflow/operations/assign_to.rb +27 -27
- data/lib/ecoportal/api/graphql/base/pages_workflow/operations/send_notification.rb +30 -30
- data/lib/ecoportal/api/graphql/base/pages_workflow/recipient_config.rb +34 -34
- data/lib/ecoportal/api/graphql/base/pages_workflow.rb +35 -35
- data/lib/ecoportal/api/graphql/base/permissions.rb +15 -0
- data/lib/ecoportal/api/graphql/base/person_member.rb +22 -22
- 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/preview_page.rb +23 -23
- data/lib/ecoportal/api/graphql/base/register.rb +6 -1
- data/lib/ecoportal/api/graphql/base/resource.rb +13 -13
- data/lib/ecoportal/api/graphql/base.rb +9 -0
- data/lib/ecoportal/api/graphql/builder/CLAUDE.md +65 -0
- data/lib/ecoportal/api/graphql/builder/action.rb +41 -41
- data/lib/ecoportal/api/graphql/builder/contractor_entity.rb +10 -0
- data/lib/ecoportal/api/graphql/builder/location_structure/draft.rb +64 -64
- data/lib/ecoportal/api/graphql/builder/location_structure.rb +40 -40
- data/lib/ecoportal/api/graphql/builder/page.rb +0 -16
- data/lib/ecoportal/api/graphql/builder/register/preset_view.rb +84 -84
- data/lib/ecoportal/api/graphql/builder/register.rb +49 -49
- data/lib/ecoportal/api/graphql/builder/template.rb +18 -0
- data/lib/ecoportal/api/graphql/compat/filter_translator.rb +1 -1
- data/lib/ecoportal/api/graphql/compat/page_reference.rb +23 -23
- data/lib/ecoportal/api/graphql/compat/pages.rb +7 -2
- data/lib/ecoportal/api/graphql/compat/registers.rb +84 -84
- data/lib/ecoportal/api/graphql/compat/response.rb +14 -0
- data/lib/ecoportal/api/graphql/compat/search_results.rb +33 -33
- data/lib/ecoportal/api/graphql/compat.rb +17 -17
- data/lib/ecoportal/api/graphql/concerns/data_field_access.rb +71 -71
- data/lib/ecoportal/api/graphql/concerns/fragment_definitions.rb +68 -68
- data/lib/ecoportal/api/graphql/concerns/snake_camel_access.rb +60 -60
- 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/preset_view.rb +11 -11
- data/lib/ecoportal/api/graphql/connection/preview_page.rb +1 -1
- data/lib/ecoportal/api/graphql/connection.rb +5 -0
- data/lib/ecoportal/api/graphql/diff/pairing/signals.rb +21 -1
- data/lib/ecoportal/api/graphql/error/locations_error/fetch_nested.rb +51 -51
- data/lib/ecoportal/api/graphql/error/locations_error.rb +28 -28
- data/lib/ecoportal/api/graphql/error/locations_validation_error.rb +20 -20
- data/lib/ecoportal/api/graphql/error/validation_errors.rb +28 -28
- data/lib/ecoportal/api/graphql/error.rb +12 -12
- data/lib/ecoportal/api/graphql/file_upload/client.rb +198 -139
- data/lib/ecoportal/api/graphql/file_upload.rb +10 -10
- data/lib/ecoportal/api/graphql/fragment/action.rb +65 -65
- data/lib/ecoportal/api/graphql/fragment/action_category.rb +17 -17
- 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/contractor_entity.rb +20 -20
- data/lib/ecoportal/api/graphql/fragment/location_node.rb +1 -0
- data/lib/ecoportal/api/graphql/fragment/locations_error.rb +19 -19
- data/lib/ecoportal/api/graphql/fragment/minimal_dashboard.rb +31 -0
- data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +21 -0
- data/lib/ecoportal/api/graphql/fragment/pages.rb +15 -15
- data/lib/ecoportal/api/graphql/fragment/pagination.rb +17 -17
- data/lib/ecoportal/api/graphql/fragment/permissions.rb +98 -0
- data/lib/ecoportal/api/graphql/fragment/person_member_changelog.rb +33 -0
- data/lib/ecoportal/api/graphql/fragment.rb +7 -0
- data/lib/ecoportal/api/graphql/helpers/locations_tree.rb +41 -41
- data/lib/ecoportal/api/graphql/helpers.rb +10 -10
- data/lib/ecoportal/api/graphql/input/action/archive.rb +14 -14
- data/lib/ecoportal/api/graphql/input/action/create.rb +13 -13
- data/lib/ecoportal/api/graphql/input/action/update.rb +12 -0
- data/lib/ecoportal/api/graphql/input/action.rb +14 -14
- data/lib/ecoportal/api/graphql/input/contractor_entity/create.rb +14 -14
- data/lib/ecoportal/api/graphql/input/contractor_entity/destroy.rb +13 -13
- 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/delta_input.rb +16 -16
- data/lib/ecoportal/api/graphql/input/id_diff.rb +11 -11
- data/lib/ecoportal/api/graphql/input/location_structure/apply_commands.rb +2 -2
- data/lib/ecoportal/api/graphql/input/location_structure/archive_command.rb +13 -13
- data/lib/ecoportal/api/graphql/input/location_structure/delete_command.rb +13 -13
- data/lib/ecoportal/api/graphql/input/location_structure/draft/add_commands.rb +2 -2
- data/lib/ecoportal/api/graphql/input/location_structure/draft/create.rb +15 -15
- data/lib/ecoportal/api/graphql/input/location_structure/draft/delete.rb +15 -15
- data/lib/ecoportal/api/graphql/input/location_structure/draft/drop_bad_commands.rb +16 -16
- data/lib/ecoportal/api/graphql/input/location_structure/draft/publish.rb +16 -16
- data/lib/ecoportal/api/graphql/input/location_structure/draft.rb +19 -19
- data/lib/ecoportal/api/graphql/input/location_structure/insert_command.rb +13 -13
- data/lib/ecoportal/api/graphql/input/location_structure/move_command.rb +14 -14
- data/lib/ecoportal/api/graphql/input/location_structure/reorder_command.rb +13 -13
- data/lib/ecoportal/api/graphql/input/location_structure/unarchive_command.rb +13 -13
- data/lib/ecoportal/api/graphql/input/location_structure/update_command.rb +6 -2
- data/lib/ecoportal/api/graphql/input/location_structure.rb +20 -20
- data/lib/ecoportal/api/graphql/input/page/archive.rb +14 -14
- data/lib/ecoportal/api/graphql/input/page/build_from_template.rb +13 -13
- data/lib/ecoportal/api/graphql/input/page/create_draft.rb +13 -13
- data/lib/ecoportal/api/graphql/input/page/create_from_template.rb +18 -18
- data/lib/ecoportal/api/graphql/input/page/delete_draft.rb +13 -13
- data/lib/ecoportal/api/graphql/input/page/publish_draft.rb +13 -13
- data/lib/ecoportal/api/graphql/input/page/review_task.rb +14 -14
- data/lib/ecoportal/api/graphql/input/page/unarchive.rb +14 -14
- data/lib/ecoportal/api/graphql/input/page/update.rb +2 -2
- data/lib/ecoportal/api/graphql/input/page.rb +26 -26
- data/lib/ecoportal/api/graphql/input/preset_view/create.rb +18 -18
- data/lib/ecoportal/api/graphql/input/preset_view/permission.rb +16 -16
- data/lib/ecoportal/api/graphql/input/preset_view/update.rb +17 -2
- data/lib/ecoportal/api/graphql/input/preset_view.rb +14 -14
- data/lib/ecoportal/api/graphql/input/register/create.rb +18 -18
- data/lib/ecoportal/api/graphql/input/register/update.rb +15 -15
- data/lib/ecoportal/api/graphql/input/register.rb +13 -13
- data/lib/ecoportal/api/graphql/input/search.rb +13 -13
- data/lib/ecoportal/api/graphql/input/search_conf/ai_generator.rb +234 -234
- data/lib/ecoportal/api/graphql/input/search_conf.rb +1 -1
- data/lib/ecoportal/api/graphql/input/search_filter.rb +12 -12
- data/lib/ecoportal/api/graphql/input/search_sorter.rb +11 -11
- data/lib/ecoportal/api/graphql/input/workflow_command/add_action_tag.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_binding.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_checklist_field_item.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_comment_tagging_user_group.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_default_direct_strategy_user.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_default_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_direct_strategy_user.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_force.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_field_config.rb +23 -23
- data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_helper.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_direct_strategy_user.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_action_type.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_filter.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_people_field.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_task_config.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_user.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback.rb +23 -23
- data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback_action.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_section.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +19 -19
- 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_stage_section.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_tag.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_task.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_task_assignment_user_group.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/add_viewable_field.rb +45 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_workflow_callback.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/archive_public_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/collapse_section.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/create_public_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_binding.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_checklist_field_item.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_creator_permissions.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_default_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +12 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_gauge_field_stop.rb +19 -19
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_field_config.rb +19 -19
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_helper.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_public_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_reminder.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_required_sign_offs.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_comment_tagging.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_task_assignment.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_scheduled_callback.rb +22 -22
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_section_header.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +19 -19
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_smart_fill_config.rb +21 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_stage.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_task_due.rb +18 -18
- 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 +27 -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/edit_trigger.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/expand_section.rb +18 -18
- 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 +24 -24
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +3 -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/gauge.rb +20 -20
- 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/location_field.rb +24 -24
- 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 +3 -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/field_config/signature.rb +20 -20
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb +25 -25
- data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +3 -2
- data/lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/move_viewable_field.rb +33 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_binding.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_callback.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_checklist_field_item.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_comment_tagging_user_group.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_direct_strategy_user.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_direct_strategy_user.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_field.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_force.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_helper.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_direct_strategy_user.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_action_type.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_filter.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_people_field.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_task_config.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_user.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_scheduled_callback.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_section.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_smart_fill_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_section.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_tag.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_strategy.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_assignment_user_group.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_due.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_priority_level.rb +18 -18
- 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 +43 -5
- data/lib/ecoportal/api/graphql/input.rb +1 -0
- data/lib/ecoportal/api/graphql/interface/base_page.rb +36 -3
- data/lib/ecoportal/api/graphql/interface/location_structure/command.rb +2 -1
- data/lib/ecoportal/api/graphql/interface/location_structure/node.rb +43 -43
- data/lib/ecoportal/api/graphql/interface/location_structure.rb +14 -14
- data/lib/ecoportal/api/graphql/interface.rb +11 -11
- data/lib/ecoportal/api/graphql/logic/base_model.rb +15 -15
- data/lib/ecoportal/api/graphql/logic/base_query.rb +193 -193
- 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/logic/mutation.rb +59 -59
- data/lib/ecoportal/api/graphql/logic/payload.rb +42 -42
- data/lib/ecoportal/api/graphql/logic/query.rb +23 -23
- data/lib/ecoportal/api/graphql/logic/query_array.rb +30 -30
- data/lib/ecoportal/api/graphql/logic/query_connection.rb +48 -48
- data/lib/ecoportal/api/graphql/logic.rb +18 -18
- data/lib/ecoportal/api/graphql/model/account.rb +15 -15
- data/lib/ecoportal/api/graphql/model/action.rb +22 -22
- 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/ai_summary_version.rb +10 -10
- 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/contractor_entity.rb +12 -12
- data/lib/ecoportal/api/graphql/model/field.rb +10 -10
- data/lib/ecoportal/api/graphql/model/file_attachment.rb +10 -10
- data/lib/ecoportal/api/graphql/model/file_container.rb +11 -11
- data/lib/ecoportal/api/graphql/model/location_node.rb +14 -14
- data/lib/ecoportal/api/graphql/model/location_structure/draft/structure.rb +15 -15
- data/lib/ecoportal/api/graphql/model/location_structure/draft.rb +15 -15
- data/lib/ecoportal/api/graphql/model/location_structure.rb +16 -16
- data/lib/ecoportal/api/graphql/model/minimal_dashboard.rb +14 -0
- data/lib/ecoportal/api/graphql/model/organization.rb +27 -0
- data/lib/ecoportal/api/graphql/model/page/basic.rb +14 -14
- data/lib/ecoportal/api/graphql/model/page/data_field.rb +12 -12
- data/lib/ecoportal/api/graphql/model/page/phased/stage.rb +14 -14
- data/lib/ecoportal/api/graphql/model/page/section.rb +12 -12
- data/lib/ecoportal/api/graphql/model/page_union.rb +21 -21
- data/lib/ecoportal/api/graphql/model/pages_workflow.rb +20 -20
- data/lib/ecoportal/api/graphql/model/permissions.rb +179 -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/preset_view.rb +10 -10
- data/lib/ecoportal/api/graphql/model/preview_page.rb +10 -10
- data/lib/ecoportal/api/graphql/model/register.rb +10 -10
- data/lib/ecoportal/api/graphql/model/resource.rb +13 -13
- data/lib/ecoportal/api/graphql/model/user.rb +14 -14
- data/lib/ecoportal/api/graphql/model.rb +9 -0
- data/lib/ecoportal/api/graphql/mutation/action/archive.rb +41 -41
- data/lib/ecoportal/api/graphql/mutation/action/create.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/action/update.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/action.rb +14 -14
- data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +21 -11
- data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +26 -11
- data/lib/ecoportal/api/graphql/mutation/ai_summary.rb +13 -13
- data/lib/ecoportal/api/graphql/mutation/contractor_entity/create.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/contractor_entity/destroy.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/contractor_entity/update.rb +40 -40
- 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/location_structure/apply_commands.rb +54 -54
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/add_commands.rb +55 -55
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/create.rb +54 -54
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/delete.rb +43 -43
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/drop_bad_commands.rb +56 -56
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/publish.rb +66 -66
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft.rb +18 -18
- data/lib/ecoportal/api/graphql/mutation/location_structure.rb +13 -13
- data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/page/archive.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/page/build_from_template.rb +50 -50
- data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/page/create_from_template.rb +43 -43
- data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/page/unarchive.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/page/update.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/page.rb +28 -28
- data/lib/ecoportal/api/graphql/mutation/preset_view/create.rb +35 -35
- data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/preset_view/permission.rb +37 -37
- data/lib/ecoportal/api/graphql/mutation/preset_view/update.rb +35 -35
- data/lib/ecoportal/api/graphql/mutation/preset_view.rb +15 -15
- data/lib/ecoportal/api/graphql/mutation/register/create.rb +35 -35
- data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/register/update.rb +35 -35
- data/lib/ecoportal/api/graphql/mutation/register.rb +14 -14
- 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/action/archive.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/action/create.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/action/update.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/action.rb +14 -14
- data/lib/ecoportal/api/graphql/payload/ai_summary_generate.rb +12 -12
- data/lib/ecoportal/api/graphql/payload/contractor_entity/create.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/contractor_entity/destroy.rb +12 -12
- data/lib/ecoportal/api/graphql/payload/contractor_entity/manager_settings.rb +20 -0
- data/lib/ecoportal/api/graphql/payload/contractor_entity/update.rb +12 -12
- data/lib/ecoportal/api/graphql/payload/contractor_entity.rb +1 -0
- data/lib/ecoportal/api/graphql/payload/location_structure/apply_commands.rb +51 -51
- data/lib/ecoportal/api/graphql/payload/location_structure/command_execution_result.rb +50 -50
- data/lib/ecoportal/api/graphql/payload/location_structure/draft/add_commands.rb +30 -30
- data/lib/ecoportal/api/graphql/payload/location_structure/draft/delete.rb +30 -30
- data/lib/ecoportal/api/graphql/payload/location_structure/draft/drop_bad_commands.rb +43 -43
- data/lib/ecoportal/api/graphql/payload/location_structure/draft/publish.rb +63 -63
- data/lib/ecoportal/api/graphql/payload/location_structure/draft.rb +18 -18
- data/lib/ecoportal/api/graphql/payload/location_structure.rb +14 -14
- data/lib/ecoportal/api/graphql/payload/ok_payload.rb +1 -1
- data/lib/ecoportal/api/graphql/payload/page/archive.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/page/build_from_template.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/page/create_from_template.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/page/draft.rb +1 -1
- data/lib/ecoportal/api/graphql/payload/page/review_task.rb +1 -1
- data/lib/ecoportal/api/graphql/payload/page/unarchive.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/page/update.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/preset_view.rb +1 -1
- data/lib/ecoportal/api/graphql/payload/register.rb +1 -1
- 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/action.rb +33 -33
- data/lib/ecoportal/api/graphql/query/action_categories.rb +53 -53
- data/lib/ecoportal/api/graphql/query/actions.rb +43 -43
- 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/contractor_entities.rb +53 -53
- data/lib/ecoportal/api/graphql/query/dashboard_search.rb +57 -0
- data/lib/ecoportal/api/graphql/query/file_upload_signature.rb +76 -76
- data/lib/ecoportal/api/graphql/query/location_classifications.rb +39 -39
- 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/page_delta.rb +47 -47
- data/lib/ecoportal/api/graphql/query/pages.rb +59 -59
- 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/register_preset_views.rb +1 -1
- data/lib/ecoportal/api/graphql/query/register_preview_pages.rb +83 -83
- data/lib/ecoportal/api/graphql/query/templates.rb +53 -53
- data/lib/ecoportal/api/graphql/query.rb +6 -0
- data/lib/ecoportal/api/graphql_version.rb +1 -1
- data/lib/ecoportal/api-graphql.rb +10 -10
- metadata +78 -12
- 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,28 @@
|
|
|
1
|
+
# common/graphql/model
|
|
2
|
+
|
|
3
|
+
Concerns that add dirty-tracking diff (`Diffable`) and mutation-input serialisation (`AsInput`) to the base `Common::GraphQL::Model`.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
| File / class | Purpose |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `diffable.rb` / `Model::Diffable` | Provides `as_update` (returns changed-field hash or nil) and `dirty?`; delegates to `DIFF_CLASS` (defaults to `DiffService`) |
|
|
10
|
+
| `as_input.rb` / `Model::AsInput` | Instance `as_input` (wraps diff as mutation variables) + class-level `as_input(hash)` (key-sym + nil-id cleanup) |
|
|
11
|
+
| `diffable/diff_service.rb` / `DiffService` | Primary diff engine: flat classic diff then cascaded reduce over nested `GraphQL::Model` children |
|
|
12
|
+
| `diffable/classic_diff_service.rb` / `ClassicDiffService` | Low-level diff: compares `curr_doc` vs `prev_doc`, returns `{ id:, changed_field: new_value }` or nil |
|
|
13
|
+
| `diffable/hash_diff.rb` / `HashDiff` | Primitive equality helpers used by `ClassicDiffService` |
|
|
14
|
+
| `diffable/hash_diff_nesting.rb` / `HashDiffNesting` | Nested path helpers: `dig_set!`, `dig_delete!`, `dig_path?` used when building cascaded diff results |
|
|
15
|
+
|
|
16
|
+
## Conventions
|
|
17
|
+
|
|
18
|
+
- `DIFF_CLASS = DiffService` is a constant on `Diffable` — subclasses can override it to swap diff strategies.
|
|
19
|
+
- `DiffService` `flat: true` produces a single-level diff (current model only); `flat: false` (default) recurses via `cascaded_reduce` through nested `GraphQL::Model` objects.
|
|
20
|
+
- Objects declared with `root!` in their class are skipped during cascaded diff — they are independent server entities (look-ups only).
|
|
21
|
+
- `as_input` on a model calls `as_update` first; returns `nil` when nothing has changed so callers can skip the mutation.
|
|
22
|
+
- `as_input(target_class:)` is the preferred path when a corresponding `Input::X` class exists — delegates to `target_class.from_model(self)`.
|
|
23
|
+
|
|
24
|
+
## Related
|
|
25
|
+
|
|
26
|
+
- `../hash_helpers.rb` — `HashHelpers` used inside `DiffService` for key transforms
|
|
27
|
+
- `../../graphql/logic/input.rb` — `Logic::Input.from_model` is the canonical consumer of `as_update`
|
|
28
|
+
- `../../graphql/logic/base_model.rb` — all concrete models inherit this chain
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
module Ecoportal
|
|
2
|
-
module API
|
|
3
|
-
module Common
|
|
4
|
-
module GraphQL
|
|
5
|
-
class Model
|
|
6
|
-
# @todo
|
|
7
|
-
# 1. `#as_input` vs `#to_input` **or** named argument `klass`
|
|
8
|
-
# One gets the `input` to be already used in a mutation query.
|
|
9
|
-
# The other gets the `Input` class object out of the `Base/Model`.
|
|
10
|
-
# - To figure out when `as_update` should be called.
|
|
11
|
-
# 2. Each Base/Model should have its `Input` class counterpart.
|
|
12
|
-
# This could be auto-inflected (via namespace constant lookup)
|
|
13
|
-
# at some point.
|
|
14
|
-
# 3. Think if a service class can be used to this purpose
|
|
15
|
-
# (i.e. decorator of DiffService).
|
|
16
|
-
module AsInput
|
|
17
|
-
class << self
|
|
18
|
-
def included(base)
|
|
19
|
-
super
|
|
20
|
-
|
|
21
|
-
base.send(:include, Model::Diffable)
|
|
22
|
-
base.extend ClassMethods
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
module ClassMethods
|
|
27
|
-
def as_input(hash, clientMutationId: '')
|
|
28
|
-
hash_input = Ecoportal::API::Common::GraphQL::HashHelpers.
|
|
29
|
-
keys_to_sym_deep(hash)
|
|
30
|
-
|
|
31
|
-
hash_input.merge!(clientMutationId: clientMutationId)
|
|
32
|
-
|
|
33
|
-
Ecoportal::API::Common::GraphQL::HashHelpers.
|
|
34
|
-
remove_nil_keys_deep(hash_input, target: :id)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# INSTANCE METHODS
|
|
39
|
-
|
|
40
|
-
def as_input(target_class: nil, clientMutationId: '')
|
|
41
|
-
return target_class.from_model(self, client_mutation_id: clientMutationId) if target_class
|
|
42
|
-
|
|
43
|
-
diff = as_update
|
|
44
|
-
return nil if diff.nil?
|
|
45
|
-
|
|
46
|
-
diff[:patchVer] = patchVer if respond_to?(:patchVer) && !patchVer.nil?
|
|
47
|
-
self.class.as_input(diff, clientMutationId: clientMutationId)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
module Common
|
|
4
|
+
module GraphQL
|
|
5
|
+
class Model
|
|
6
|
+
# @todo
|
|
7
|
+
# 1. `#as_input` vs `#to_input` **or** named argument `klass`
|
|
8
|
+
# One gets the `input` to be already used in a mutation query.
|
|
9
|
+
# The other gets the `Input` class object out of the `Base/Model`.
|
|
10
|
+
# - To figure out when `as_update` should be called.
|
|
11
|
+
# 2. Each Base/Model should have its `Input` class counterpart.
|
|
12
|
+
# This could be auto-inflected (via namespace constant lookup)
|
|
13
|
+
# at some point.
|
|
14
|
+
# 3. Think if a service class can be used to this purpose
|
|
15
|
+
# (i.e. decorator of DiffService).
|
|
16
|
+
module AsInput
|
|
17
|
+
class << self
|
|
18
|
+
def included(base)
|
|
19
|
+
super
|
|
20
|
+
|
|
21
|
+
base.send(:include, Model::Diffable)
|
|
22
|
+
base.extend ClassMethods
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module ClassMethods
|
|
27
|
+
def as_input(hash, clientMutationId: '')
|
|
28
|
+
hash_input = Ecoportal::API::Common::GraphQL::HashHelpers.
|
|
29
|
+
keys_to_sym_deep(hash)
|
|
30
|
+
|
|
31
|
+
hash_input.merge!(clientMutationId: clientMutationId)
|
|
32
|
+
|
|
33
|
+
Ecoportal::API::Common::GraphQL::HashHelpers.
|
|
34
|
+
remove_nil_keys_deep(hash_input, target: :id)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# INSTANCE METHODS
|
|
39
|
+
|
|
40
|
+
def as_input(target_class: nil, clientMutationId: '')
|
|
41
|
+
return target_class.from_model(self, client_mutation_id: clientMutationId) if target_class
|
|
42
|
+
|
|
43
|
+
diff = as_update
|
|
44
|
+
return nil if diff.nil?
|
|
45
|
+
|
|
46
|
+
diff[:patchVer] = patchVer if respond_to?(:patchVer) && !patchVer.nil?
|
|
47
|
+
self.class.as_input(diff, clientMutationId: clientMutationId)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
2
|
-
class ClassicDiffService
|
|
3
|
-
include Ecoportal::API::Common::GraphQL::Model::Diffable::HashDiffNesting
|
|
4
|
-
|
|
5
|
-
attr_reader :subject
|
|
6
|
-
|
|
7
|
-
def initialize(subject, ignore: [])
|
|
8
|
-
msg = 'Expecting Ecoportal::API::Common::Content::DoubleModel. '
|
|
9
|
-
msg << "Given: #{subject.class}"
|
|
10
|
-
raise ArgumentError, msg unless subject.is_a?(Ecoportal::API::Common::Content::DoubleModel)
|
|
11
|
-
|
|
12
|
-
@subject = subject
|
|
13
|
-
@ignored = to_a(ignore)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def diff(ignore: [])
|
|
17
|
-
classic_diff(ignore: ignore)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
protected
|
|
21
|
-
|
|
22
|
-
def classic_diff(ignore: [])
|
|
23
|
-
change_diff(
|
|
24
|
-
curr_doc,
|
|
25
|
-
prev_doc,
|
|
26
|
-
ignore: to_a(ignored, ignore)
|
|
27
|
-
)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
private
|
|
31
|
-
|
|
32
|
-
attr_reader :ignored
|
|
33
|
-
|
|
34
|
-
def curr_doc(target = subject)
|
|
35
|
-
return target.as_json if target.respond_to?(:as_json)
|
|
36
|
-
return target.doc if target.respond_to?(:doc)
|
|
37
|
-
|
|
38
|
-
raise "Can't fetch underlying document for instance of #{target.class}."
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def prev_doc(target = subject)
|
|
42
|
-
return target.original_doc if target.respond_to?(:original_doc)
|
|
43
|
-
|
|
44
|
-
raise "Can't fetch original underlying model for instance of #{target.class}."
|
|
45
|
-
rescue NoMethodError
|
|
46
|
-
nil
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
1
|
+
module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
2
|
+
class ClassicDiffService
|
|
3
|
+
include Ecoportal::API::Common::GraphQL::Model::Diffable::HashDiffNesting
|
|
4
|
+
|
|
5
|
+
attr_reader :subject
|
|
6
|
+
|
|
7
|
+
def initialize(subject, ignore: [])
|
|
8
|
+
msg = 'Expecting Ecoportal::API::Common::Content::DoubleModel. '
|
|
9
|
+
msg << "Given: #{subject.class}"
|
|
10
|
+
raise ArgumentError, msg unless subject.is_a?(Ecoportal::API::Common::Content::DoubleModel)
|
|
11
|
+
|
|
12
|
+
@subject = subject
|
|
13
|
+
@ignored = to_a(ignore)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def diff(ignore: [])
|
|
17
|
+
classic_diff(ignore: ignore)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
protected
|
|
21
|
+
|
|
22
|
+
def classic_diff(ignore: [])
|
|
23
|
+
change_diff(
|
|
24
|
+
curr_doc,
|
|
25
|
+
prev_doc,
|
|
26
|
+
ignore: to_a(ignored, ignore)
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
attr_reader :ignored
|
|
33
|
+
|
|
34
|
+
def curr_doc(target = subject)
|
|
35
|
+
return target.as_json if target.respond_to?(:as_json)
|
|
36
|
+
return target.doc if target.respond_to?(:doc)
|
|
37
|
+
|
|
38
|
+
raise "Can't fetch underlying document for instance of #{target.class}."
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def prev_doc(target = subject)
|
|
42
|
+
return target.original_doc if target.respond_to?(:original_doc)
|
|
43
|
+
|
|
44
|
+
raise "Can't fetch original underlying model for instance of #{target.class}."
|
|
45
|
+
rescue NoMethodError
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -1,188 +1,188 @@
|
|
|
1
|
-
module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
2
|
-
class DiffService < ClassicDiffService
|
|
3
|
-
include Ecoportal::API::Common::GraphQL::Model::Diffable::HashDiffNesting
|
|
4
|
-
include Ecoportal::API::Common::GraphQL::HashHelpers
|
|
5
|
-
|
|
6
|
-
def initialize(subject, flat: false, ignore: [])
|
|
7
|
-
super(subject, ignore: ignore)
|
|
8
|
-
|
|
9
|
-
@flat = flat
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def flat?
|
|
13
|
-
@flat
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# @param flat [Boolean] whethere it should skip nested models.
|
|
17
|
-
# @param cascaded [Boolean] whether it should cascade the calls through
|
|
18
|
-
# the nested models.
|
|
19
|
-
# - When `flat` is `true` will only cascade the 1st level of nested models.
|
|
20
|
-
# - When `flat` is `false` will do a full cascade.
|
|
21
|
-
def diff(flat: flat?, ignore: [])
|
|
22
|
-
classic_diff(
|
|
23
|
-
flat: true,
|
|
24
|
-
ignore: ignore
|
|
25
|
-
).then do |value|
|
|
26
|
-
next value if flat
|
|
27
|
-
|
|
28
|
-
diff_reduce(
|
|
29
|
-
value,
|
|
30
|
-
ignore: ignore
|
|
31
|
-
)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
protected
|
|
36
|
-
|
|
37
|
-
# Override: GraphQL mutations expect flat changed-prop values, not patch-op wrappers.
|
|
38
|
-
# Returns { id: ..., changed_field: new_value, ... } or nil when nothing changed.
|
|
39
|
-
def classic_diff(flat: flat?, ignore: [])
|
|
40
|
-
curr = keys_to_sym_deep(curr_doc(flat: flat) || {})
|
|
41
|
-
prev = keys_to_sym_deep(prev_doc(flat: flat) || {})
|
|
42
|
-
|
|
43
|
-
data = change_data(curr, prev, ignore: to_a(ignored, ignore))
|
|
44
|
-
return nil if data == NO_CHANGES
|
|
45
|
-
|
|
46
|
-
id = get_id(curr, exception: false)
|
|
47
|
-
id ? { id: id }.merge(data) : data
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# @note it calls `as_update` for nested / cascaded attributes, which in turn
|
|
51
|
-
# will use this `DiffService`. Therefore, we aim for a first flat classic diff,
|
|
52
|
-
# onto `self`, and cascaded callbacks for the nested attributes.
|
|
53
|
-
# - This will translate into `key_path` being lost on each jump between
|
|
54
|
-
# `#as_update` and `DiffService#diff`.
|
|
55
|
-
# - The `result` object regards, therefore, to the **current level** alone.
|
|
56
|
-
# With the aim of building it up (accumulating through the call chain).
|
|
57
|
-
def diff_reduce(init, ignore: [])
|
|
58
|
-
subject.cascaded_reduce(init, recurs: false) do |result, obj, _key, key_path, _trace|
|
|
59
|
-
next result if key_path.empty?
|
|
60
|
-
next result if obj == subject
|
|
61
|
-
|
|
62
|
-
sym_path = key_path.map(&:to_sym)
|
|
63
|
-
|
|
64
|
-
# Remove any flat-diff placeholder for this key before deciding its fate.
|
|
65
|
-
dig_delete!(result, sym_path) if result && dig_path?(result, sym_path)
|
|
66
|
-
|
|
67
|
-
# Discard root-class objects — they are independent entities, not mutation payload.
|
|
68
|
-
next result if root?(obj)
|
|
69
|
-
# Only cascade-diff GraphQL model objects; ecoportal-api-v2 DoubleModel
|
|
70
|
-
# subclasses (ArrayModel, etc.) have a different as_update signature.
|
|
71
|
-
next result unless obj.is_a?(Ecoportal::API::Common::GraphQL::Model)
|
|
72
|
-
|
|
73
|
-
value = obj.as_update(ignore: ignore)
|
|
74
|
-
next result if value.nil?
|
|
75
|
-
|
|
76
|
-
result ||= {}
|
|
77
|
-
result[:id] ||= get_id(keys_to_sym_deep(curr_doc(flat: true) || {}), exception: false)
|
|
78
|
-
dig_set!(result, sym_path, value)
|
|
79
|
-
result
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# PROBLEM: trace can't be used with knowing if it's the root of the call!
|
|
84
|
-
# see `#cascaded_reduce` (when calling `_cascaded_attributes_trace`).
|
|
85
|
-
def diff_reduce_with_as_update_and_trace(init = {}, ignore: [], trace: {})
|
|
86
|
-
subject.cascaded_reduce(init, recurs: false, trace: trace) do |result, obj, _key, key_path, _trace|
|
|
87
|
-
next result if key_path.empty? # first iteration already done
|
|
88
|
-
next result if obj == subject # first call had done it
|
|
89
|
-
|
|
90
|
-
dig_delete!(result, key_path) if dig_path?(result, key_path)
|
|
91
|
-
|
|
92
|
-
# discard rooted (i.e. read_only) objects from the diff.
|
|
93
|
-
next result if root?(obj)
|
|
94
|
-
next result unless dig_path?(result, key_path)
|
|
95
|
-
next result unless obj.respond_to?(:as_update)
|
|
96
|
-
|
|
97
|
-
value = obj.as_update(ignore: ignore)
|
|
98
|
-
|
|
99
|
-
dig_set!(
|
|
100
|
-
result,
|
|
101
|
-
key_path,
|
|
102
|
-
value
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
result
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# FAILS to CALL #as_update on each object!!!
|
|
110
|
-
def diff_reduce_preserve_keys(init, flat: flat?, ignore: [])
|
|
111
|
-
subject.cascaded_reduce(init, recurs: !flat) do |result, obj, _key, key_path, _trace|
|
|
112
|
-
# discard rooted (i.e. read_only) objects from the diff.
|
|
113
|
-
if root?(obj)
|
|
114
|
-
dig_delete!(result, key_path)
|
|
115
|
-
else
|
|
116
|
-
value = classic_diff(
|
|
117
|
-
obj,
|
|
118
|
-
flat: true,
|
|
119
|
-
ignore: ignore
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
dig_set!(result, key_path, value)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
result
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def cascaded_diff(flat: flat?, ignore: [])
|
|
130
|
-
subject.cascaded_callback(
|
|
131
|
-
method: :as_update,
|
|
132
|
-
kargs: {
|
|
133
|
-
ignore: to_a(ignored, ignore),
|
|
134
|
-
flat: flat
|
|
135
|
-
},
|
|
136
|
-
recurs: !flat
|
|
137
|
-
) do |result, value, key_path, obj|
|
|
138
|
-
result.tap do
|
|
139
|
-
# on first call key_path is empty
|
|
140
|
-
next result if key_path.empty? # this condition isn't met, first call doesn't yield.
|
|
141
|
-
|
|
142
|
-
# discard rooted (i.e. read_only) objects from the diff.
|
|
143
|
-
if root?(obj)
|
|
144
|
-
dig_delete!(result, key_path)
|
|
145
|
-
else
|
|
146
|
-
dig_set!(result, key_path, value)
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
private
|
|
153
|
-
|
|
154
|
-
attr_reader :ignored
|
|
155
|
-
|
|
156
|
-
def root?(obj)
|
|
157
|
-
# root? is a CLASS method (via Rootable::ClassMethods). The instance root?
|
|
158
|
-
# is protected and checks parent position, not the class declaration.
|
|
159
|
-
# Check the ancestor chain for any class that declared root!.
|
|
160
|
-
obj.class.ancestors.any? { |k| k.respond_to?(:root?) && k.root? }
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def curr_doc(target = subject, flat: flat?)
|
|
164
|
-
may_use_flat_diff(flat) { super(target) }
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def prev_doc(target = subject, flat: flat?)
|
|
168
|
-
may_use_flat_diff(flat) { super(target) }
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
# Remove nested attributes
|
|
172
|
-
def may_use_flat_diff(flat = flat?)
|
|
173
|
-
yield.then do |json|
|
|
174
|
-
next json unless flat
|
|
175
|
-
|
|
176
|
-
doc_with_non_cascaded_attributes(json)
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
# Remove from `json` doc all the nested properties.
|
|
181
|
-
def doc_with_non_cascaded_attributes(json)
|
|
182
|
-
return json unless subject.class.respond_to?(:_cascaded_doc_keys)
|
|
183
|
-
return json if (excluded = subject.class._cascaded_doc_keys).empty?
|
|
184
|
-
|
|
185
|
-
except_keys(json, *excluded)
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
end
|
|
1
|
+
module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
2
|
+
class DiffService < ClassicDiffService
|
|
3
|
+
include Ecoportal::API::Common::GraphQL::Model::Diffable::HashDiffNesting
|
|
4
|
+
include Ecoportal::API::Common::GraphQL::HashHelpers
|
|
5
|
+
|
|
6
|
+
def initialize(subject, flat: false, ignore: [])
|
|
7
|
+
super(subject, ignore: ignore)
|
|
8
|
+
|
|
9
|
+
@flat = flat
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def flat?
|
|
13
|
+
@flat
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @param flat [Boolean] whethere it should skip nested models.
|
|
17
|
+
# @param cascaded [Boolean] whether it should cascade the calls through
|
|
18
|
+
# the nested models.
|
|
19
|
+
# - When `flat` is `true` will only cascade the 1st level of nested models.
|
|
20
|
+
# - When `flat` is `false` will do a full cascade.
|
|
21
|
+
def diff(flat: flat?, ignore: [])
|
|
22
|
+
classic_diff(
|
|
23
|
+
flat: true,
|
|
24
|
+
ignore: ignore
|
|
25
|
+
).then do |value|
|
|
26
|
+
next value if flat
|
|
27
|
+
|
|
28
|
+
diff_reduce(
|
|
29
|
+
value,
|
|
30
|
+
ignore: ignore
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
|
|
37
|
+
# Override: GraphQL mutations expect flat changed-prop values, not patch-op wrappers.
|
|
38
|
+
# Returns { id: ..., changed_field: new_value, ... } or nil when nothing changed.
|
|
39
|
+
def classic_diff(flat: flat?, ignore: [])
|
|
40
|
+
curr = keys_to_sym_deep(curr_doc(flat: flat) || {})
|
|
41
|
+
prev = keys_to_sym_deep(prev_doc(flat: flat) || {})
|
|
42
|
+
|
|
43
|
+
data = change_data(curr, prev, ignore: to_a(ignored, ignore))
|
|
44
|
+
return nil if data == NO_CHANGES
|
|
45
|
+
|
|
46
|
+
id = get_id(curr, exception: false)
|
|
47
|
+
id ? { id: id }.merge(data) : data
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @note it calls `as_update` for nested / cascaded attributes, which in turn
|
|
51
|
+
# will use this `DiffService`. Therefore, we aim for a first flat classic diff,
|
|
52
|
+
# onto `self`, and cascaded callbacks for the nested attributes.
|
|
53
|
+
# - This will translate into `key_path` being lost on each jump between
|
|
54
|
+
# `#as_update` and `DiffService#diff`.
|
|
55
|
+
# - The `result` object regards, therefore, to the **current level** alone.
|
|
56
|
+
# With the aim of building it up (accumulating through the call chain).
|
|
57
|
+
def diff_reduce(init, ignore: [])
|
|
58
|
+
subject.cascaded_reduce(init, recurs: false) do |result, obj, _key, key_path, _trace|
|
|
59
|
+
next result if key_path.empty?
|
|
60
|
+
next result if obj == subject
|
|
61
|
+
|
|
62
|
+
sym_path = key_path.map(&:to_sym)
|
|
63
|
+
|
|
64
|
+
# Remove any flat-diff placeholder for this key before deciding its fate.
|
|
65
|
+
dig_delete!(result, sym_path) if result && dig_path?(result, sym_path)
|
|
66
|
+
|
|
67
|
+
# Discard root-class objects — they are independent entities, not mutation payload.
|
|
68
|
+
next result if root?(obj)
|
|
69
|
+
# Only cascade-diff GraphQL model objects; ecoportal-api-v2 DoubleModel
|
|
70
|
+
# subclasses (ArrayModel, etc.) have a different as_update signature.
|
|
71
|
+
next result unless obj.is_a?(Ecoportal::API::Common::GraphQL::Model)
|
|
72
|
+
|
|
73
|
+
value = obj.as_update(ignore: ignore)
|
|
74
|
+
next result if value.nil?
|
|
75
|
+
|
|
76
|
+
result ||= {}
|
|
77
|
+
result[:id] ||= get_id(keys_to_sym_deep(curr_doc(flat: true) || {}), exception: false)
|
|
78
|
+
dig_set!(result, sym_path, value)
|
|
79
|
+
result
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# PROBLEM: trace can't be used with knowing if it's the root of the call!
|
|
84
|
+
# see `#cascaded_reduce` (when calling `_cascaded_attributes_trace`).
|
|
85
|
+
def diff_reduce_with_as_update_and_trace(init = {}, ignore: [], trace: {})
|
|
86
|
+
subject.cascaded_reduce(init, recurs: false, trace: trace) do |result, obj, _key, key_path, _trace|
|
|
87
|
+
next result if key_path.empty? # first iteration already done
|
|
88
|
+
next result if obj == subject # first call had done it
|
|
89
|
+
|
|
90
|
+
dig_delete!(result, key_path) if dig_path?(result, key_path)
|
|
91
|
+
|
|
92
|
+
# discard rooted (i.e. read_only) objects from the diff.
|
|
93
|
+
next result if root?(obj)
|
|
94
|
+
next result unless dig_path?(result, key_path)
|
|
95
|
+
next result unless obj.respond_to?(:as_update)
|
|
96
|
+
|
|
97
|
+
value = obj.as_update(ignore: ignore)
|
|
98
|
+
|
|
99
|
+
dig_set!(
|
|
100
|
+
result,
|
|
101
|
+
key_path,
|
|
102
|
+
value
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
result
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# FAILS to CALL #as_update on each object!!!
|
|
110
|
+
def diff_reduce_preserve_keys(init, flat: flat?, ignore: [])
|
|
111
|
+
subject.cascaded_reduce(init, recurs: !flat) do |result, obj, _key, key_path, _trace|
|
|
112
|
+
# discard rooted (i.e. read_only) objects from the diff.
|
|
113
|
+
if root?(obj)
|
|
114
|
+
dig_delete!(result, key_path)
|
|
115
|
+
else
|
|
116
|
+
value = classic_diff(
|
|
117
|
+
obj,
|
|
118
|
+
flat: true,
|
|
119
|
+
ignore: ignore
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
dig_set!(result, key_path, value)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
result
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def cascaded_diff(flat: flat?, ignore: [])
|
|
130
|
+
subject.cascaded_callback(
|
|
131
|
+
method: :as_update,
|
|
132
|
+
kargs: {
|
|
133
|
+
ignore: to_a(ignored, ignore),
|
|
134
|
+
flat: flat
|
|
135
|
+
},
|
|
136
|
+
recurs: !flat
|
|
137
|
+
) do |result, value, key_path, obj|
|
|
138
|
+
result.tap do
|
|
139
|
+
# on first call key_path is empty
|
|
140
|
+
next result if key_path.empty? # this condition isn't met, first call doesn't yield.
|
|
141
|
+
|
|
142
|
+
# discard rooted (i.e. read_only) objects from the diff.
|
|
143
|
+
if root?(obj)
|
|
144
|
+
dig_delete!(result, key_path)
|
|
145
|
+
else
|
|
146
|
+
dig_set!(result, key_path, value)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
|
|
154
|
+
attr_reader :ignored
|
|
155
|
+
|
|
156
|
+
def root?(obj)
|
|
157
|
+
# root? is a CLASS method (via Rootable::ClassMethods). The instance root?
|
|
158
|
+
# is protected and checks parent position, not the class declaration.
|
|
159
|
+
# Check the ancestor chain for any class that declared root!.
|
|
160
|
+
obj.class.ancestors.any? { |k| k.respond_to?(:root?) && k.root? }
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def curr_doc(target = subject, flat: flat?)
|
|
164
|
+
may_use_flat_diff(flat) { super(target) }
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def prev_doc(target = subject, flat: flat?)
|
|
168
|
+
may_use_flat_diff(flat) { super(target) }
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Remove nested attributes
|
|
172
|
+
def may_use_flat_diff(flat = flat?)
|
|
173
|
+
yield.then do |json|
|
|
174
|
+
next json unless flat
|
|
175
|
+
|
|
176
|
+
doc_with_non_cascaded_attributes(json)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Remove from `json` doc all the nested properties.
|
|
181
|
+
def doc_with_non_cascaded_attributes(json)
|
|
182
|
+
return json unless subject.class.respond_to?(:_cascaded_doc_keys)
|
|
183
|
+
return json if (excluded = subject.class._cascaded_doc_keys).empty?
|
|
184
|
+
|
|
185
|
+
except_keys(json, *excluded)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|