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
|
@@ -7,8 +7,8 @@ module Ecoportal
|
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
require 'ecoportal/api/common/graphql/http_client'
|
|
11
10
|
require 'ecoportal/api/common/graphql/auth_service'
|
|
11
|
+
require 'ecoportal/api/common/graphql/http_client'
|
|
12
12
|
require 'ecoportal/api/common/graphql/client'
|
|
13
13
|
require 'ecoportal/api/common/graphql/class_helpers'
|
|
14
14
|
require 'ecoportal/api/common/graphql/hash_helpers'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# graphql (gem root)
|
|
2
|
+
|
|
3
|
+
The entry point for the gem: `Ecoportal::API::GraphQL` is the top-level class consumers instantiate; it holds the `client`, wires the `HttpClient`, and exposes builder/compat entry points.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
| File / class | Purpose |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `graphql.rb` / `GraphQL` | Main entry class — `initialize` builds `Client` + `HttpClient`, exposes `pages`, `registers`, `page`, `action`, `contractorEntity`, `locationStructure`, `currentOrganization` |
|
|
10
|
+
| `graphql_version.rb` | Gem `VERSION` constant |
|
|
11
|
+
| `base/` | Data-only model base classes (no resolvers, no `client`); see `base/CLAUDE.md` |
|
|
12
|
+
| `builder/` | Facade builders that group related mutations under one object |
|
|
13
|
+
| `compat/` | v2-compatible API layer for eco-helpers scripts |
|
|
14
|
+
| `concerns/` | Shared Ruby mixins (`PageCompat`, `DataFieldAccess`, `SnakeCamelAccess`, `FragmentDefinitions`) |
|
|
15
|
+
| `connection/` | `Logic::Connection` subclasses — typed pagination wrappers per entity |
|
|
16
|
+
| `error/` | Domain error classes (`ValidationErrors`, `LocationsError`, `LocationsValidationError`) |
|
|
17
|
+
| `fragment/` | GraphQL fragment heredoc strings + `Fragment.assemble(*syms)` |
|
|
18
|
+
| `helpers/` | Utility modules (`LocationsTree`) |
|
|
19
|
+
| `input/` | Mutation input serialisers; `SearchConf` is a chainable value object |
|
|
20
|
+
| `interface/` | Abstract base models shared by `Base::` and `Model::` (e.g. `BasePage`, `LocationStructure`) |
|
|
21
|
+
| `logic/` | Abstract base classes for queries, mutations, connections — no domain code |
|
|
22
|
+
| `model/` | Concrete domain models with `class_resolver` wiring; subclass their `Base::` counterparts |
|
|
23
|
+
| `mutation/` | Concrete mutation execution classes |
|
|
24
|
+
| `payload/` | Mutation response payload wrappers |
|
|
25
|
+
| `query/` | Concrete query execution classes |
|
|
26
|
+
|
|
27
|
+
## Conventions
|
|
28
|
+
|
|
29
|
+
- Load order in `graphql.rb` matters: `logic/base_model` → `error` → `interface` → `base` → `model` → rest.
|
|
30
|
+
- `#pages` returns `Compat::Pages` (v2-compatible); `#page` returns `Builder::Page` (raw mutation facade).
|
|
31
|
+
- `#currentOrganization` returns `Model::Organization` class (not instance) with `client` set — query methods are class-level.
|
|
32
|
+
- `GraphQL` (not `GraphQL`) is the namespace: use `Ecoportal::API::Graphql` alias only for legacy references; internal code uses `GraphQL`.
|
|
33
|
+
|
|
34
|
+
## Related
|
|
35
|
+
|
|
36
|
+
- `../../common/graphql/` — HTTP client, auth, and base model infrastructure
|
|
37
|
+
- Downstream: `eco-helpers` calls `.pages` and `.registers` exclusively via `Compat::*`
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# base
|
|
2
|
+
|
|
3
|
+
Data-only model base classes — these declare fields and structure but hold no `client`, no query resolvers, and no business logic.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
| File / class | Purpose |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `action.rb` / `Base::Action` | Action fields (id, name, status, dates, assignee IDs); declared `root!` so excluded from cascaded diffs |
|
|
10
|
+
| `action_category.rb` / `Base::ActionCategory` | Action category fields |
|
|
11
|
+
| `contractor_entity.rb` / `Base::ContractorEntity` | Contractor entity fields |
|
|
12
|
+
| `contractor_entity/member_changes.rb` | Nested member-changes sub-model |
|
|
13
|
+
| `date_time.rb` / `Base::DateTime` | Wraps `{ dateTime:, timeZone: }` response objects |
|
|
14
|
+
| `delta_result.rb` / `Base::DeltaResult` | `pageDelta` result item: `id` + `delta` enum (UPDATED/NOT_FOUND/NEW) |
|
|
15
|
+
| `field.rb` / `Base::Field` | Generic field model |
|
|
16
|
+
| `file_attachment.rb` / `Base::FileAttachment` | File attachment metadata |
|
|
17
|
+
| `file_container.rb` / `Base::FileContainer` | File container wrapper |
|
|
18
|
+
| `location_classification_type.rb` | Classification type (name) |
|
|
19
|
+
| `location_node.rb` / `Base::LocationNode` | Location node with ancestors and classifications |
|
|
20
|
+
| `location_structure.rb` / `Base::LocationStructure` | Location structure tree model |
|
|
21
|
+
| `location_structure/draft.rb` | Draft structure model |
|
|
22
|
+
| `location_structure/draft/structure.rb` | Nested draft structure detail |
|
|
23
|
+
| `organization.rb` / `Base::Organization` | Thin organization base (id, name) |
|
|
24
|
+
| `page.rb` | Namespace module; requires `basic`, `data_field`, `section`, `section_collection`, `phased` |
|
|
25
|
+
| `page/basic.rb` / `Base::Page::Basic` | BasicPage — inherits `Interface::BasePage`; no extra fields |
|
|
26
|
+
| `page/phased.rb` / `Base::Page::Phased` | PhasedPage — inherits `Interface::BasePage`; `embeds_many :stages` |
|
|
27
|
+
| `page/phased/stage.rb` / `Base::Page::Phased::Stage` | Single stage: id, name, ordering, state, sections, components |
|
|
28
|
+
| `page/section.rb` / `Base::Page::Section` | Section wrapper (ContentSection or SplitSection); merges left/right dataFields into `components` |
|
|
29
|
+
| `page/section_collection.rb` / `Base::Page::SectionCollection` | Enumerable wrapper over sections; provides `get_by_type`, `get_by_heading`, `components` |
|
|
30
|
+
| `page/data_field.rb` / `Base::Page::DataField` | Base data field class; `TYPE_MAP` dispatches `from_doc` to typed subclasses |
|
|
31
|
+
| `page/data_field/` | 10 typed subclasses (PlainText, RichText, DateField, Number, Gauge, People, Select, Checklist, TagField, Geo) + `Collection` |
|
|
32
|
+
| `page_info.rb` / `Base::PageInfo` | Cursor pagination info (endCursor, hasNextPage) |
|
|
33
|
+
| `person_member.rb` / `Base::PersonMember` | Person member (name, email, id) |
|
|
34
|
+
| `preview_page.rb` / `Base::PreviewPage` | Lightweight page preview (no field data) |
|
|
35
|
+
| `resource.rb` / `Base::Resource` | Resource model (inherits `Logic::BaseModel` directly) |
|
|
36
|
+
| `pages_workflow.rb` / `Base::PagesWorkflow` | PagesWorkflow top-level model: `autoPageCreationEnabled`, `fields` (RegisterField), `stages`; sub-files under `pages_workflow/` cover RegisterField, CallbackType, OperationInterface, TriggerInterface, and supporting types |
|
|
37
|
+
|
|
38
|
+
## Conventions
|
|
39
|
+
|
|
40
|
+
- `Base::` classes are data-only: `passkey`, `passthrough`, `passboolean`, `passarray`, `embeds_one`, `embeds_many` only — no business methods, no resolvers.
|
|
41
|
+
- `Model::` subclasses in `../model/` add `class_resolver` wiring and may add behaviour (e.g. `Model::Page::Phased#stages` wraps the array in `Compat::StageCollection`).
|
|
42
|
+
- `Interface::BasePage` is the shared parent of both `Basic` and `Phased`; field declarations that apply to both page types live there.
|
|
43
|
+
- `Base::Action` declares `root!` — this marks it as an independent server entity, excluded from cascaded `as_update` diffs.
|
|
44
|
+
- When adding a new field to a page type, add it to `Interface::BasePage` if it applies to both, or to the appropriate `Base::Page::*` class.
|
|
45
|
+
|
|
46
|
+
## Related
|
|
47
|
+
|
|
48
|
+
- `../interface/base_page.rb` — common parent for Basic + Phased page base classes
|
|
49
|
+
- `../model/` — concrete models that subclass these bases
|
|
50
|
+
- `../model/page_union.rb` — factory that dispatches `__typename` to `Model::Page::Basic` or `Model::Page::Phased`
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
# Represents one generation version of an AiSummary field.
|
|
6
|
+
# Returned by generateAiSummary — tracks the prompt, output, token usage, and status.
|
|
7
|
+
class AiSummaryVersion < Logic::BaseModel
|
|
8
|
+
passkey :id
|
|
9
|
+
passthrough :aiSummary, :status, :prompt
|
|
10
|
+
passthrough :inputTokens, :outputTokens, :totalTokens
|
|
11
|
+
passthrough :resourceType # "field" | "stage" | "page"
|
|
12
|
+
passarray :ratings # [[user_id, score], ...]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
# Result of a pageDelta query for a single page ID.
|
|
6
|
+
# delta: 'UPDATED' | 'NOT_FOUND' | 'NEW'
|
|
7
|
+
class DeltaResult < Logic::BaseModel
|
|
8
|
+
read_only!
|
|
9
|
+
|
|
10
|
+
passkey :id
|
|
11
|
+
passthrough :delta
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
class Force
|
|
6
|
+
# A single force binding — links a Force to a data field or section by referenceId.
|
|
7
|
+
class Binding < Logic::BaseModel
|
|
8
|
+
passkey :id
|
|
9
|
+
passthrough :name, :referenceId
|
|
10
|
+
|
|
11
|
+
def reference_id
|
|
12
|
+
referenceId
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
class Force
|
|
6
|
+
# Wraps the bindings array of a Force. Supports the v2 scripting interface:
|
|
7
|
+
# force.bindings.get_by_name(name) → [Binding, ...]
|
|
8
|
+
# force.bindings.add(field, name:) → queues addBinding command
|
|
9
|
+
# force.bindings.delete!(binding) → queues removeBinding command
|
|
10
|
+
class BindingCollection
|
|
11
|
+
include Enumerable
|
|
12
|
+
|
|
13
|
+
def initialize(raw, force:)
|
|
14
|
+
@force = force
|
|
15
|
+
@bindings = Array(raw).map { |b| Force::Binding.new(b) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Filter bindings by name (case-insensitive).
|
|
19
|
+
def get_by_name(name)
|
|
20
|
+
target = name.to_s.downcase
|
|
21
|
+
@bindings.select { |b| b.name.to_s.downcase == target }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Queue an addBinding command. `field` may be a GraphQL DataField object
|
|
25
|
+
# (uses field.id as referenceId) or a raw ID string.
|
|
26
|
+
def add(field, name:, type: 'field')
|
|
27
|
+
ref_id = field.respond_to?(:id) ? field.id : field.to_s
|
|
28
|
+
@force.queue_command(
|
|
29
|
+
addBinding: {
|
|
30
|
+
forceId: @force.id,
|
|
31
|
+
name: name.to_s,
|
|
32
|
+
referenceId: ref_id,
|
|
33
|
+
type: type
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
self
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Queue a removeBinding command. Accepts a Binding object or an ID string.
|
|
40
|
+
def delete!(binding_or_id)
|
|
41
|
+
bid = binding_or_id.respond_to?(:id) ? binding_or_id.id : binding_or_id.to_s
|
|
42
|
+
@force.queue_command(removeBinding: { id: bid })
|
|
43
|
+
self
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def each(&block)
|
|
47
|
+
@bindings.each(&block)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def size
|
|
51
|
+
@bindings.size
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def empty?
|
|
55
|
+
@bindings.empty?
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
class Force
|
|
6
|
+
# Wraps a page's forces array. Provides the v2 scripting interface:
|
|
7
|
+
# page.forces.get_by_name(name) → [Force, ...]
|
|
8
|
+
class Collection
|
|
9
|
+
include Enumerable
|
|
10
|
+
|
|
11
|
+
def initialize(raw)
|
|
12
|
+
@forces = Array(raw).map { |f| Force.new(f) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Filter forces by name (case-insensitive).
|
|
16
|
+
def get_by_name(name)
|
|
17
|
+
target = name.to_s.downcase
|
|
18
|
+
@forces.select { |f| f.name.to_s.downcase == target }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# True if any force has uncommitted script changes or pending binding commands.
|
|
22
|
+
def dirty?
|
|
23
|
+
@forces.any?(&:dirty?)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# All pending commands across all forces (editForce, addBinding, removeBinding).
|
|
27
|
+
def pending_commands
|
|
28
|
+
@forces.flat_map(&:all_pending_commands)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def each(&block)
|
|
32
|
+
@forces.each(&block)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def size
|
|
36
|
+
@forces.size
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def empty?
|
|
40
|
+
@forces.empty?
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
# Represents a Force — a AngularJS/LISP snippet that implements conditional
|
|
6
|
+
# field behaviour on a page stage. Forces are queried as part of a page
|
|
7
|
+
# when forces are explicitly included in the query fragment.
|
|
8
|
+
#
|
|
9
|
+
# Read access is via the page's force collection:
|
|
10
|
+
# force = page.forces.get_by_name('Workflow (S1)').first
|
|
11
|
+
# force.custom_script # → current LISP script
|
|
12
|
+
# force.bindings.get_by_name('top-txt') # → [Binding, ...]
|
|
13
|
+
#
|
|
14
|
+
# Write access queues workflow commands executed after process_ooze:
|
|
15
|
+
# force.custom_script = new_script # → queues editForce command
|
|
16
|
+
# force.bindings.add(field, name: 'bind-name') # → queues addBinding
|
|
17
|
+
# force.bindings.delete!(binding) # → queues removeBinding
|
|
18
|
+
class Force < Logic::BaseModel
|
|
19
|
+
passkey :id
|
|
20
|
+
passthrough :name, :script, :customScript, :weight, :url
|
|
21
|
+
passarray :globalBindingIds
|
|
22
|
+
|
|
23
|
+
require_relative 'force/binding'
|
|
24
|
+
require_relative 'force/binding_collection'
|
|
25
|
+
require_relative 'force/collection'
|
|
26
|
+
|
|
27
|
+
def bindings
|
|
28
|
+
@bindings ||= Force::BindingCollection.new(doc['bindings'] || [], force: self)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# v2 compat: scripts read and write custom_script directly.
|
|
32
|
+
# Writing queues an editForce workflow command consumed by ForceCompat.
|
|
33
|
+
def custom_script=(new_script)
|
|
34
|
+
return if doc['customScript'] == new_script
|
|
35
|
+
|
|
36
|
+
doc['customScript'] = new_script
|
|
37
|
+
@_custom_script_dirty = true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def dirty?
|
|
41
|
+
@_custom_script_dirty || pending_commands.any?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Accumulate workflow commands (editForce, addBinding, removeBinding).
|
|
45
|
+
def queue_command(command_hash)
|
|
46
|
+
pending_commands << command_hash
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# All pending commands for this force (editForce if script changed + binding ops).
|
|
50
|
+
def pending_commands
|
|
51
|
+
@pending_commands ||= []
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Collect all commands including the script edit if dirty.
|
|
55
|
+
def all_pending_commands
|
|
56
|
+
cmds = []
|
|
57
|
+
cmds << { editForce: { id: id, customScript: doc['customScript'] } } if @_custom_script_dirty
|
|
58
|
+
cmds.concat(pending_commands)
|
|
59
|
+
cmds
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
module Kickstand
|
|
6
|
+
class Job < Logic::BaseModel
|
|
7
|
+
SCHEMA_VERSION = '20260605'.freeze
|
|
8
|
+
|
|
9
|
+
passkey :id
|
|
10
|
+
passthrough :status
|
|
11
|
+
passthrough :createdAt, :updatedAt
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
module Kickstand
|
|
6
|
+
class Workflow < Logic::BaseModel
|
|
7
|
+
SCHEMA_VERSION = '20260605'.freeze
|
|
8
|
+
|
|
9
|
+
passkey :id
|
|
10
|
+
passthrough :name, :status
|
|
11
|
+
passthrough :createdAt, :updatedAt
|
|
12
|
+
passthrough :startedAt, :stoppedAt, :failedAt, :finishedAt
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Base
|
|
5
|
+
module Page
|
|
6
|
+
class Basic < Interface::BasePage
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
# v2-compat read flatten: a basic page's fields live nested under
|
|
10
|
+
# sections (CommonPageUnion fetches `sections { ...sectionUnion }` with the
|
|
11
|
+
# data fields inside each section — it does NOT select a top-level
|
|
12
|
+
# `dataFields`). v2 exposed fields flat at the page (page.components), so
|
|
13
|
+
# gather them from sections here, mirroring Model::Page::Phased#raw_data_fields.
|
|
14
|
+
# Field docs are shared by reference, so mutations forward to the section doc.
|
|
15
|
+
#
|
|
16
|
+
# `raw_sections` keeps the DataFieldAccess default (doc['sections']) — basic
|
|
17
|
+
# pages already store sections at the page root.
|
|
18
|
+
def raw_data_fields
|
|
19
|
+
from_sections = raw_sections.flat_map { |section| field_docs_in(section) }.compact.uniq { |fld| fld['id'] }
|
|
20
|
+
return from_sections unless from_sections.empty?
|
|
21
|
+
|
|
22
|
+
# Create/flat path: fields may be supplied at the page root (top-level
|
|
23
|
+
# `dataFields`, no sections) — fall back to the DataFieldAccess default
|
|
24
|
+
# so create input + flat-built basic pages still expose their fields.
|
|
25
|
+
doc['dataFields'] || []
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def field_docs_in(section)
|
|
29
|
+
(section['dataFields'] || []) +
|
|
30
|
+
(section['leftDataFields'] || []) +
|
|
31
|
+
(section['rightDataFields'] || [])
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# Actions list field — embedded action items linked to this page.
|
|
4
|
+
# Actions are managed through Mutation::Action::*; not via DataFieldInput.
|
|
5
|
+
class ActionsList < DataField
|
|
6
|
+
passarray :actions # each: { id:, name:, status: }
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# AI-generated summary field.
|
|
4
|
+
# Content is generated server-side via generateAiSummary mutation (Bedrock Claude).
|
|
5
|
+
# Not settable via DataFieldInput — use the dedicated mutation instead.
|
|
6
|
+
#
|
|
7
|
+
# instructions: the AI prompt configured on this field in the template.
|
|
8
|
+
# trigger: "submitted" | "approved" — when generation fires.
|
|
9
|
+
# trigger_stage_ids: stages that trigger generation (empty = all stages).
|
|
10
|
+
# text_format: "simple_text" | "bullet_points" | "numbered_list" | "headings"
|
|
11
|
+
class AiSummary < DataField
|
|
12
|
+
passthrough :aiSummary, :generatedAt, :instructions
|
|
13
|
+
passthrough :trigger, :textFormat
|
|
14
|
+
passarray :triggerStageIds, :fieldConfigurations
|
|
15
|
+
passboolean :alreadyRated
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
class Checklist < DataField
|
|
4
|
+
passarray :items # each: { id:, label:, checked: }
|
|
5
|
+
passthrough :complete
|
|
6
|
+
|
|
7
|
+
# Check/uncheck an item by label or id.
|
|
8
|
+
def check(label_or_id, checked: true)
|
|
9
|
+
item = (doc['items'] || []).find { |i| i['label'] == label_or_id.to_s || i['id'] == label_or_id.to_s }
|
|
10
|
+
return unless item
|
|
11
|
+
|
|
12
|
+
item['checked'] = checked
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def as_input
|
|
16
|
+
return nil unless dirty?
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
checklist: {
|
|
20
|
+
id: id,
|
|
21
|
+
# rubocop:disable Style/DoubleNegation
|
|
22
|
+
items: (doc['items'] || []).map { |i| { id: i['id'], checked: !!i['checked'] } }
|
|
23
|
+
# rubocop:enable Style/DoubleNegation
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# Wraps an array of raw data field docs as typed DataField objects.
|
|
4
|
+
# Provides v2-compatible access patterns used in eco-helpers scripts:
|
|
5
|
+
# components.get_by_type(:plain_text) — filter by field type
|
|
6
|
+
# components.get_by_name('FieldLabel') — find by label
|
|
7
|
+
# components.doc — raw doc array
|
|
8
|
+
# components.dirty_inputs — changed field hashes for mutation
|
|
9
|
+
class Collection
|
|
10
|
+
include Enumerable
|
|
11
|
+
|
|
12
|
+
# Accepts raw field docs (→ built via from_doc) OR already-built DataField objects
|
|
13
|
+
# (kept as-is). Preserving existing objects lets a phased page's Stage#components share
|
|
14
|
+
# the SAME field objects as the page's canonical field_collection (so stage-level
|
|
15
|
+
# mutations land in the page's data_fields_updates — phased write-path identity).
|
|
16
|
+
def initialize(fields)
|
|
17
|
+
@fields = Array(fields).map { |f| f.is_a?(DataField) ? f : DataField.from_doc(f) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Build from a raw docs array.
|
|
21
|
+
def self.from_doc(raw_array)
|
|
22
|
+
new(Array(raw_array))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Filter by field type. Accepts symbol (:plain_text), string ('PlainText'), or
|
|
26
|
+
# the GraphQL __typename directly. Matching is case-insensitive.
|
|
27
|
+
def get_by_type(type_key)
|
|
28
|
+
target = normalise_type(type_key)
|
|
29
|
+
@fields.select { |f| normalise_type(f.type) == target }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Find first field matching label (case-insensitive). Optional type: restricts to
|
|
33
|
+
# that field type first (v2 compat: components.get_by_name(name, type:) — used by
|
|
34
|
+
# the farmers cutover use case which calls it directly, not via OozeRedirect).
|
|
35
|
+
def get_by_name(label, type: nil)
|
|
36
|
+
pool = type ? get_by_type(type) : @fields
|
|
37
|
+
pool.find { |f| f.label.to_s.downcase == label.to_s.downcase }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Raw doc array (v2 compat — scripts iterate secs_doc / flds_doc).
|
|
41
|
+
def doc
|
|
42
|
+
@fields.map(&:doc)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Add a new field to this collection (v2 compat: components.add).
|
|
46
|
+
# The field must reference an existing server-side ID (from buildFromTemplate).
|
|
47
|
+
# Yields the new field object to the block for configuration.
|
|
48
|
+
# Returns the field object.
|
|
49
|
+
#
|
|
50
|
+
# Usage:
|
|
51
|
+
# components.add(doc: raw_doc) { |f| f.value = 'X' }
|
|
52
|
+
# components.add(id: 'f1', label: 'Name', type: 'PlainText') { |f| f.value = 'X' }
|
|
53
|
+
def add(doc: nil, id: nil, label: nil, type: nil, **opts)
|
|
54
|
+
raw = doc || opts.merge('id' => id, 'label' => label, '__typename' => type.to_s).compact
|
|
55
|
+
field = DataField.from_doc(raw)
|
|
56
|
+
@additions ||= []
|
|
57
|
+
@additions << field
|
|
58
|
+
yield field if block_given?
|
|
59
|
+
field
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Mark a field for deletion by field ID or field object.
|
|
63
|
+
# The field ID is sent in dataFields.deletions on the next update.
|
|
64
|
+
def mark_for_deletion(id_or_field)
|
|
65
|
+
field_id = id_or_field.respond_to?(:id) ? id_or_field.id : id_or_field.to_s
|
|
66
|
+
@deletions ||= []
|
|
67
|
+
@deletions |= [field_id]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Returns DataFieldInput hashes for fields modified via value setters.
|
|
71
|
+
def dirty_inputs
|
|
72
|
+
@fields.filter_map(&:as_input)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Returns DataFieldInput hashes for fields added via #add.
|
|
76
|
+
def dirty_additions
|
|
77
|
+
(@additions || []).filter_map(&:as_input)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns field IDs queued for deletion via #mark_for_deletion.
|
|
81
|
+
def dirty_deletions
|
|
82
|
+
@deletions || []
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def dirty?
|
|
86
|
+
@fields.any?(&:dirty?) ||
|
|
87
|
+
(@additions || []).any?(&:dirty?) ||
|
|
88
|
+
!dirty_deletions.empty?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def each(&block)
|
|
92
|
+
@fields.each(&block)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def empty?
|
|
96
|
+
@fields.empty?
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def length
|
|
100
|
+
@fields.length
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
# Normalise type key to lowercase no-underscore string for comparison.
|
|
106
|
+
# :plain_text → 'plaintext', 'PlainText' → 'plaintext'
|
|
107
|
+
def normalise_type(type_key)
|
|
108
|
+
type_key.to_s.downcase.delete('_') if type_key
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Ecoportal::API::GraphQL::Base::Page
|
|
2
|
+
class DataField
|
|
3
|
+
# Contractor entity selector field.
|
|
4
|
+
# Stores references to ContractorEntity records.
|
|
5
|
+
class ContractorEntities < DataField
|
|
6
|
+
passarray :contractors # each: { id:, name: }
|
|
7
|
+
|
|
8
|
+
def contractor_entity_ids
|
|
9
|
+
Array(contractors).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def contractor_entity_ids=(ids)
|
|
13
|
+
doc['contractors'] = Array(ids).map { |id_val| { 'id' => id_val } }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# v2 compat alias
|
|
17
|
+
def value=(ids)
|
|
18
|
+
self.contractor_entity_ids = ids
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def as_input
|
|
22
|
+
return nil unless dirty?
|
|
23
|
+
|
|
24
|
+
{ contractorEntities: { id: id, contractorEntityIds: contractor_entity_ids } }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|