ecoportal-api-graphql 1.3.5 → 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.
Files changed (499) hide show
  1. checksums.yaml +4 -4
  2. data/.ai-assistance/bridge/CLAUDE.md +338 -0
  3. data/.ai-assistance/bridge/archive/.gitkeep +0 -0
  4. data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.inbox.md +29 -0
  5. data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.outbox.md +18 -0
  6. data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.inbox.md +42 -0
  7. data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.outbox.md +115 -0
  8. data/.ai-assistance/bridge/context/gemini-review-prompt.txt +48 -0
  9. data/.ai-assistance/bridge/context/gemini-review-response.md +104 -0
  10. data/.ai-assistance/bridge/context/project.md +42 -0
  11. data/.ai-assistance/bridge/inbox/.gitkeep +0 -0
  12. data/.ai-assistance/bridge/outbox/.gitkeep +0 -0
  13. data/.ai-assistance/bridge/outbox/request-for-standards-discovery.md +48 -0
  14. data/.ai-assistance/bridge/queue/.gitkeep +1 -0
  15. data/.ai-assistance/capabilities/CLAUDE.md +27 -0
  16. data/.ai-assistance/capabilities/assumptions-log.md +80 -0
  17. data/.ai-assistance/capabilities/code.md +47 -0
  18. data/.ai-assistance/capabilities/connectors.md +37 -0
  19. data/.ai-assistance/capabilities/cowork.md +55 -0
  20. data/.ai-assistance/code/OVERVIEW.md +155 -0
  21. data/.ai-assistance/code/data_fields.md +242 -0
  22. data/.ai-assistance/code/dependencies.md +151 -0
  23. data/.ai-assistance/code/diff_as_input.md +234 -0
  24. data/.ai-assistance/code/diff_service_deep_dive.md +192 -0
  25. data/.ai-assistance/code/ecoPortal_architecture/00_overview_and_index.md +55 -0
  26. data/.ai-assistance/code/ecoPortal_architecture/01_terminology_dictionary.md +181 -0
  27. data/.ai-assistance/code/ecoPortal_architecture/02_data_model.md +192 -0
  28. data/.ai-assistance/code/ecoPortal_architecture/03_api_layers.md +147 -0
  29. data/.ai-assistance/code/ecoPortal_architecture/04_graphql_queries_mutations.md +277 -0
  30. data/.ai-assistance/code/ecoPortal_architecture/05_page_workflows.md +200 -0
  31. data/.ai-assistance/code/ecoPortal_architecture/06_search_and_filters.md +228 -0
  32. data/.ai-assistance/code/ecoPortal_architecture/07_data_fields.md +197 -0
  33. data/.ai-assistance/code/ecoPortal_architecture/08_stages_sections.md +243 -0
  34. data/.ai-assistance/code/ecoPortal_architecture/09_people_contractors_locations.md +196 -0
  35. data/.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md +132 -0
  36. data/.ai-assistance/code/ecoPortal_architecture/11_integration_gems.md +187 -0
  37. data/.ai-assistance/code/ecoPortal_architecture/12_ai_documentation_sources_gaps.md +236 -0
  38. data/.ai-assistance/code/ecoPortal_architecture/13_ai_infrastructure.md +183 -0
  39. data/.ai-assistance/code/ecoportal_schema_reference.md +240 -0
  40. data/.ai-assistance/code/graphql_domain_knowledge.md +230 -0
  41. data/.ai-assistance/code/refactoring/datafield-readwrite-shape-asymmetry.md +71 -0
  42. data/.ai-assistance/code/refactoring/opportunities.md +251 -0
  43. data/.ai-assistance/code/schema_analysis.md +321 -0
  44. data/.ai-assistance/code/search_filters.md +868 -0
  45. data/.ai-assistance/code/spec_coverage.md +73 -0
  46. data/.ai-assistance/code/workflow-command-guide.md +438 -0
  47. data/.ai-assistance/code/workflow-space.md +353 -0
  48. data/.ai-assistance/conventions/CLAUDE.md +30 -0
  49. data/.ai-assistance/conventions/code-working-tree-protocol.md +199 -0
  50. data/.ai-assistance/conventions/gitignore-rules.md +42 -0
  51. data/.ai-assistance/conventions/permission-guidance.md +120 -0
  52. data/.ai-assistance/integrations/README.md +70 -0
  53. data/.ai-assistance/integrations/gitkraken-mcp.md +107 -0
  54. data/.ai-assistance/integrations/gitlab-mcp.md +123 -0
  55. data/.ai-assistance/integrations/local-git.md +60 -0
  56. data/.ai-assistance/local_paths.example.md +17 -0
  57. data/.ai-assistance/projects/TODO.md +97 -0
  58. data/.ai-assistance/projects/api-v2-to-graphql-migration/DECISIONS.md +168 -0
  59. data/.ai-assistance/projects/api-v2-to-graphql-migration/INTENT.md +60 -0
  60. data/.ai-assistance/projects/api-v2-to-graphql-migration/TODO.md +267 -0
  61. data/.ai-assistance/projects/api-v2-to-graphql-migration/UPSTREAM.md +53 -0
  62. data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/csv-template-pipeline-design.md +102 -0
  63. data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/cutover-usecase-gap-audit.md +139 -0
  64. data/.ai-assistance/projects/dynamic-model-generation/INTENT.md +93 -0
  65. data/.ai-assistance/projects/eco-helpers-compat/INTENT.md +244 -0
  66. data/.ai-assistance/projects/eco-helpers-compat/MIGRATION_GUIDE.md +266 -0
  67. data/.ai-assistance/projects/eco-helpers-compat/TODO.md +86 -0
  68. data/.ai-assistance/projects/ecoportal-api-v2-doublemodel-review/INTENT.md +101 -0
  69. data/.ai-assistance/projects/graphql-agent/GAP_ANALYSIS.md +177 -0
  70. data/.ai-assistance/projects/ooze-graphql-native-migration/DECISIONS.md +161 -0
  71. data/.ai-assistance/projects/ooze-graphql-native-migration/INTENT.md +125 -0
  72. data/.ai-assistance/projects/ooze-graphql-native-migration/RISKS.md +126 -0
  73. data/.ai-assistance/projects/ooze-graphql-native-migration/TODO.md +256 -0
  74. data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-06-30-cutover-workflow-deep-review.md +122 -0
  75. data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-07-01-forces-via-workflow-commands-miss-rca.md +148 -0
  76. data/.ai-assistance/projects/page-model/DECISIONS.md +245 -0
  77. data/.ai-assistance/projects/page-model/TODO.md +190 -0
  78. data/.ai-assistance/projects/search-filter-builder/INTENT.md +107 -0
  79. data/.ai-assistance/projects/search-filter-builder/TODO.md +131 -0
  80. data/.ai-assistance/projects/template-maintenance/DESIGN.md +134 -0
  81. data/.ai-assistance/projects/workflow-space/TODO.md +213 -0
  82. data/.ai-assistance/reinstall-claude-desktop-windows.md +136 -0
  83. data/.ai-assistance/scripts/CLAUDE.md +150 -0
  84. data/.ai-assistance/scripts/bridge-init.sh +86 -0
  85. data/.ai-assistance/scripts/bridge-status.sh +44 -0
  86. data/.ai-assistance/scripts/capabilities-check.ts +104 -0
  87. data/.ai-assistance/scripts/check-outbox.sh +43 -0
  88. data/.ai-assistance/scripts/dep_graph.rb +91 -0
  89. data/.ai-assistance/scripts/lock-acquire.sh +103 -0
  90. data/.ai-assistance/scripts/lock-multi.sh +124 -0
  91. data/.ai-assistance/scripts/lock-queue.sh +94 -0
  92. data/.ai-assistance/scripts/setup-mcps.test.ts +188 -0
  93. data/.ai-assistance/scripts/setup-mcps.ts +234 -0
  94. data/.ai-assistance/scripts/task-complete.ts +74 -0
  95. data/.ai-assistance/scripts/task-create.ts +75 -0
  96. data/.ai-assistance/scripts/task-read.ts +125 -0
  97. data/.ai-assistance/scripts/token-logger.js +220 -0
  98. data/.ai-assistance/scripts/token-report.ts +158 -0
  99. data/.ai-assistance/scripts/token-session-start.js +66 -0
  100. data/.ai-assistance/skills/ai-instructions/SKILL.md +48 -0
  101. data/.ai-assistance/skills/code-specs/SKILL.md +69 -0
  102. data/.ai-assistance/skills/corporate-policies/SKILL.md +201 -0
  103. data/.ai-assistance/skills/dep-graph/SKILL.md +139 -0
  104. data/.ai-assistance/skills/ep-ai-manager/SKILL.md +417 -0
  105. data/.ai-assistance/skills/gemini-assist/SKILL.md +63 -0
  106. data/.ai-assistance/skills/gemini-assist/gemini-mcp-server.js +205 -0
  107. data/.ai-assistance/skills/gemini-assist/gemini_ask.py +1 -0
  108. data/.ai-assistance/skills/gemini-assist/gemini_ask.rb +240 -0
  109. data/.ai-assistance/skills/gemini-assist/prompts/cycle_end_review.txt +25 -0
  110. data/.ai-assistance/skills/graphql-schema-analysis/SKILL.md +261 -0
  111. data/.ai-assistance/skills/project-cycle/SKILL.md +177 -0
  112. data/.ai-assistance/skills/refactor/SKILL.md +62 -0
  113. data/.ai-assistance/skills/rubocop/SKILL.md +93 -0
  114. data/.ai-assistance/skills/ruby-scripting/SKILL.md +215 -0
  115. data/.ai-assistance/skills/spec-generation/SKILL.md +72 -0
  116. data/.ai-assistance/standards-version.json +21 -0
  117. data/.ai-assistance/token-budget.json +32 -0
  118. data/.ai-assistance/version.json +39 -0
  119. data/.claude/settings.json +146 -0
  120. data/.env.example +18 -0
  121. data/.gitattributes +15 -0
  122. data/.gitignore +13 -0
  123. data/.rubocop.yml +121 -97
  124. data/CHANGELOG.md +673 -477
  125. data/CLAUDE.md +232 -0
  126. data/Gemfile +30 -6
  127. data/Rakefile +90 -38
  128. data/docs/worklog.md +574 -0
  129. data/ecoportal-api-graphql.gemspec +40 -40
  130. data/lib/ecoportal/api/common/graphql/CLAUDE.md +36 -0
  131. data/lib/ecoportal/api/common/graphql/client.rb +1 -1
  132. data/lib/ecoportal/api/common/graphql/http_client.rb +35 -3
  133. data/lib/ecoportal/api/common/graphql/model/CLAUDE.md +28 -0
  134. data/lib/ecoportal/api/common/graphql/model/as_input.rb +8 -5
  135. data/lib/ecoportal/api/common/graphql/model/diffable/classic_diff_service.rb +3 -1
  136. data/lib/ecoportal/api/common/graphql/model/diffable/diff_service.rb +31 -23
  137. data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff_nesting.rb +54 -1
  138. data/lib/ecoportal/api/graphql/CLAUDE.md +37 -0
  139. data/lib/ecoportal/api/graphql/base/CLAUDE.md +50 -0
  140. data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +17 -0
  141. data/lib/ecoportal/api/graphql/base/delta_result.rb +16 -0
  142. data/lib/ecoportal/api/graphql/base/force/binding.rb +19 -0
  143. data/lib/ecoportal/api/graphql/base/force/binding_collection.rb +62 -0
  144. data/lib/ecoportal/api/graphql/base/force/collection.rb +47 -0
  145. data/lib/ecoportal/api/graphql/base/force.rb +65 -0
  146. data/lib/ecoportal/api/graphql/base/kickstand/job.rb +17 -0
  147. data/lib/ecoportal/api/graphql/base/kickstand/workflow.rb +18 -0
  148. data/lib/ecoportal/api/graphql/base/kickstand.rb +13 -0
  149. data/lib/ecoportal/api/graphql/base/page/basic.rb +38 -0
  150. data/lib/ecoportal/api/graphql/base/page/data_field/actions_list.rb +9 -0
  151. data/lib/ecoportal/api/graphql/base/page/data_field/ai_summary.rb +18 -0
  152. data/lib/ecoportal/api/graphql/base/page/data_field/checklist.rb +29 -0
  153. data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +112 -0
  154. data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +28 -0
  155. data/lib/ecoportal/api/graphql/base/page/data_field/cross_reference.rb +54 -0
  156. data/lib/ecoportal/api/graphql/base/page/data_field/date_field.rb +23 -0
  157. data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +25 -0
  158. data/lib/ecoportal/api/graphql/base/page/data_field/gauge.rb +19 -0
  159. data/lib/ecoportal/api/graphql/base/page/data_field/geo.rb +24 -0
  160. data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +24 -0
  161. data/lib/ecoportal/api/graphql/base/page/data_field/law.rb +8 -0
  162. data/lib/ecoportal/api/graphql/base/page/data_field/mailbox.rb +9 -0
  163. data/lib/ecoportal/api/graphql/base/page/data_field/number.rb +20 -0
  164. data/lib/ecoportal/api/graphql/base/page/data_field/people.rb +35 -0
  165. data/lib/ecoportal/api/graphql/base/page/data_field/plain_text.rb +17 -0
  166. data/lib/ecoportal/api/graphql/base/page/data_field/rich_text.rb +26 -0
  167. data/lib/ecoportal/api/graphql/base/page/data_field/select.rb +41 -0
  168. data/lib/ecoportal/api/graphql/base/page/data_field/signature.rb +9 -0
  169. data/lib/ecoportal/api/graphql/base/page/data_field/smart_fill.rb +17 -0
  170. data/lib/ecoportal/api/graphql/base/page/data_field/table.rb +9 -0
  171. data/lib/ecoportal/api/graphql/base/page/data_field/tag_field.rb +21 -0
  172. data/lib/ecoportal/api/graphql/base/page/data_field.rb +137 -12
  173. data/lib/ecoportal/api/graphql/base/page/phased/stage.rb +68 -14
  174. data/lib/ecoportal/api/graphql/base/page/phased.rb +1 -0
  175. data/lib/ecoportal/api/graphql/base/page/section.rb +36 -0
  176. data/lib/ecoportal/api/graphql/base/page/section_collection.rb +79 -0
  177. data/lib/ecoportal/api/graphql/base/page.rb +2 -0
  178. data/lib/ecoportal/api/graphql/base/pages_workflow/action_type_selection.rb +17 -0
  179. data/lib/ecoportal/api/graphql/base/pages_workflow/callback_type.rb +28 -0
  180. data/lib/ecoportal/api/graphql/base/pages_workflow/command_change.rb +17 -0
  181. data/lib/ecoportal/api/graphql/base/pages_workflow/command_change_message.rb +15 -0
  182. data/lib/ecoportal/api/graphql/base/pages_workflow/command_es_change.rb +17 -0
  183. data/lib/ecoportal/api/graphql/base/pages_workflow/command_interface.rb +36 -0
  184. data/lib/ecoportal/api/graphql/base/pages_workflow/email_config.rb +18 -0
  185. data/lib/ecoportal/api/graphql/base/pages_workflow/escalation_level.rb +19 -0
  186. data/lib/ecoportal/api/graphql/base/pages_workflow/in_system_config.rb +16 -0
  187. data/lib/ecoportal/api/graphql/base/pages_workflow/mailbox_field_selection.rb +17 -0
  188. data/lib/ecoportal/api/graphql/base/pages_workflow/operation_interface.rb +39 -0
  189. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/assign_to.rb +27 -0
  190. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/create_page.rb +21 -0
  191. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/send_notification.rb +30 -0
  192. data/lib/ecoportal/api/graphql/base/pages_workflow/people_field_selection.rb +17 -0
  193. data/lib/ecoportal/api/graphql/base/pages_workflow/recipient_config.rb +34 -0
  194. data/lib/ecoportal/api/graphql/base/pages_workflow/register_field.rb +17 -0
  195. data/lib/ecoportal/api/graphql/base/pages_workflow/task_config_selection.rb +17 -0
  196. data/lib/ecoportal/api/graphql/base/pages_workflow/time_delay_config.rb +16 -0
  197. data/lib/ecoportal/api/graphql/base/pages_workflow/trigger_interface.rb +26 -0
  198. data/lib/ecoportal/api/graphql/base/pages_workflow/triggers/conditional_logic.rb +17 -0
  199. data/lib/ecoportal/api/graphql/base/pages_workflow/user_selection.rb +16 -0
  200. data/lib/ecoportal/api/graphql/base/pages_workflow.rb +35 -0
  201. data/lib/ecoportal/api/graphql/base/preset_view.rb +17 -0
  202. data/lib/ecoportal/api/graphql/base/preview_page.rb +23 -0
  203. data/lib/ecoportal/api/graphql/base/register.rb +18 -0
  204. data/lib/ecoportal/api/graphql/base.rb +11 -0
  205. data/lib/ecoportal/api/graphql/builder/CLAUDE.md +65 -0
  206. data/lib/ecoportal/api/graphql/builder/kickstand.rb +73 -0
  207. data/lib/ecoportal/api/graphql/builder/page.rb +210 -41
  208. data/lib/ecoportal/api/graphql/builder/register/preset_view.rb +84 -0
  209. data/lib/ecoportal/api/graphql/builder/register.rb +27 -19
  210. data/lib/ecoportal/api/graphql/builder/template.rb +80 -0
  211. data/lib/ecoportal/api/graphql/builder.rb +2 -0
  212. data/lib/ecoportal/api/graphql/compat/filter_translator.rb +107 -0
  213. data/lib/ecoportal/api/graphql/compat/page_reference.rb +23 -0
  214. data/lib/ecoportal/api/graphql/compat/pages.rb +212 -0
  215. data/lib/ecoportal/api/graphql/compat/registers.rb +84 -0
  216. data/lib/ecoportal/api/graphql/compat/response.rb +35 -0
  217. data/lib/ecoportal/api/graphql/compat/search_results.rb +33 -0
  218. data/lib/ecoportal/api/graphql/compat/stage_collection.rb +70 -0
  219. data/lib/ecoportal/api/graphql/compat/stage_view.rb +76 -0
  220. data/lib/ecoportal/api/graphql/compat.rb +17 -0
  221. data/lib/ecoportal/api/graphql/concerns/data_field_access.rb +71 -0
  222. data/lib/ecoportal/api/graphql/concerns/deprecation.rb +20 -0
  223. data/lib/ecoportal/api/graphql/concerns/fragment_definitions.rb +21 -28
  224. data/lib/ecoportal/api/graphql/concerns/page_compat.rb +51 -0
  225. data/lib/ecoportal/api/graphql/concerns/snake_camel_access.rb +60 -0
  226. data/lib/ecoportal/api/graphql/concerns.rb +4 -0
  227. data/lib/ecoportal/api/graphql/connection/page.rb +11 -0
  228. data/lib/ecoportal/api/graphql/connection/pages_workflow_command.rb +13 -0
  229. data/lib/ecoportal/api/graphql/connection/preset_view.rb +11 -0
  230. data/lib/ecoportal/api/graphql/connection/preview_page.rb +11 -0
  231. data/lib/ecoportal/api/graphql/connection.rb +4 -0
  232. data/lib/ecoportal/api/graphql/file_upload/client.rb +181 -0
  233. data/lib/ecoportal/api/graphql/file_upload.rb +10 -0
  234. data/lib/ecoportal/api/graphql/fragment/action.rb +1 -1
  235. data/lib/ecoportal/api/graphql/fragment/action_category.rb +1 -1
  236. data/lib/ecoportal/api/graphql/fragment/contractor_entity.rb +1 -1
  237. data/lib/ecoportal/api/graphql/fragment/force.rb +30 -0
  238. data/lib/ecoportal/api/graphql/fragment/location_draft.rb +2 -2
  239. data/lib/ecoportal/api/graphql/fragment/location_node.rb +1 -1
  240. data/lib/ecoportal/api/graphql/fragment/locations_error.rb +1 -1
  241. data/lib/ecoportal/api/graphql/fragment/page.rb +85 -0
  242. data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +395 -0
  243. data/lib/ecoportal/api/graphql/fragment/pages.rb +15 -0
  244. data/lib/ecoportal/api/graphql/fragment/pages_workflow.rb +172 -0
  245. data/lib/ecoportal/api/graphql/fragment/pagination.rb +1 -1
  246. data/lib/ecoportal/api/graphql/fragment.rb +37 -27
  247. data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +25 -0
  248. data/lib/ecoportal/api/graphql/input/delta_input.rb +16 -0
  249. data/lib/ecoportal/api/graphql/input/page/archive.rb +14 -0
  250. data/lib/ecoportal/api/graphql/input/page/build_from_template.rb +13 -0
  251. data/lib/ecoportal/api/graphql/input/page/create_draft.rb +13 -0
  252. data/lib/ecoportal/api/graphql/input/page/create_from_template.rb +18 -0
  253. data/lib/ecoportal/api/graphql/input/page/delete_draft.rb +13 -0
  254. data/lib/ecoportal/api/graphql/input/page/publish_draft.rb +13 -0
  255. data/lib/ecoportal/api/graphql/input/page/review_task.rb +14 -0
  256. data/lib/ecoportal/api/graphql/input/page/unarchive.rb +14 -0
  257. data/lib/ecoportal/api/graphql/input/page/update.rb +140 -0
  258. data/lib/ecoportal/api/graphql/input/page.rb +26 -0
  259. data/lib/ecoportal/api/graphql/input/preset_view/create.rb +18 -0
  260. data/lib/ecoportal/api/graphql/input/preset_view/permission.rb +16 -0
  261. data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -0
  262. data/lib/ecoportal/api/graphql/input/preset_view.rb +14 -0
  263. data/lib/ecoportal/api/graphql/input/register/create.rb +18 -0
  264. data/lib/ecoportal/api/graphql/input/register/update.rb +15 -0
  265. data/lib/ecoportal/api/graphql/input/register.rb +13 -0
  266. data/lib/ecoportal/api/graphql/input/search_conf/ai_generator.rb +234 -0
  267. data/lib/ecoportal/api/graphql/input/search_conf.rb +367 -0
  268. data/lib/ecoportal/api/graphql/input/variable_binding.rb +20 -0
  269. data/lib/ecoportal/api/graphql/input/workflow_command/add_action_tag.rb +18 -0
  270. data/lib/ecoportal/api/graphql/input/workflow_command/add_binding.rb +18 -0
  271. data/lib/ecoportal/api/graphql/input/workflow_command/add_comment_tagging_user_group.rb +18 -0
  272. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_direct_strategy_user.rb +18 -0
  273. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_strategy.rb +18 -0
  274. data/lib/ecoportal/api/graphql/input/workflow_command/add_direct_strategy_user.rb +18 -0
  275. data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +18 -0
  276. data/lib/ecoportal/api/graphql/input/workflow_command/add_force.rb +18 -0
  277. data/lib/ecoportal/api/graphql/input/workflow_command/add_gauge_field_stop.rb +19 -0
  278. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_field_config.rb +23 -0
  279. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_helper.rb +18 -0
  280. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation.rb +18 -0
  281. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_direct_strategy_user.rb +18 -0
  282. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_strategy.rb +18 -0
  283. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_action_type.rb +18 -0
  284. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_filter.rb +18 -0
  285. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_people_field.rb +18 -0
  286. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_task_config.rb +18 -0
  287. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_user.rb +18 -0
  288. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback.rb +23 -0
  289. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback_action.rb +18 -0
  290. data/lib/ecoportal/api/graphql/input/workflow_command/add_section.rb +18 -0
  291. data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +19 -0
  292. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +18 -0
  293. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_section.rb +18 -0
  294. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_tag.rb +18 -0
  295. data/lib/ecoportal/api/graphql/input/workflow_command/add_strategy.rb +18 -0
  296. data/lib/ecoportal/api/graphql/input/workflow_command/add_task.rb +18 -0
  297. data/lib/ecoportal/api/graphql/input/workflow_command/add_task_assignment_user_group.rb +18 -0
  298. data/lib/ecoportal/api/graphql/input/workflow_command/add_workflow_callback.rb +18 -0
  299. data/lib/ecoportal/api/graphql/input/workflow_command/collapse_section.rb +18 -0
  300. data/lib/ecoportal/api/graphql/input/workflow_command/edit_binding.rb +18 -0
  301. data/lib/ecoportal/api/graphql/input/workflow_command/edit_creator_permissions.rb +18 -0
  302. data/lib/ecoportal/api/graphql/input/workflow_command/edit_default_strategy.rb +18 -0
  303. data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +21 -0
  304. data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +18 -0
  305. data/lib/ecoportal/api/graphql/input/workflow_command/edit_gauge_field_stop.rb +19 -0
  306. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_field_config.rb +19 -0
  307. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_helper.rb +18 -0
  308. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation.rb +18 -0
  309. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation_strategy.rb +18 -0
  310. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +28 -0
  311. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page_creator_permissions.rb +18 -0
  312. data/lib/ecoportal/api/graphql/input/workflow_command/edit_reminder.rb +18 -0
  313. data/lib/ecoportal/api/graphql/input/workflow_command/edit_required_sign_offs.rb +18 -0
  314. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_comment_tagging.rb +18 -0
  315. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_task_assignment.rb +18 -0
  316. data/lib/ecoportal/api/graphql/input/workflow_command/edit_scheduled_callback.rb +22 -0
  317. data/lib/ecoportal/api/graphql/input/workflow_command/edit_section_header.rb +18 -0
  318. data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +19 -0
  319. data/lib/ecoportal/api/graphql/input/workflow_command/edit_stage.rb +18 -0
  320. data/lib/ecoportal/api/graphql/input/workflow_command/edit_strategy.rb +18 -0
  321. data/lib/ecoportal/api/graphql/input/workflow_command/edit_task_due.rb +18 -0
  322. data/lib/ecoportal/api/graphql/input/workflow_command/edit_trigger.rb +18 -0
  323. data/lib/ecoportal/api/graphql/input/workflow_command/expand_section.rb +18 -0
  324. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/contractor_entities.rb +24 -0
  325. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +23 -0
  326. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +20 -0
  327. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/gauge.rb +20 -0
  328. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +20 -0
  329. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/location_field.rb +24 -0
  330. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +24 -0
  331. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +20 -0
  332. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +20 -0
  333. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +20 -0
  334. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/signature.rb +20 -0
  335. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb +25 -0
  336. data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +18 -0
  337. data/lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb +18 -0
  338. data/lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb +18 -0
  339. data/lib/ecoportal/api/graphql/input/workflow_command/remove_binding.rb +18 -0
  340. data/lib/ecoportal/api/graphql/input/workflow_command/remove_callback.rb +18 -0
  341. data/lib/ecoportal/api/graphql/input/workflow_command/remove_comment_tagging_user_group.rb +18 -0
  342. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_direct_strategy_user.rb +18 -0
  343. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_strategy.rb +18 -0
  344. data/lib/ecoportal/api/graphql/input/workflow_command/remove_direct_strategy_user.rb +18 -0
  345. data/lib/ecoportal/api/graphql/input/workflow_command/remove_field.rb +18 -0
  346. data/lib/ecoportal/api/graphql/input/workflow_command/remove_force.rb +18 -0
  347. data/lib/ecoportal/api/graphql/input/workflow_command/remove_gauge_field_stop.rb +17 -0
  348. data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_field_config.rb +17 -0
  349. data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_helper.rb +18 -0
  350. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation.rb +18 -0
  351. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_direct_strategy_user.rb +18 -0
  352. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_strategy.rb +18 -0
  353. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_action_type.rb +18 -0
  354. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_filter.rb +18 -0
  355. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_people_field.rb +18 -0
  356. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_task_config.rb +18 -0
  357. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_user.rb +18 -0
  358. data/lib/ecoportal/api/graphql/input/workflow_command/remove_scheduled_callback.rb +18 -0
  359. data/lib/ecoportal/api/graphql/input/workflow_command/remove_section.rb +18 -0
  360. data/lib/ecoportal/api/graphql/input/workflow_command/remove_select_field_option.rb +17 -0
  361. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage.rb +18 -0
  362. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_section.rb +18 -0
  363. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_tag.rb +18 -0
  364. data/lib/ecoportal/api/graphql/input/workflow_command/remove_strategy.rb +18 -0
  365. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task.rb +18 -0
  366. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_assignment_user_group.rb +18 -0
  367. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_due.rb +18 -0
  368. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_priority_level.rb +18 -0
  369. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +18 -0
  370. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +18 -0
  371. data/lib/ecoportal/api/graphql/input/workflow_command.rb +251 -0
  372. data/lib/ecoportal/api/graphql/input.rb +8 -0
  373. data/lib/ecoportal/api/graphql/interface/base_page.rb +100 -58
  374. data/lib/ecoportal/api/graphql/interface/location_structure/nodes.rb +27 -28
  375. data/lib/ecoportal/api/graphql/logic/base_model.rb +2 -0
  376. data/lib/ecoportal/api/graphql/logic/base_query.rb +45 -2
  377. data/lib/ecoportal/api/graphql/logic/input.rb +15 -0
  378. data/lib/ecoportal/api/graphql/model/ai_summary_version.rb +10 -0
  379. data/lib/ecoportal/api/graphql/model/organization.rb +65 -55
  380. data/lib/ecoportal/api/graphql/model/page/basic.rb +14 -0
  381. data/lib/ecoportal/api/graphql/model/page/phased.rb +82 -20
  382. data/lib/ecoportal/api/graphql/model/page.rb +1 -0
  383. data/lib/ecoportal/api/graphql/model/page_union.rb +21 -0
  384. data/lib/ecoportal/api/graphql/model/pages_workflow.rb +20 -0
  385. data/lib/ecoportal/api/graphql/model/preset_view.rb +10 -0
  386. data/lib/ecoportal/api/graphql/model/preview_page.rb +10 -0
  387. data/lib/ecoportal/api/graphql/model/register.rb +10 -0
  388. data/lib/ecoportal/api/graphql/model.rb +8 -0
  389. data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +45 -0
  390. data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +40 -0
  391. data/lib/ecoportal/api/graphql/mutation/ai_summary.rb +13 -0
  392. data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_jobs.rb +43 -0
  393. data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_workflows.rb +43 -0
  394. data/lib/ecoportal/api/graphql/mutation/kickstand/fail_job.rb +39 -0
  395. data/lib/ecoportal/api/graphql/mutation/kickstand/fail_workflow.rb +39 -0
  396. data/lib/ecoportal/api/graphql/mutation/kickstand/start_job.rb +39 -0
  397. data/lib/ecoportal/api/graphql/mutation/kickstand/start_workflow.rb +39 -0
  398. data/lib/ecoportal/api/graphql/mutation/kickstand/stop_workflow.rb +39 -0
  399. data/lib/ecoportal/api/graphql/mutation/kickstand.rb +18 -0
  400. data/lib/ecoportal/api/graphql/mutation/location_structure/apply_commands.rb +3 -3
  401. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/add_commands.rb +2 -2
  402. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/create.rb +2 -2
  403. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/drop_bad_commands.rb +3 -3
  404. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/publish.rb +3 -3
  405. data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +40 -0
  406. data/lib/ecoportal/api/graphql/mutation/page/archive.rb +40 -0
  407. data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +40 -0
  408. data/lib/ecoportal/api/graphql/mutation/page/build_from_template.rb +50 -0
  409. data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +40 -0
  410. data/lib/ecoportal/api/graphql/mutation/page/create_from_template.rb +43 -0
  411. data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +40 -0
  412. data/lib/ecoportal/api/graphql/mutation/page/execute_force_commands.rb +69 -0
  413. data/lib/ecoportal/api/graphql/mutation/page/execute_workflow_commands.rb +51 -0
  414. data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +40 -0
  415. data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +40 -0
  416. data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +40 -0
  417. data/lib/ecoportal/api/graphql/mutation/page/unarchive.rb +40 -0
  418. data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +40 -0
  419. data/lib/ecoportal/api/graphql/mutation/page/update.rb +40 -0
  420. data/lib/ecoportal/api/graphql/mutation/page/update_variable_bindings.rb +44 -0
  421. data/lib/ecoportal/api/graphql/mutation/page.rb +28 -0
  422. data/lib/ecoportal/api/graphql/mutation/preset_view/create.rb +35 -0
  423. data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +35 -0
  424. data/lib/ecoportal/api/graphql/mutation/preset_view/permission.rb +37 -0
  425. data/lib/ecoportal/api/graphql/mutation/preset_view/update.rb +35 -0
  426. data/lib/ecoportal/api/graphql/mutation/preset_view.rb +15 -0
  427. data/lib/ecoportal/api/graphql/mutation/register/create.rb +35 -0
  428. data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +35 -0
  429. data/lib/ecoportal/api/graphql/mutation/register/update.rb +35 -0
  430. data/lib/ecoportal/api/graphql/mutation/register.rb +14 -0
  431. data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +36 -0
  432. data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +40 -0
  433. data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +13 -0
  434. data/lib/ecoportal/api/graphql/mutation/template/create.rb +39 -0
  435. data/lib/ecoportal/api/graphql/mutation/template/create_related_page.rb +46 -0
  436. data/lib/ecoportal/api/graphql/mutation/template/destroy_related_page.rb +43 -0
  437. data/lib/ecoportal/api/graphql/mutation/template/publish.rb +39 -0
  438. data/lib/ecoportal/api/graphql/mutation/template/unpublish.rb +39 -0
  439. data/lib/ecoportal/api/graphql/mutation/template/update.rb +43 -0
  440. data/lib/ecoportal/api/graphql/mutation/template/update_information.rb +43 -0
  441. data/lib/ecoportal/api/graphql/mutation/template.rb +18 -0
  442. data/lib/ecoportal/api/graphql/mutation.rb +8 -0
  443. data/lib/ecoportal/api/graphql/payload/ai_summary_generate.rb +12 -0
  444. data/lib/ecoportal/api/graphql/payload/execute_workflow_commands.rb +36 -0
  445. data/lib/ecoportal/api/graphql/payload/force_commands.rb +31 -0
  446. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_jobs.rb +36 -0
  447. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_workflows.rb +36 -0
  448. data/lib/ecoportal/api/graphql/payload/kickstand/job.rb +13 -0
  449. data/lib/ecoportal/api/graphql/payload/kickstand/workflow.rb +13 -0
  450. data/lib/ecoportal/api/graphql/payload/kickstand.rb +15 -0
  451. data/lib/ecoportal/api/graphql/payload/location_structure/draft/create.rb +33 -34
  452. data/lib/ecoportal/api/graphql/payload/ok_payload.rb +21 -0
  453. data/lib/ecoportal/api/graphql/payload/page/archive.rb +13 -0
  454. data/lib/ecoportal/api/graphql/payload/page/build_from_template.rb +13 -0
  455. data/lib/ecoportal/api/graphql/payload/page/create_from_template.rb +13 -0
  456. data/lib/ecoportal/api/graphql/payload/page/draft.rb +13 -0
  457. data/lib/ecoportal/api/graphql/payload/page/review_task.rb +13 -0
  458. data/lib/ecoportal/api/graphql/payload/page/unarchive.rb +13 -0
  459. data/lib/ecoportal/api/graphql/payload/page/update.rb +13 -0
  460. data/lib/ecoportal/api/graphql/payload/page/update_variable_bindings.rb +13 -0
  461. data/lib/ecoportal/api/graphql/payload/page.rb +19 -0
  462. data/lib/ecoportal/api/graphql/payload/preset_view.rb +11 -0
  463. data/lib/ecoportal/api/graphql/payload/register.rb +11 -0
  464. data/lib/ecoportal/api/graphql/payload/template/create.rb +13 -0
  465. data/lib/ecoportal/api/graphql/payload/template/create_related_page.rb +13 -0
  466. data/lib/ecoportal/api/graphql/payload/template/destroy_related_page.rb +13 -0
  467. data/lib/ecoportal/api/graphql/payload/template/publish.rb +13 -0
  468. data/lib/ecoportal/api/graphql/payload/template/unpublish.rb +13 -0
  469. data/lib/ecoportal/api/graphql/payload/template/update.rb +13 -0
  470. data/lib/ecoportal/api/graphql/payload/template/update_information.rb +13 -0
  471. data/lib/ecoportal/api/graphql/payload/template.rb +18 -0
  472. data/lib/ecoportal/api/graphql/payload.rb +11 -0
  473. data/lib/ecoportal/api/graphql/query/action.rb +1 -1
  474. data/lib/ecoportal/api/graphql/query/action_categories.rb +1 -1
  475. data/lib/ecoportal/api/graphql/query/actions.rb +2 -2
  476. data/lib/ecoportal/api/graphql/query/contractor_entities.rb +1 -1
  477. data/lib/ecoportal/api/graphql/query/file_upload_signature.rb +76 -0
  478. data/lib/ecoportal/api/graphql/query/location_structure/draft.rb +2 -2
  479. data/lib/ecoportal/api/graphql/query/location_structure.rb +1 -1
  480. data/lib/ecoportal/api/graphql/query/location_structures.rb +1 -1
  481. data/lib/ecoportal/api/graphql/query/page.rb +45 -0
  482. data/lib/ecoportal/api/graphql/query/page_delta.rb +47 -0
  483. data/lib/ecoportal/api/graphql/query/page_with_forces.rb +43 -0
  484. data/lib/ecoportal/api/graphql/query/pages.rb +59 -0
  485. data/lib/ecoportal/api/graphql/query/pages_workflow_commands.rb +59 -0
  486. data/lib/ecoportal/api/graphql/query/register_preset_views.rb +78 -0
  487. data/lib/ecoportal/api/graphql/query/register_preview_pages.rb +83 -0
  488. data/lib/ecoportal/api/graphql/query/templates.rb +53 -0
  489. data/lib/ecoportal/api/graphql/query.rb +11 -0
  490. data/lib/ecoportal/api/graphql.rb +60 -2
  491. data/lib/ecoportal/api/graphql_version.rb +5 -5
  492. data/scripts/auto-worker-scheduler.sh +386 -0
  493. data/tests/contractor_entity_create.rb +19 -19
  494. data/tests/contractor_entity_udpate.rb +20 -20
  495. data/tests/dump_page_model.rb +74 -0
  496. data/tests/loc_structure_get.rb +1 -2
  497. data/tests/loc_structure_update.rb +51 -51
  498. data/tests/loc_structures_get.rb +15 -15
  499. metadata +436 -5
@@ -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(%r{^(test|spec|features)/})
22
- end
23
- spec.bindir = 'exe'
24
- spec.executables = spec.files.grep(%r{^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.15'
36
- spec.add_dependency 'ecoportal-api-v2', '~> 3.3', '>= 3.3.1'
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`
@@ -6,7 +6,7 @@ module Ecoportal
6
6
  class Client < ::Graphlient::Client
7
7
  ENDPOINT_PATH = 'external/graphql'.freeze
8
8
 
9
- attr_accessor :host
9
+ attr_accessor :host, :http_client
10
10
 
11
11
  READ_TIMEOUT = 90
12
12
  WRITE_TIMEOUT = 90
@@ -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,6 +15,7 @@ module Ecoportal
13
15
  end
14
16
  end
15
17
 
18
+ ENDPOINT_PATH = 'external/graphql'.freeze
16
19
  READ_TIMEOUT = 90
17
20
  WRITE_TIMEOUT = 90
18
21
 
@@ -58,8 +61,9 @@ module Ecoportal
58
61
  when 'v2', 'v3'
59
62
  HTTP.headers('X-ECOPORTAL-API-KEY' => key_token)
60
63
  when 'graphql'
61
- HTTP.headers('Authorization' => "Bearer #{key_token}")
64
+ HTTP.headers('Authorization' => "Bearer #{session_token(host: host)}")
62
65
  end.then do |request|
66
+ request ||= HTTP
63
67
  request.accept(:json).timeout(
64
68
  read: READ_TIMEOUT,
65
69
  write: WRITE_TIMEOUT
@@ -71,6 +75,20 @@ module Ecoportal
71
75
  @org_id || fetch_env_required('ORGANIZATION_ID')
72
76
  end
73
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
+
74
92
  # Full URl builder of the request
75
93
  # @param path [String] the tail that completes the url of the request.
76
94
  # @return [String] the final url.
@@ -91,8 +109,8 @@ module Ecoportal
91
109
 
92
110
  def api_url
93
111
  base_url.then do |url|
94
- next "#{url}/api/#{version}" if v1_0? || v2_3?
95
- next "#{url}/api/#{org_id}/graphql" if graphql?
112
+ next "#{url}/api/#{version}" if v1_0? || v2_3?
113
+ next "#{url}/api/#{org_id}/#{ENDPOINT_PATH}" if graphql?
96
114
 
97
115
  url
98
116
  end
@@ -138,6 +156,20 @@ module Ecoportal
138
156
  def graphql?
139
157
  @version == 'graphql'
140
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
+ )
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
172
+ end
141
173
  end
142
174
  end
143
175
  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
- self.class.as_input(
42
- as_update,
43
- clientMutationId: clientMutationId
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, flat: flat?)
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
- change_diff(
39
- curr_doc(flat: flat),
40
- prev_doc(flat: flat),
41
- ignore: to_a(ignored, ignore)
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 = {}, ignore: [])
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? # first iteration already done
55
- next result if obj == subject # first call had done it (same as above: path relative)
59
+ next result if key_path.empty?
60
+ next result if obj == subject
56
61
 
57
- dig_delete!(result, key_path) if dig_path?(result, key_path)
62
+ sym_path = key_path.map(&:to_sym)
58
63
 
59
- # discard rooted (i.e. read_only) objects from the diff.
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
- next result unless dig_path?(result, key_path)
62
- next result unless obj.respond_to?(:as_update)
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
- dig_set!(
67
- result,
68
- key_path,
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
- return false unless obj.respond_to?(:root?)
151
-
152
- obj.root?
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 unless (excluded = subject._cascaded_doc_keys)
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? {|item| item.is_a?(Array)}
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
@@ -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