ecoportal-api-graphql 1.3.4 → 1.3.9
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/.ai-assistance/bridge/CLAUDE.md +338 -0
- data/.ai-assistance/bridge/archive/.gitkeep +0 -0
- data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.inbox.md +29 -0
- data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.outbox.md +18 -0
- data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.inbox.md +42 -0
- data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.outbox.md +115 -0
- data/.ai-assistance/bridge/context/gemini-review-prompt.txt +48 -0
- data/.ai-assistance/bridge/context/gemini-review-response.md +104 -0
- data/.ai-assistance/bridge/context/project.md +42 -0
- data/.ai-assistance/bridge/inbox/.gitkeep +0 -0
- data/.ai-assistance/bridge/outbox/.gitkeep +0 -0
- data/.ai-assistance/bridge/outbox/request-for-standards-discovery.md +48 -0
- data/.ai-assistance/bridge/queue/.gitkeep +1 -0
- data/.ai-assistance/capabilities/CLAUDE.md +27 -0
- data/.ai-assistance/capabilities/assumptions-log.md +80 -0
- data/.ai-assistance/capabilities/code.md +47 -0
- data/.ai-assistance/capabilities/connectors.md +37 -0
- data/.ai-assistance/capabilities/cowork.md +55 -0
- data/.ai-assistance/code/OVERVIEW.md +155 -0
- data/.ai-assistance/code/data_fields.md +242 -0
- data/.ai-assistance/code/dependencies.md +151 -0
- data/.ai-assistance/code/diff_as_input.md +234 -0
- data/.ai-assistance/code/diff_service_deep_dive.md +192 -0
- data/.ai-assistance/code/ecoPortal_architecture/00_overview_and_index.md +55 -0
- data/.ai-assistance/code/ecoPortal_architecture/01_terminology_dictionary.md +181 -0
- data/.ai-assistance/code/ecoPortal_architecture/02_data_model.md +192 -0
- data/.ai-assistance/code/ecoPortal_architecture/03_api_layers.md +147 -0
- data/.ai-assistance/code/ecoPortal_architecture/04_graphql_queries_mutations.md +277 -0
- data/.ai-assistance/code/ecoPortal_architecture/05_page_workflows.md +200 -0
- data/.ai-assistance/code/ecoPortal_architecture/06_search_and_filters.md +228 -0
- data/.ai-assistance/code/ecoPortal_architecture/07_data_fields.md +197 -0
- data/.ai-assistance/code/ecoPortal_architecture/08_stages_sections.md +243 -0
- data/.ai-assistance/code/ecoPortal_architecture/09_people_contractors_locations.md +196 -0
- data/.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md +132 -0
- data/.ai-assistance/code/ecoPortal_architecture/11_integration_gems.md +187 -0
- data/.ai-assistance/code/ecoPortal_architecture/12_ai_documentation_sources_gaps.md +236 -0
- data/.ai-assistance/code/ecoPortal_architecture/13_ai_infrastructure.md +183 -0
- data/.ai-assistance/code/ecoportal_schema_reference.md +240 -0
- data/.ai-assistance/code/graphql_domain_knowledge.md +230 -0
- data/.ai-assistance/code/refactoring/datafield-readwrite-shape-asymmetry.md +71 -0
- data/.ai-assistance/code/refactoring/opportunities.md +251 -0
- data/.ai-assistance/code/schema_analysis.md +321 -0
- data/.ai-assistance/code/search_filters.md +868 -0
- data/.ai-assistance/code/spec_coverage.md +73 -0
- data/.ai-assistance/code/workflow-command-guide.md +438 -0
- data/.ai-assistance/code/workflow-space.md +353 -0
- data/.ai-assistance/conventions/CLAUDE.md +30 -0
- data/.ai-assistance/conventions/code-working-tree-protocol.md +199 -0
- data/.ai-assistance/conventions/gitignore-rules.md +42 -0
- data/.ai-assistance/conventions/permission-guidance.md +120 -0
- data/.ai-assistance/integrations/README.md +70 -0
- data/.ai-assistance/integrations/gitkraken-mcp.md +107 -0
- data/.ai-assistance/integrations/gitlab-mcp.md +123 -0
- data/.ai-assistance/integrations/local-git.md +60 -0
- data/.ai-assistance/local_paths.example.md +17 -0
- data/.ai-assistance/projects/TODO.md +97 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/DECISIONS.md +168 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/INTENT.md +60 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/TODO.md +267 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/UPSTREAM.md +53 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/csv-template-pipeline-design.md +102 -0
- data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/cutover-usecase-gap-audit.md +139 -0
- data/.ai-assistance/projects/dynamic-model-generation/INTENT.md +93 -0
- data/.ai-assistance/projects/eco-helpers-compat/INTENT.md +244 -0
- data/.ai-assistance/projects/eco-helpers-compat/MIGRATION_GUIDE.md +266 -0
- data/.ai-assistance/projects/eco-helpers-compat/TODO.md +86 -0
- data/.ai-assistance/projects/ecoportal-api-v2-doublemodel-review/INTENT.md +101 -0
- data/.ai-assistance/projects/graphql-agent/GAP_ANALYSIS.md +177 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/DECISIONS.md +161 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/INTENT.md +125 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/RISKS.md +126 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/TODO.md +256 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-06-30-cutover-workflow-deep-review.md +122 -0
- data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-07-01-forces-via-workflow-commands-miss-rca.md +148 -0
- data/.ai-assistance/projects/page-model/DECISIONS.md +245 -0
- data/.ai-assistance/projects/page-model/TODO.md +190 -0
- data/.ai-assistance/projects/search-filter-builder/INTENT.md +107 -0
- data/.ai-assistance/projects/search-filter-builder/TODO.md +131 -0
- data/.ai-assistance/projects/template-maintenance/DESIGN.md +134 -0
- data/.ai-assistance/projects/workflow-space/TODO.md +213 -0
- data/.ai-assistance/reinstall-claude-desktop-windows.md +136 -0
- data/.ai-assistance/scripts/CLAUDE.md +150 -0
- data/.ai-assistance/scripts/bridge-init.sh +86 -0
- data/.ai-assistance/scripts/bridge-status.sh +44 -0
- data/.ai-assistance/scripts/capabilities-check.ts +104 -0
- data/.ai-assistance/scripts/check-outbox.sh +43 -0
- data/.ai-assistance/scripts/dep_graph.rb +91 -0
- data/.ai-assistance/scripts/lock-acquire.sh +103 -0
- data/.ai-assistance/scripts/lock-multi.sh +124 -0
- data/.ai-assistance/scripts/lock-queue.sh +94 -0
- data/.ai-assistance/scripts/setup-mcps.test.ts +188 -0
- data/.ai-assistance/scripts/setup-mcps.ts +234 -0
- data/.ai-assistance/scripts/task-complete.ts +74 -0
- data/.ai-assistance/scripts/task-create.ts +75 -0
- data/.ai-assistance/scripts/task-read.ts +125 -0
- data/.ai-assistance/scripts/token-logger.js +220 -0
- data/.ai-assistance/scripts/token-report.ts +158 -0
- data/.ai-assistance/scripts/token-session-start.js +66 -0
- data/.ai-assistance/skills/ai-instructions/SKILL.md +48 -0
- data/.ai-assistance/skills/code-specs/SKILL.md +69 -0
- data/.ai-assistance/skills/corporate-policies/SKILL.md +201 -0
- data/.ai-assistance/skills/dep-graph/SKILL.md +139 -0
- data/.ai-assistance/skills/ep-ai-manager/SKILL.md +417 -0
- data/.ai-assistance/skills/gemini-assist/SKILL.md +63 -0
- data/.ai-assistance/skills/gemini-assist/gemini-mcp-server.js +205 -0
- data/.ai-assistance/skills/gemini-assist/gemini_ask.py +1 -0
- data/.ai-assistance/skills/gemini-assist/gemini_ask.rb +240 -0
- data/.ai-assistance/skills/gemini-assist/prompts/cycle_end_review.txt +25 -0
- data/.ai-assistance/skills/graphql-schema-analysis/SKILL.md +261 -0
- data/.ai-assistance/skills/project-cycle/SKILL.md +177 -0
- data/.ai-assistance/skills/refactor/SKILL.md +62 -0
- data/.ai-assistance/skills/rubocop/SKILL.md +93 -0
- data/.ai-assistance/skills/ruby-scripting/SKILL.md +215 -0
- data/.ai-assistance/skills/spec-generation/SKILL.md +72 -0
- data/.ai-assistance/standards-version.json +21 -0
- data/.ai-assistance/token-budget.json +32 -0
- data/.ai-assistance/version.json +39 -0
- data/.claude/settings.json +146 -0
- data/.env.example +18 -0
- data/.gitattributes +15 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +121 -97
- data/CHANGELOG.md +673 -470
- data/CLAUDE.md +232 -0
- data/Gemfile +30 -6
- data/Rakefile +90 -38
- data/docs/worklog.md +574 -0
- data/ecoportal-api-graphql.gemspec +40 -40
- data/lib/ecoportal/api/common/graphql/CLAUDE.md +36 -0
- data/lib/ecoportal/api/common/graphql/auth_service.rb +12 -14
- data/lib/ecoportal/api/common/graphql/client.rb +11 -3
- data/lib/ecoportal/api/common/graphql/http_client.rb +117 -29
- data/lib/ecoportal/api/common/graphql/model/CLAUDE.md +28 -0
- data/lib/ecoportal/api/common/graphql/model/as_input.rb +8 -5
- data/lib/ecoportal/api/common/graphql/model/diffable/classic_diff_service.rb +3 -1
- data/lib/ecoportal/api/common/graphql/model/diffable/diff_service.rb +31 -23
- data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff_nesting.rb +54 -1
- data/lib/ecoportal/api/common/graphql.rb +1 -1
- 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/ai_summary_version.rb +17 -0
- data/lib/ecoportal/api/graphql/base/delta_result.rb +16 -0
- data/lib/ecoportal/api/graphql/base/force/binding.rb +19 -0
- data/lib/ecoportal/api/graphql/base/force/binding_collection.rb +62 -0
- data/lib/ecoportal/api/graphql/base/force/collection.rb +47 -0
- data/lib/ecoportal/api/graphql/base/force.rb +65 -0
- data/lib/ecoportal/api/graphql/base/kickstand/job.rb +17 -0
- data/lib/ecoportal/api/graphql/base/kickstand/workflow.rb +18 -0
- data/lib/ecoportal/api/graphql/base/kickstand.rb +13 -0
- data/lib/ecoportal/api/graphql/base/page/basic.rb +38 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/actions_list.rb +9 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/ai_summary.rb +18 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/checklist.rb +29 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +112 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +28 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/cross_reference.rb +54 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/date_field.rb +23 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +25 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/gauge.rb +19 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/geo.rb +24 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +24 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/law.rb +8 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/mailbox.rb +9 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/number.rb +20 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/people.rb +35 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/plain_text.rb +17 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/rich_text.rb +26 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/select.rb +41 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/signature.rb +9 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/smart_fill.rb +17 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/table.rb +9 -0
- data/lib/ecoportal/api/graphql/base/page/data_field/tag_field.rb +21 -0
- data/lib/ecoportal/api/graphql/base/page/data_field.rb +137 -0
- data/lib/ecoportal/api/graphql/base/page/phased/stage.rb +68 -0
- data/lib/ecoportal/api/graphql/base/page/phased.rb +15 -0
- data/lib/ecoportal/api/graphql/base/page/section.rb +48 -0
- data/lib/ecoportal/api/graphql/base/page/section_collection.rb +79 -0
- data/lib/ecoportal/api/graphql/base/page.rb +7 -1
- data/lib/ecoportal/api/graphql/base/pages_workflow/action_type_selection.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/callback_type.rb +28 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/command_change.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/command_change_message.rb +15 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/command_es_change.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/command_interface.rb +36 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/email_config.rb +18 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/escalation_level.rb +19 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/in_system_config.rb +16 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/mailbox_field_selection.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/operation_interface.rb +39 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/operations/assign_to.rb +27 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/operations/create_page.rb +21 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/operations/send_notification.rb +30 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/people_field_selection.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/recipient_config.rb +34 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/register_field.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/task_config_selection.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/time_delay_config.rb +16 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/trigger_interface.rb +26 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/triggers/conditional_logic.rb +17 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow/user_selection.rb +16 -0
- data/lib/ecoportal/api/graphql/base/pages_workflow.rb +35 -0
- data/lib/ecoportal/api/graphql/base/preset_view.rb +17 -0
- data/lib/ecoportal/api/graphql/base/preview_page.rb +23 -0
- data/lib/ecoportal/api/graphql/base/register.rb +18 -0
- data/lib/ecoportal/api/graphql/base.rb +26 -15
- data/lib/ecoportal/api/graphql/builder/CLAUDE.md +65 -0
- data/lib/ecoportal/api/graphql/builder/kickstand.rb +73 -0
- data/lib/ecoportal/api/graphql/builder/page.rb +210 -0
- data/lib/ecoportal/api/graphql/builder/register/preset_view.rb +84 -0
- data/lib/ecoportal/api/graphql/builder/register.rb +49 -0
- data/lib/ecoportal/api/graphql/builder/template.rb +80 -0
- data/lib/ecoportal/api/graphql/builder.rb +7 -3
- data/lib/ecoportal/api/graphql/compat/filter_translator.rb +107 -0
- data/lib/ecoportal/api/graphql/compat/page_reference.rb +23 -0
- data/lib/ecoportal/api/graphql/compat/pages.rb +212 -0
- data/lib/ecoportal/api/graphql/compat/registers.rb +84 -0
- data/lib/ecoportal/api/graphql/compat/response.rb +35 -0
- data/lib/ecoportal/api/graphql/compat/search_results.rb +33 -0
- data/lib/ecoportal/api/graphql/compat/stage_collection.rb +70 -0
- data/lib/ecoportal/api/graphql/compat/stage_view.rb +76 -0
- data/lib/ecoportal/api/graphql/compat.rb +17 -0
- data/lib/ecoportal/api/graphql/concerns/data_field_access.rb +71 -0
- data/lib/ecoportal/api/graphql/concerns/deprecation.rb +20 -0
- data/lib/ecoportal/api/graphql/concerns/fragment_definitions.rb +68 -0
- data/lib/ecoportal/api/graphql/concerns/page_compat.rb +51 -0
- data/lib/ecoportal/api/graphql/concerns/snake_camel_access.rb +60 -0
- data/lib/ecoportal/api/graphql/concerns.rb +14 -0
- data/lib/ecoportal/api/graphql/connection/page.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/pages_workflow_command.rb +13 -0
- data/lib/ecoportal/api/graphql/connection/preset_view.rb +11 -0
- data/lib/ecoportal/api/graphql/connection/preview_page.rb +11 -0
- data/lib/ecoportal/api/graphql/connection.rb +8 -4
- data/lib/ecoportal/api/graphql/error.rb +3 -3
- data/lib/ecoportal/api/graphql/file_upload/client.rb +181 -0
- data/lib/ecoportal/api/graphql/file_upload.rb +10 -0
- data/lib/ecoportal/api/graphql/fragment/action.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/action_category.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/contractor_entity.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/force.rb +30 -0
- data/lib/ecoportal/api/graphql/fragment/location_draft.rb +2 -2
- data/lib/ecoportal/api/graphql/fragment/location_node.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/locations_error.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/page.rb +85 -0
- data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +395 -0
- data/lib/ecoportal/api/graphql/fragment/pages.rb +15 -0
- data/lib/ecoportal/api/graphql/fragment/pages_workflow.rb +172 -0
- data/lib/ecoportal/api/graphql/fragment/pagination.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment.rb +37 -71
- data/lib/ecoportal/api/graphql/helpers/locations_tree.rb +1 -0
- data/lib/ecoportal/api/graphql/helpers.rb +1 -1
- data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +25 -0
- data/lib/ecoportal/api/graphql/input/delta_input.rb +16 -0
- data/lib/ecoportal/api/graphql/input/page/archive.rb +14 -0
- data/lib/ecoportal/api/graphql/input/page/build_from_template.rb +13 -0
- data/lib/ecoportal/api/graphql/input/page/create_draft.rb +13 -0
- data/lib/ecoportal/api/graphql/input/page/create_from_template.rb +18 -0
- data/lib/ecoportal/api/graphql/input/page/delete_draft.rb +13 -0
- data/lib/ecoportal/api/graphql/input/page/publish_draft.rb +13 -0
- data/lib/ecoportal/api/graphql/input/page/review_task.rb +14 -0
- data/lib/ecoportal/api/graphql/input/page/unarchive.rb +14 -0
- data/lib/ecoportal/api/graphql/input/page/update.rb +140 -0
- data/lib/ecoportal/api/graphql/input/page.rb +26 -0
- data/lib/ecoportal/api/graphql/input/preset_view/create.rb +18 -0
- data/lib/ecoportal/api/graphql/input/preset_view/permission.rb +16 -0
- data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -0
- data/lib/ecoportal/api/graphql/input/preset_view.rb +14 -0
- data/lib/ecoportal/api/graphql/input/register/create.rb +18 -0
- data/lib/ecoportal/api/graphql/input/register/update.rb +15 -0
- data/lib/ecoportal/api/graphql/input/register.rb +13 -0
- data/lib/ecoportal/api/graphql/input/search_conf/ai_generator.rb +234 -0
- data/lib/ecoportal/api/graphql/input/search_conf.rb +367 -0
- data/lib/ecoportal/api/graphql/input/variable_binding.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_action_tag.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_binding.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_comment_tagging_user_group.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_default_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_default_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_force.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_gauge_field_stop.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_field_config.rb +23 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_helper.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_action_type.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_filter.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_people_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_task_config.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback.rb +23 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback_action.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_tag.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_task.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_task_assignment_user_group.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/add_workflow_callback.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/collapse_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_binding.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_creator_permissions.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_default_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +21 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_gauge_field_stop.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_field_config.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_helper.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +28 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_page_creator_permissions.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_reminder.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_required_sign_offs.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_comment_tagging.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_task_assignment.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_scheduled_callback.rb +22 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_section_header.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +19 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_stage.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_task_due.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_trigger.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/expand_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/contractor_entities.rb +24 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +23 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/gauge.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/location_field.rb +24 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +24 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/signature.rb +20 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb +25 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_binding.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_callback.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_comment_tagging_user_group.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_force.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_gauge_field_stop.rb +17 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_field_config.rb +17 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_helper.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_direct_strategy_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_action_type.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_filter.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_people_field.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_task_config.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_user.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_scheduled_callback.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_select_field_option.rb +17 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_tag.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_strategy.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_assignment_user_group.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_due.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_priority_level.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +18 -0
- data/lib/ecoportal/api/graphql/input/workflow_command.rb +251 -0
- data/lib/ecoportal/api/graphql/input.rb +15 -7
- data/lib/ecoportal/api/graphql/interface/base_page.rb +100 -58
- data/lib/ecoportal/api/graphql/interface/location_structure/nodes.rb +27 -28
- data/lib/ecoportal/api/graphql/logic/base_model.rb +2 -0
- data/lib/ecoportal/api/graphql/logic/base_query.rb +45 -2
- data/lib/ecoportal/api/graphql/logic/input.rb +15 -0
- data/lib/ecoportal/api/graphql/logic/mutation.rb +6 -1
- data/lib/ecoportal/api/graphql/logic/query_array.rb +1 -0
- data/lib/ecoportal/api/graphql/logic/query_connection.rb +2 -0
- data/lib/ecoportal/api/graphql/logic.rb +9 -9
- data/lib/ecoportal/api/graphql/model/ai_summary_version.rb +10 -0
- data/lib/ecoportal/api/graphql/model/organization.rb +65 -52
- data/lib/ecoportal/api/graphql/model/page/basic.rb +14 -0
- data/lib/ecoportal/api/graphql/model/page/data_field.rb +12 -0
- data/lib/ecoportal/api/graphql/model/page/phased/stage.rb +14 -0
- data/lib/ecoportal/api/graphql/model/page/phased.rb +82 -0
- data/lib/ecoportal/api/graphql/model/page/section.rb +12 -0
- data/lib/ecoportal/api/graphql/model/page.rb +6 -7
- data/lib/ecoportal/api/graphql/model/page_union.rb +21 -0
- data/lib/ecoportal/api/graphql/model/pages_workflow.rb +20 -0
- data/lib/ecoportal/api/graphql/model/preset_view.rb +10 -0
- data/lib/ecoportal/api/graphql/model/preview_page.rb +10 -0
- data/lib/ecoportal/api/graphql/model/register.rb +10 -0
- data/lib/ecoportal/api/graphql/model/resource.rb +1 -1
- data/lib/ecoportal/api/graphql/model.rb +21 -13
- data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +45 -0
- data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/ai_summary.rb +13 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_jobs.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_workflows.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/fail_job.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/fail_workflow.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/start_job.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/start_workflow.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand/stop_workflow.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/kickstand.rb +18 -0
- data/lib/ecoportal/api/graphql/mutation/location_structure/apply_commands.rb +3 -3
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/add_commands.rb +2 -2
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/create.rb +2 -2
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/drop_bad_commands.rb +3 -3
- data/lib/ecoportal/api/graphql/mutation/location_structure/draft/publish.rb +3 -3
- data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/archive.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/build_from_template.rb +50 -0
- data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/create_from_template.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/execute_force_commands.rb +69 -0
- data/lib/ecoportal/api/graphql/mutation/page/execute_workflow_commands.rb +51 -0
- data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/unarchive.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/update.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/page/update_variable_bindings.rb +44 -0
- data/lib/ecoportal/api/graphql/mutation/page.rb +28 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view/create.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view/permission.rb +37 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view/update.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/preset_view.rb +15 -0
- data/lib/ecoportal/api/graphql/mutation/register/create.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/register/update.rb +35 -0
- data/lib/ecoportal/api/graphql/mutation/register.rb +14 -0
- data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +36 -0
- data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +40 -0
- data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +13 -0
- data/lib/ecoportal/api/graphql/mutation/template/create.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/template/create_related_page.rb +46 -0
- data/lib/ecoportal/api/graphql/mutation/template/destroy_related_page.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/template/publish.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/template/unpublish.rb +39 -0
- data/lib/ecoportal/api/graphql/mutation/template/update.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/template/update_information.rb +43 -0
- data/lib/ecoportal/api/graphql/mutation/template.rb +18 -0
- data/lib/ecoportal/api/graphql/mutation.rb +11 -3
- data/lib/ecoportal/api/graphql/payload/ai_summary_generate.rb +12 -0
- data/lib/ecoportal/api/graphql/payload/execute_workflow_commands.rb +36 -0
- data/lib/ecoportal/api/graphql/payload/force_commands.rb +31 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_jobs.rb +36 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_workflows.rb +36 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/job.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/kickstand/workflow.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/kickstand.rb +15 -0
- data/lib/ecoportal/api/graphql/payload/location_structure/draft/create.rb +33 -34
- data/lib/ecoportal/api/graphql/payload/ok_payload.rb +21 -0
- data/lib/ecoportal/api/graphql/payload/page/archive.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/build_from_template.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/create_from_template.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/draft.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/review_task.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/unarchive.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/update.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page/update_variable_bindings.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/page.rb +19 -0
- data/lib/ecoportal/api/graphql/payload/preset_view.rb +11 -0
- data/lib/ecoportal/api/graphql/payload/register.rb +11 -0
- data/lib/ecoportal/api/graphql/payload/template/create.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/create_related_page.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/destroy_related_page.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/publish.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/unpublish.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/update.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template/update_information.rb +13 -0
- data/lib/ecoportal/api/graphql/payload/template.rb +18 -0
- data/lib/ecoportal/api/graphql/payload.rb +14 -3
- data/lib/ecoportal/api/graphql/query/action.rb +1 -1
- data/lib/ecoportal/api/graphql/query/action_categories.rb +2 -1
- data/lib/ecoportal/api/graphql/query/actions.rb +2 -2
- data/lib/ecoportal/api/graphql/query/contractor_entities.rb +2 -1
- data/lib/ecoportal/api/graphql/query/file_upload_signature.rb +76 -0
- data/lib/ecoportal/api/graphql/query/location_structure/draft.rb +2 -2
- data/lib/ecoportal/api/graphql/query/location_structure.rb +1 -1
- data/lib/ecoportal/api/graphql/query/location_structures.rb +1 -1
- data/lib/ecoportal/api/graphql/query/page.rb +45 -0
- data/lib/ecoportal/api/graphql/query/page_delta.rb +47 -0
- data/lib/ecoportal/api/graphql/query/page_with_forces.rb +43 -0
- data/lib/ecoportal/api/graphql/query/pages.rb +59 -0
- data/lib/ecoportal/api/graphql/query/pages_workflow_commands.rb +59 -0
- data/lib/ecoportal/api/graphql/query/register_preset_views.rb +78 -0
- data/lib/ecoportal/api/graphql/query/register_preview_pages.rb +83 -0
- data/lib/ecoportal/api/graphql/query/templates.rb +53 -0
- data/lib/ecoportal/api/graphql/query.rb +18 -7
- data/lib/ecoportal/api/graphql.rb +70 -2
- data/lib/ecoportal/api/graphql_version.rb +5 -5
- data/scripts/auto-worker-scheduler.sh +386 -0
- data/tests/contractor_entity_create.rb +19 -19
- data/tests/contractor_entity_udpate.rb +20 -20
- data/tests/dump_page_model.rb +74 -0
- data/tests/loc_structure_get.rb +1 -2
- data/tests/loc_structure_update.rb +51 -51
- data/tests/loc_structures_get.rb +15 -15
- data/tests/local_libs.rb +7 -7
- metadata +450 -11
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
# rubocop:disable Gemspec/DevelopmentDependencies
|
|
2
|
-
lib = File.expand_path('lib', __dir__)
|
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require 'ecoportal/api/graphql_version'
|
|
5
|
-
|
|
6
|
-
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name = 'ecoportal-api-graphql'
|
|
8
|
-
spec.version = Ecoportal::API::GRAPQL_VERSION
|
|
9
|
-
spec.authors = ['Oscar Segura']
|
|
10
|
-
spec.email = ['oscar@ecoportal.co.nz']
|
|
11
|
-
|
|
12
|
-
spec.summary = 'A collection of helpers for interacting with the ecoPortal GraphQL API'
|
|
13
|
-
spec.homepage = 'https://www.ecoportal.com'
|
|
14
|
-
spec.licenses = %w[MIT]
|
|
15
|
-
|
|
16
|
-
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
17
|
-
|
|
18
|
-
spec.required_ruby_version = '>= 3.2.2'
|
|
19
|
-
|
|
20
|
-
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
21
|
-
f.match(
|
|
22
|
-
end
|
|
23
|
-
spec.bindir = 'exe'
|
|
24
|
-
spec.executables = spec.files.grep(
|
|
25
|
-
spec.require_paths = ['lib']
|
|
26
|
-
|
|
27
|
-
spec.add_development_dependency 'pry', '>= 0.14'
|
|
28
|
-
spec.add_development_dependency 'rake', '>= 13.0.3', '< 14'
|
|
29
|
-
spec.add_development_dependency 'redcarpet', '>= 3.6.0', '< 4'
|
|
30
|
-
spec.add_development_dependency 'rspec', '>= 3.12.0', '< 4'
|
|
31
|
-
spec.add_development_dependency 'rubocop', '~> 1'
|
|
32
|
-
spec.add_development_dependency 'rubocop-rake', '~> 0'
|
|
33
|
-
spec.add_development_dependency 'yard', '>= 0.9.34', '< 1'
|
|
34
|
-
|
|
35
|
-
spec.add_dependency 'ecoportal-api', '~> 0.10', '>= 0.10.
|
|
36
|
-
spec.add_dependency 'ecoportal-api-v2', '~> 3.3', '>= 3.3.
|
|
37
|
-
spec.add_dependency 'graphlient', '>= 0.8.0', '< 0.9'
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# rubocop:enable Gemspec/DevelopmentDependencies
|
|
1
|
+
# rubocop:disable Gemspec/DevelopmentDependencies
|
|
2
|
+
lib = File.expand_path('lib', __dir__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'ecoportal/api/graphql_version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = 'ecoportal-api-graphql'
|
|
8
|
+
spec.version = Ecoportal::API::GRAPQL_VERSION
|
|
9
|
+
spec.authors = ['Oscar Segura']
|
|
10
|
+
spec.email = ['oscar@ecoportal.co.nz']
|
|
11
|
+
|
|
12
|
+
spec.summary = 'A collection of helpers for interacting with the ecoPortal GraphQL API'
|
|
13
|
+
spec.homepage = 'https://www.ecoportal.com'
|
|
14
|
+
spec.licenses = %w[MIT]
|
|
15
|
+
|
|
16
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
17
|
+
|
|
18
|
+
spec.required_ruby_version = '>= 3.2.2'
|
|
19
|
+
|
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
21
|
+
f.match(/^(test|spec|features)\//)
|
|
22
|
+
end
|
|
23
|
+
spec.bindir = 'exe'
|
|
24
|
+
spec.executables = spec.files.grep(/^exe\//) { |f| File.basename(f) }
|
|
25
|
+
spec.require_paths = ['lib']
|
|
26
|
+
|
|
27
|
+
spec.add_development_dependency 'pry', '>= 0.14'
|
|
28
|
+
spec.add_development_dependency 'rake', '>= 13.0.3', '< 14'
|
|
29
|
+
spec.add_development_dependency 'redcarpet', '>= 3.6.0', '< 4'
|
|
30
|
+
spec.add_development_dependency 'rspec', '>= 3.12.0', '< 4'
|
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 1'
|
|
32
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0'
|
|
33
|
+
spec.add_development_dependency 'yard', '>= 0.9.34', '< 1'
|
|
34
|
+
|
|
35
|
+
spec.add_dependency 'ecoportal-api', '~> 0.10', '>= 0.10.16'
|
|
36
|
+
spec.add_dependency 'ecoportal-api-v2', '~> 3.3', '>= 3.3.2'
|
|
37
|
+
spec.add_dependency 'graphlient', '>= 0.8.0', '< 0.9'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# rubocop:enable Gemspec/DevelopmentDependencies
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# common/graphql
|
|
2
|
+
|
|
3
|
+
Shared HTTP transport, authentication, and base model infrastructure used by the gem — nothing here is EcoPortal-domain-specific.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
| File / class | Purpose |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `auth_service.rb` / `AuthService` | OAuth2 password + refresh-token flow; included in both client classes |
|
|
10
|
+
| `client.rb` / `Client` | Graphlient-based GraphQL client (builds bearer-token headers, constructs endpoint URL) |
|
|
11
|
+
| `http_client.rb` / `HttpClient` | Raw HTTP client (extends `Common::Client`); `execute` sends query strings + variables; supports v0–v3 + graphql API version modes |
|
|
12
|
+
| `class_helpers.rb` / `ClassHelpers` | `becomes(klass)` instance casting + `const?` class helper |
|
|
13
|
+
| `hash_helpers.rb` / `HashHelpers` | Deep key transforms (`keys_to_sym_deep`, `deep_dup`, `remove_nil_keys_deep`) — used by diff and input serialisation |
|
|
14
|
+
| `query_integration.rb` / `QueryIntegration` | Class macro `query(:method, query_klass:)` that wires a named query method on `Model::Organization` |
|
|
15
|
+
| `model.rb` / `Model` | Base model class: `DoubleModel` + `Diffable` + `AsInput`; all GraphQL models ultimately inherit this |
|
|
16
|
+
| `patches.rb` | Reserved placeholder (empty) |
|
|
17
|
+
| `model/diffable.rb` | `as_update` / `dirty?` — delegates to `DiffService` |
|
|
18
|
+
| `model/as_input.rb` | `as_input` (instance) and `as_input(hash)` (class method) — converts diff to GraphQL mutation variables |
|
|
19
|
+
| `model/diffable/diff_service.rb` | Main diff engine: flat classic diff + cascaded reduce through nested `GraphQL::Model` objects |
|
|
20
|
+
| `model/diffable/classic_diff_service.rb` | Low-level change-data extraction (compares `curr_doc` vs `prev_doc`) |
|
|
21
|
+
| `model/diffable/hash_diff.rb` | Hash equality / change detection helpers |
|
|
22
|
+
| `model/diffable/hash_diff_nesting.rb` | Nested key path helpers (`dig_set!`, `dig_delete!`, `dig_path?`) |
|
|
23
|
+
|
|
24
|
+
## Conventions
|
|
25
|
+
|
|
26
|
+
- `Client` is graphlient-based and used for schema introspection; `HttpClient` is the actual request sender used in production (set as `client.http_client`).
|
|
27
|
+
- `HashHelpers` is used as both a module mixin (include) and directly via `HashHelpers.keys_to_sym_deep(...)`.
|
|
28
|
+
- `DiffService` handles the `flat:` flag: `flat: true` does a single-level diff; `flat: false` (default) cascades through nested `GraphQL::Model` objects.
|
|
29
|
+
- Root-class objects (`root!` declared) are excluded from cascaded diffs — they represent independent server entities.
|
|
30
|
+
- `AsInput#as_input(target_class:)` delegates to `Input::X.from_model(self)` when a target class is given.
|
|
31
|
+
|
|
32
|
+
## Related
|
|
33
|
+
|
|
34
|
+
- `../graphql/logic/base_model.rb` — adds `SnakeCamelAccess` on top of `Common::GraphQL::Model`
|
|
35
|
+
- `../graphql/logic/input.rb` — `Logic::Input` base class built on top of `Model`
|
|
36
|
+
- `../graphql/logic/base_query.rb` — consumes `HttpClient#execute` and `HashHelpers`
|
|
@@ -7,14 +7,13 @@ module Ecoportal
|
|
|
7
7
|
TOKEN_AUTORENEW = 90 # minutes
|
|
8
8
|
|
|
9
9
|
module InstanceMethods
|
|
10
|
-
def session_token(host: server,
|
|
11
|
-
session_token_data(host: host
|
|
10
|
+
def session_token(host: server, auto_renew: true)
|
|
11
|
+
session_token_data(host: host).then do |body|
|
|
12
12
|
next unless body
|
|
13
13
|
|
|
14
14
|
if auto_renew && token_renew?(body['expires_in'])
|
|
15
15
|
session_token_renewed(
|
|
16
16
|
host: host,
|
|
17
|
-
version: version,
|
|
18
17
|
refresh_token: body['refresh_token']
|
|
19
18
|
)
|
|
20
19
|
else
|
|
@@ -23,15 +22,14 @@ module Ecoportal
|
|
|
23
22
|
end
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
def session_token_renewed(host: server,
|
|
25
|
+
def session_token_renewed(host: server, refresh_token: nil)
|
|
27
26
|
unless refresh_token
|
|
28
|
-
return unless (body = session_token_data(host: host
|
|
27
|
+
return unless (body = session_token_data(host: host))
|
|
29
28
|
return unless (refresh_token = body['resfresh_token'])
|
|
30
29
|
end
|
|
31
30
|
|
|
32
31
|
session_refresh_token_data(
|
|
33
32
|
host: host,
|
|
34
|
-
version: version,
|
|
35
33
|
refresh_token: refresh_token
|
|
36
34
|
).then do |bdy|
|
|
37
35
|
bdy['access_token'] if bdy
|
|
@@ -40,8 +38,8 @@ module Ecoportal
|
|
|
40
38
|
|
|
41
39
|
private
|
|
42
40
|
|
|
43
|
-
def session_token_data(host: server
|
|
44
|
-
|
|
41
|
+
def session_token_data(host: server)
|
|
42
|
+
auth_http_client(host: host).post(
|
|
45
43
|
'/oauth/token',
|
|
46
44
|
data: {
|
|
47
45
|
'grant_type' => 'password',
|
|
@@ -53,8 +51,8 @@ module Ecoportal
|
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
53
|
|
|
56
|
-
def session_refresh_token_data(refresh_token:, host: server
|
|
57
|
-
|
|
54
|
+
def session_refresh_token_data(refresh_token:, host: server)
|
|
55
|
+
auth_http_client(host: host).post(
|
|
58
56
|
'/oauth/token',
|
|
59
57
|
data: {
|
|
60
58
|
'grant_type' => 'refresh_token',
|
|
@@ -69,10 +67,10 @@ module Ecoportal
|
|
|
69
67
|
(TOKEN_AUTORENEW * 60) > seconds
|
|
70
68
|
end
|
|
71
69
|
|
|
72
|
-
def
|
|
73
|
-
@
|
|
70
|
+
def auth_http_client(host: server)
|
|
71
|
+
@auth_http_client ||= Ecoportal::API::Common::GraphQL::HttpClient.new(
|
|
74
72
|
host: host,
|
|
75
|
-
version:
|
|
73
|
+
version: 'http'
|
|
76
74
|
)
|
|
77
75
|
end
|
|
78
76
|
|
|
@@ -89,7 +87,7 @@ module Ecoportal
|
|
|
89
87
|
end
|
|
90
88
|
|
|
91
89
|
def fetch_env_required(name)
|
|
92
|
-
|
|
90
|
+
raise "Missing ENV '#{name}'" unless ENV.key?(name)
|
|
93
91
|
ENV[name]
|
|
94
92
|
end
|
|
95
93
|
|
|
@@ -4,7 +4,9 @@ module Ecoportal
|
|
|
4
4
|
module Common
|
|
5
5
|
module GraphQL
|
|
6
6
|
class Client < ::Graphlient::Client
|
|
7
|
-
|
|
7
|
+
ENDPOINT_PATH = 'external/graphql'.freeze
|
|
8
|
+
|
|
9
|
+
attr_accessor :host, :http_client
|
|
8
10
|
|
|
9
11
|
READ_TIMEOUT = 90
|
|
10
12
|
WRITE_TIMEOUT = 90
|
|
@@ -42,7 +44,12 @@ module Ecoportal
|
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
def new(org_id: self.org_id, host: self.host, schema_path: host, no_schema: @no_schema)
|
|
45
|
-
self.class.new(
|
|
47
|
+
self.class.new(
|
|
48
|
+
org_id: org_id,
|
|
49
|
+
host: host,
|
|
50
|
+
schema_path: schema_path,
|
|
51
|
+
no_schema: no_schema
|
|
52
|
+
)
|
|
46
53
|
end
|
|
47
54
|
|
|
48
55
|
def org_id
|
|
@@ -52,7 +59,8 @@ module Ecoportal
|
|
|
52
59
|
private
|
|
53
60
|
|
|
54
61
|
def url
|
|
55
|
-
|
|
62
|
+
base_url = Ecoportal::API::Common::GraphQL::HttpClient.base_url(host)
|
|
63
|
+
"#{base_url}/api/#{org_id}/#{ENDPOINT_PATH}"
|
|
56
64
|
end
|
|
57
65
|
end
|
|
58
66
|
end
|
|
@@ -2,6 +2,8 @@ module Ecoportal
|
|
|
2
2
|
module API
|
|
3
3
|
module Common
|
|
4
4
|
module GraphQL
|
|
5
|
+
class ResponseError < StandardError; end
|
|
6
|
+
|
|
5
7
|
class HttpClient < Common::Client
|
|
6
8
|
class << self
|
|
7
9
|
def base_url(host)
|
|
@@ -13,20 +15,37 @@ module Ecoportal
|
|
|
13
15
|
end
|
|
14
16
|
end
|
|
15
17
|
|
|
18
|
+
ENDPOINT_PATH = 'external/graphql'.freeze
|
|
19
|
+
READ_TIMEOUT = 90
|
|
20
|
+
WRITE_TIMEOUT = 90
|
|
21
|
+
|
|
16
22
|
attr_reader :host, :version
|
|
17
23
|
|
|
24
|
+
include Ecoportal::API::Common::GraphQL::AuthService
|
|
25
|
+
|
|
18
26
|
def initialize(
|
|
27
|
+
email: nil,
|
|
28
|
+
pass: nil,
|
|
29
|
+
org_id: nil,
|
|
19
30
|
api_key: nil,
|
|
20
|
-
version:
|
|
31
|
+
version: 'graphql',
|
|
21
32
|
host: 'live.ecoportal.com',
|
|
22
33
|
logger: ::Logger.new(IO::NULL),
|
|
23
|
-
deep_logging: false
|
|
34
|
+
deep_logging: false,
|
|
35
|
+
no_schema: true
|
|
24
36
|
)
|
|
25
|
-
|
|
26
|
-
|
|
37
|
+
@org_id = org_id
|
|
38
|
+
@user_email = email
|
|
39
|
+
@user_pass = pass
|
|
40
|
+
@no_schema = no_schema
|
|
41
|
+
@version = version
|
|
27
42
|
|
|
28
|
-
|
|
29
|
-
|
|
43
|
+
super(
|
|
44
|
+
api_key: api_key,
|
|
45
|
+
host: host,
|
|
46
|
+
logger: logger,
|
|
47
|
+
deep_logging: deep_logging
|
|
48
|
+
)
|
|
30
49
|
end
|
|
31
50
|
|
|
32
51
|
# Creates a HTTP object adding the `X-ApiKey` or `X-ECOPORTAL-API-KEY` param to the header, depending on the API version.
|
|
@@ -35,52 +54,121 @@ module Ecoportal
|
|
|
35
54
|
def base_request
|
|
36
55
|
@base_request ||=
|
|
37
56
|
case @version
|
|
38
|
-
when NilClass
|
|
39
|
-
HTTP
|
|
40
|
-
when '
|
|
41
|
-
HTTP.headers('X-
|
|
57
|
+
when NilClass, 'http'
|
|
58
|
+
HTTP
|
|
59
|
+
when 'v1', 'v0'
|
|
60
|
+
HTTP.headers('X-ApiKey' => key_token)
|
|
61
|
+
when 'v2', 'v3'
|
|
62
|
+
HTTP.headers('X-ECOPORTAL-API-KEY' => key_token)
|
|
42
63
|
when 'graphql'
|
|
43
|
-
HTTP.headers('Authorization' => "Bearer #{
|
|
44
|
-
|
|
45
|
-
|
|
64
|
+
HTTP.headers('Authorization' => "Bearer #{session_token(host: host)}")
|
|
65
|
+
end.then do |request|
|
|
66
|
+
request ||= HTTP
|
|
67
|
+
request.accept(:json).timeout(
|
|
68
|
+
read: READ_TIMEOUT,
|
|
69
|
+
write: WRITE_TIMEOUT
|
|
70
|
+
)
|
|
46
71
|
end
|
|
47
72
|
end
|
|
48
73
|
|
|
74
|
+
def org_id
|
|
75
|
+
@org_id || fetch_env_required('ORGANIZATION_ID')
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Executes a GraphQL query or mutation over HTTP.
|
|
79
|
+
# @param query_string [String] full GraphQL query document.
|
|
80
|
+
# @param variables [Hash] variable values to pass to the operation.
|
|
81
|
+
# @param operation_name [String, nil] when the document has multiple operations.
|
|
82
|
+
# @return [Hash] parsed response body (string-keyed, includes 'data' and optionally 'errors').
|
|
83
|
+
# @raise [Ecoportal::API::Common::Client::Error::UnexpectedServerError] on non-2xx HTTP status.
|
|
84
|
+
# @raise [Ecoportal::API::Common::GraphQL::ResponseError] when the response body contains GraphQL errors.
|
|
85
|
+
def execute(query_string, variables: {}, operation_name: nil)
|
|
86
|
+
body = { query: query_string, variables: variables }
|
|
87
|
+
body[:operationName] = operation_name if operation_name
|
|
88
|
+
response = base_request.post(url_for(''), json: body)
|
|
89
|
+
handle_http_response(response)
|
|
90
|
+
end
|
|
91
|
+
|
|
49
92
|
# Full URl builder of the request
|
|
50
93
|
# @param path [String] the tail that completes the url of the request.
|
|
51
94
|
# @return [String] the final url.
|
|
52
95
|
def url_for(path)
|
|
53
|
-
|
|
96
|
+
"#{api_url}#{path}"
|
|
54
97
|
end
|
|
55
98
|
|
|
56
99
|
private
|
|
57
100
|
|
|
58
|
-
def
|
|
59
|
-
|
|
101
|
+
def key_token
|
|
102
|
+
return if http?
|
|
103
|
+
return session_token(host: host) if graphql?
|
|
104
|
+
return @api_key if api_key?
|
|
105
|
+
return ENV['ORG_INT_KEY'] if v0?
|
|
106
|
+
|
|
107
|
+
puts 'Api-key missing!'
|
|
60
108
|
end
|
|
61
109
|
|
|
62
|
-
def
|
|
63
|
-
|
|
110
|
+
def api_url
|
|
111
|
+
base_url.then do |url|
|
|
112
|
+
next "#{url}/api/#{version}" if v1_0? || v2_3?
|
|
113
|
+
next "#{url}/api/#{org_id}/#{ENDPOINT_PATH}" if graphql?
|
|
114
|
+
|
|
115
|
+
url
|
|
116
|
+
end
|
|
64
117
|
end
|
|
65
118
|
|
|
66
119
|
def base_url
|
|
67
120
|
@base_url ||= self.class.base_url(host)
|
|
68
121
|
end
|
|
69
122
|
|
|
70
|
-
def
|
|
71
|
-
@
|
|
123
|
+
def protocol
|
|
124
|
+
@protocol ||= self.class.protocol(host)
|
|
72
125
|
end
|
|
73
126
|
|
|
74
|
-
def
|
|
75
|
-
if @
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
127
|
+
def http?
|
|
128
|
+
return true if @version.nil?
|
|
129
|
+
|
|
130
|
+
@version == 'http'
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def api_key?
|
|
134
|
+
@api_key && !@api_key.match(/\A\W*\z/)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def v1_0?
|
|
138
|
+
v1? || v0?
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def v1?
|
|
142
|
+
@version == 'v1'
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def v0?
|
|
146
|
+
@version == 'v0'
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def v2_3?
|
|
150
|
+
return true if @version == 'v2'
|
|
151
|
+
return true if @version == 'v3'
|
|
152
|
+
|
|
153
|
+
false
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def graphql?
|
|
157
|
+
@version == 'graphql'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def handle_http_response(response)
|
|
161
|
+
unless response.status.success?
|
|
162
|
+
raise Ecoportal::API::Common::Client::Error::UnexpectedServerError.new(
|
|
163
|
+
response.body.to_s, code: response.status.code
|
|
164
|
+
)
|
|
83
165
|
end
|
|
166
|
+
|
|
167
|
+
parsed = response.parse(:json)
|
|
168
|
+
errors = parsed['errors']
|
|
169
|
+
raise ResponseError, errors.map { |e| e['message'] }.join('; ') if errors&.any?
|
|
170
|
+
|
|
171
|
+
parsed
|
|
84
172
|
end
|
|
85
173
|
end
|
|
86
174
|
end
|
|
@@ -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
|
|
@@ -37,11 +37,14 @@ module Ecoportal
|
|
|
37
37
|
|
|
38
38
|
# INSTANCE METHODS
|
|
39
39
|
|
|
40
|
-
def as_input(clientMutationId: '')
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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)
|
|
45
48
|
end
|
|
46
49
|
end
|
|
47
50
|
end
|
|
@@ -38,10 +38,12 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
38
38
|
raise "Can't fetch underlying document for instance of #{target.class}."
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
def prev_doc(target = subject
|
|
41
|
+
def prev_doc(target = subject)
|
|
42
42
|
return target.original_doc if target.respond_to?(:original_doc)
|
|
43
43
|
|
|
44
44
|
raise "Can't fetch original underlying model for instance of #{target.class}."
|
|
45
|
+
rescue NoMethodError
|
|
46
|
+
nil
|
|
45
47
|
end
|
|
46
48
|
end
|
|
47
49
|
end
|
|
@@ -34,12 +34,17 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
34
34
|
|
|
35
35
|
protected
|
|
36
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.
|
|
37
39
|
def classic_diff(flat: flat?, ignore: [])
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
# @note it calls `as_update` for nested / cascaded attributes, which in turn
|
|
@@ -49,26 +54,28 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
49
54
|
# `#as_update` and `DiffService#diff`.
|
|
50
55
|
# - The `result` object regards, therefore, to the **current level** alone.
|
|
51
56
|
# With the aim of building it up (accumulating through the call chain).
|
|
52
|
-
def diff_reduce(init
|
|
57
|
+
def diff_reduce(init, ignore: [])
|
|
53
58
|
subject.cascaded_reduce(init, recurs: false) do |result, obj, _key, key_path, _trace|
|
|
54
|
-
next result if key_path.empty?
|
|
55
|
-
next result if obj == subject
|
|
59
|
+
next result if key_path.empty?
|
|
60
|
+
next result if obj == subject
|
|
56
61
|
|
|
57
|
-
|
|
62
|
+
sym_path = key_path.map(&:to_sym)
|
|
58
63
|
|
|
59
|
-
#
|
|
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.
|
|
60
68
|
next result if root?(obj)
|
|
61
|
-
|
|
62
|
-
|
|
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)
|
|
63
72
|
|
|
64
73
|
value = obj.as_update(ignore: ignore)
|
|
74
|
+
next result if value.nil?
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
value
|
|
70
|
-
)
|
|
71
|
-
|
|
76
|
+
result ||= {}
|
|
77
|
+
result[:id] ||= get_id(keys_to_sym_deep(curr_doc(flat: true) || {}), exception: false)
|
|
78
|
+
dig_set!(result, sym_path, value)
|
|
72
79
|
result
|
|
73
80
|
end
|
|
74
81
|
end
|
|
@@ -147,9 +154,10 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
147
154
|
attr_reader :ignored
|
|
148
155
|
|
|
149
156
|
def root?(obj)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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? }
|
|
153
161
|
end
|
|
154
162
|
|
|
155
163
|
def curr_doc(target = subject, flat: flat?)
|
|
@@ -171,8 +179,8 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
171
179
|
|
|
172
180
|
# Remove from `json` doc all the nested properties.
|
|
173
181
|
def doc_with_non_cascaded_attributes(json)
|
|
174
|
-
return json unless subject.respond_to?(:_cascaded_doc_keys)
|
|
175
|
-
return json
|
|
182
|
+
return json unless subject.class.respond_to?(:_cascaded_doc_keys)
|
|
183
|
+
return json if (excluded = subject.class._cascaded_doc_keys).empty?
|
|
176
184
|
|
|
177
185
|
except_keys(json, *excluded)
|
|
178
186
|
end
|
|
@@ -192,7 +192,7 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
192
192
|
end
|
|
193
193
|
|
|
194
194
|
def any_array?(a, b)
|
|
195
|
-
[a, b].any?
|
|
195
|
+
[a, b].any?(Array)
|
|
196
196
|
end
|
|
197
197
|
|
|
198
198
|
def get_id(doc, exception: true)
|
|
@@ -207,6 +207,30 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
207
207
|
id
|
|
208
208
|
end
|
|
209
209
|
|
|
210
|
+
# @param arr [Array] the source Array of id-bearing items
|
|
211
|
+
# @return [Array<String>] the `id`s thereof
|
|
212
|
+
def array_ids(arr)
|
|
213
|
+
return [] if !arr.is_a?(Array) || arr.empty?
|
|
214
|
+
|
|
215
|
+
arr.map {|item| get_id(item, exception: false)}
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# @param arr [Array] the source Array
|
|
219
|
+
# @return [Integer, nil] the position of the item with the given `id`
|
|
220
|
+
def array_id_index(arr, id)
|
|
221
|
+
return unless arr.is_a?(Array)
|
|
222
|
+
|
|
223
|
+
arr.index {|item| get_id(item, exception: false) == id}
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# @param arr [Array] the source Array
|
|
227
|
+
# @return [Object, nil] the item with the given `id`
|
|
228
|
+
def array_id_item(arr, id)
|
|
229
|
+
return unless (idx = array_id_index(arr, id))
|
|
230
|
+
|
|
231
|
+
arr[idx]
|
|
232
|
+
end
|
|
233
|
+
|
|
210
234
|
def meta_keys
|
|
211
235
|
return self::META_KEYS if respond_to?(:const_get)
|
|
212
236
|
|
|
@@ -233,6 +257,35 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
233
257
|
def to_a(*values)
|
|
234
258
|
[values].flatten.compact.uniq
|
|
235
259
|
end
|
|
260
|
+
|
|
261
|
+
# Hash path helpers — used by DiffService#diff_reduce to navigate
|
|
262
|
+
# and modify nested result hashes during cascaded diffing.
|
|
263
|
+
|
|
264
|
+
def dig_path?(obj, keys)
|
|
265
|
+
return false unless obj.is_a?(Hash)
|
|
266
|
+
return obj.key?(keys.first) if keys.length == 1
|
|
267
|
+
return false unless obj.key?(keys.first)
|
|
268
|
+
|
|
269
|
+
dig_path?(obj[keys.first], keys[1..])
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def dig_set!(obj, keys, value)
|
|
273
|
+
if keys.length == 1
|
|
274
|
+
obj[keys.first] = value
|
|
275
|
+
else
|
|
276
|
+
dig_set!(obj[keys.first], keys[1..], value)
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def dig_delete!(obj, keys)
|
|
281
|
+
if keys.length == 1
|
|
282
|
+
return unless obj.respond_to?(:delete)
|
|
283
|
+
|
|
284
|
+
obj.delete(keys.first)
|
|
285
|
+
else
|
|
286
|
+
dig_delete!(obj[keys.first], keys[1..])
|
|
287
|
+
end
|
|
288
|
+
end
|
|
236
289
|
end
|
|
237
290
|
|
|
238
291
|
extend InstanceMethods
|