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.
Files changed (513) 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 -470
  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/auth_service.rb +12 -14
  132. data/lib/ecoportal/api/common/graphql/client.rb +11 -3
  133. data/lib/ecoportal/api/common/graphql/http_client.rb +117 -29
  134. data/lib/ecoportal/api/common/graphql/model/CLAUDE.md +28 -0
  135. data/lib/ecoportal/api/common/graphql/model/as_input.rb +8 -5
  136. data/lib/ecoportal/api/common/graphql/model/diffable/classic_diff_service.rb +3 -1
  137. data/lib/ecoportal/api/common/graphql/model/diffable/diff_service.rb +31 -23
  138. data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff_nesting.rb +54 -1
  139. data/lib/ecoportal/api/common/graphql.rb +1 -1
  140. data/lib/ecoportal/api/graphql/CLAUDE.md +37 -0
  141. data/lib/ecoportal/api/graphql/base/CLAUDE.md +50 -0
  142. data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +17 -0
  143. data/lib/ecoportal/api/graphql/base/delta_result.rb +16 -0
  144. data/lib/ecoportal/api/graphql/base/force/binding.rb +19 -0
  145. data/lib/ecoportal/api/graphql/base/force/binding_collection.rb +62 -0
  146. data/lib/ecoportal/api/graphql/base/force/collection.rb +47 -0
  147. data/lib/ecoportal/api/graphql/base/force.rb +65 -0
  148. data/lib/ecoportal/api/graphql/base/kickstand/job.rb +17 -0
  149. data/lib/ecoportal/api/graphql/base/kickstand/workflow.rb +18 -0
  150. data/lib/ecoportal/api/graphql/base/kickstand.rb +13 -0
  151. data/lib/ecoportal/api/graphql/base/page/basic.rb +38 -0
  152. data/lib/ecoportal/api/graphql/base/page/data_field/actions_list.rb +9 -0
  153. data/lib/ecoportal/api/graphql/base/page/data_field/ai_summary.rb +18 -0
  154. data/lib/ecoportal/api/graphql/base/page/data_field/checklist.rb +29 -0
  155. data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +112 -0
  156. data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +28 -0
  157. data/lib/ecoportal/api/graphql/base/page/data_field/cross_reference.rb +54 -0
  158. data/lib/ecoportal/api/graphql/base/page/data_field/date_field.rb +23 -0
  159. data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +25 -0
  160. data/lib/ecoportal/api/graphql/base/page/data_field/gauge.rb +19 -0
  161. data/lib/ecoportal/api/graphql/base/page/data_field/geo.rb +24 -0
  162. data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +24 -0
  163. data/lib/ecoportal/api/graphql/base/page/data_field/law.rb +8 -0
  164. data/lib/ecoportal/api/graphql/base/page/data_field/mailbox.rb +9 -0
  165. data/lib/ecoportal/api/graphql/base/page/data_field/number.rb +20 -0
  166. data/lib/ecoportal/api/graphql/base/page/data_field/people.rb +35 -0
  167. data/lib/ecoportal/api/graphql/base/page/data_field/plain_text.rb +17 -0
  168. data/lib/ecoportal/api/graphql/base/page/data_field/rich_text.rb +26 -0
  169. data/lib/ecoportal/api/graphql/base/page/data_field/select.rb +41 -0
  170. data/lib/ecoportal/api/graphql/base/page/data_field/signature.rb +9 -0
  171. data/lib/ecoportal/api/graphql/base/page/data_field/smart_fill.rb +17 -0
  172. data/lib/ecoportal/api/graphql/base/page/data_field/table.rb +9 -0
  173. data/lib/ecoportal/api/graphql/base/page/data_field/tag_field.rb +21 -0
  174. data/lib/ecoportal/api/graphql/base/page/data_field.rb +137 -0
  175. data/lib/ecoportal/api/graphql/base/page/phased/stage.rb +68 -0
  176. data/lib/ecoportal/api/graphql/base/page/phased.rb +15 -0
  177. data/lib/ecoportal/api/graphql/base/page/section.rb +48 -0
  178. data/lib/ecoportal/api/graphql/base/page/section_collection.rb +79 -0
  179. data/lib/ecoportal/api/graphql/base/page.rb +7 -1
  180. data/lib/ecoportal/api/graphql/base/pages_workflow/action_type_selection.rb +17 -0
  181. data/lib/ecoportal/api/graphql/base/pages_workflow/callback_type.rb +28 -0
  182. data/lib/ecoportal/api/graphql/base/pages_workflow/command_change.rb +17 -0
  183. data/lib/ecoportal/api/graphql/base/pages_workflow/command_change_message.rb +15 -0
  184. data/lib/ecoportal/api/graphql/base/pages_workflow/command_es_change.rb +17 -0
  185. data/lib/ecoportal/api/graphql/base/pages_workflow/command_interface.rb +36 -0
  186. data/lib/ecoportal/api/graphql/base/pages_workflow/email_config.rb +18 -0
  187. data/lib/ecoportal/api/graphql/base/pages_workflow/escalation_level.rb +19 -0
  188. data/lib/ecoportal/api/graphql/base/pages_workflow/in_system_config.rb +16 -0
  189. data/lib/ecoportal/api/graphql/base/pages_workflow/mailbox_field_selection.rb +17 -0
  190. data/lib/ecoportal/api/graphql/base/pages_workflow/operation_interface.rb +39 -0
  191. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/assign_to.rb +27 -0
  192. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/create_page.rb +21 -0
  193. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/send_notification.rb +30 -0
  194. data/lib/ecoportal/api/graphql/base/pages_workflow/people_field_selection.rb +17 -0
  195. data/lib/ecoportal/api/graphql/base/pages_workflow/recipient_config.rb +34 -0
  196. data/lib/ecoportal/api/graphql/base/pages_workflow/register_field.rb +17 -0
  197. data/lib/ecoportal/api/graphql/base/pages_workflow/task_config_selection.rb +17 -0
  198. data/lib/ecoportal/api/graphql/base/pages_workflow/time_delay_config.rb +16 -0
  199. data/lib/ecoportal/api/graphql/base/pages_workflow/trigger_interface.rb +26 -0
  200. data/lib/ecoportal/api/graphql/base/pages_workflow/triggers/conditional_logic.rb +17 -0
  201. data/lib/ecoportal/api/graphql/base/pages_workflow/user_selection.rb +16 -0
  202. data/lib/ecoportal/api/graphql/base/pages_workflow.rb +35 -0
  203. data/lib/ecoportal/api/graphql/base/preset_view.rb +17 -0
  204. data/lib/ecoportal/api/graphql/base/preview_page.rb +23 -0
  205. data/lib/ecoportal/api/graphql/base/register.rb +18 -0
  206. data/lib/ecoportal/api/graphql/base.rb +26 -15
  207. data/lib/ecoportal/api/graphql/builder/CLAUDE.md +65 -0
  208. data/lib/ecoportal/api/graphql/builder/kickstand.rb +73 -0
  209. data/lib/ecoportal/api/graphql/builder/page.rb +210 -0
  210. data/lib/ecoportal/api/graphql/builder/register/preset_view.rb +84 -0
  211. data/lib/ecoportal/api/graphql/builder/register.rb +49 -0
  212. data/lib/ecoportal/api/graphql/builder/template.rb +80 -0
  213. data/lib/ecoportal/api/graphql/builder.rb +7 -3
  214. data/lib/ecoportal/api/graphql/compat/filter_translator.rb +107 -0
  215. data/lib/ecoportal/api/graphql/compat/page_reference.rb +23 -0
  216. data/lib/ecoportal/api/graphql/compat/pages.rb +212 -0
  217. data/lib/ecoportal/api/graphql/compat/registers.rb +84 -0
  218. data/lib/ecoportal/api/graphql/compat/response.rb +35 -0
  219. data/lib/ecoportal/api/graphql/compat/search_results.rb +33 -0
  220. data/lib/ecoportal/api/graphql/compat/stage_collection.rb +70 -0
  221. data/lib/ecoportal/api/graphql/compat/stage_view.rb +76 -0
  222. data/lib/ecoportal/api/graphql/compat.rb +17 -0
  223. data/lib/ecoportal/api/graphql/concerns/data_field_access.rb +71 -0
  224. data/lib/ecoportal/api/graphql/concerns/deprecation.rb +20 -0
  225. data/lib/ecoportal/api/graphql/concerns/fragment_definitions.rb +68 -0
  226. data/lib/ecoportal/api/graphql/concerns/page_compat.rb +51 -0
  227. data/lib/ecoportal/api/graphql/concerns/snake_camel_access.rb +60 -0
  228. data/lib/ecoportal/api/graphql/concerns.rb +14 -0
  229. data/lib/ecoportal/api/graphql/connection/page.rb +11 -0
  230. data/lib/ecoportal/api/graphql/connection/pages_workflow_command.rb +13 -0
  231. data/lib/ecoportal/api/graphql/connection/preset_view.rb +11 -0
  232. data/lib/ecoportal/api/graphql/connection/preview_page.rb +11 -0
  233. data/lib/ecoportal/api/graphql/connection.rb +8 -4
  234. data/lib/ecoportal/api/graphql/error.rb +3 -3
  235. data/lib/ecoportal/api/graphql/file_upload/client.rb +181 -0
  236. data/lib/ecoportal/api/graphql/file_upload.rb +10 -0
  237. data/lib/ecoportal/api/graphql/fragment/action.rb +1 -1
  238. data/lib/ecoportal/api/graphql/fragment/action_category.rb +1 -1
  239. data/lib/ecoportal/api/graphql/fragment/contractor_entity.rb +1 -1
  240. data/lib/ecoportal/api/graphql/fragment/force.rb +30 -0
  241. data/lib/ecoportal/api/graphql/fragment/location_draft.rb +2 -2
  242. data/lib/ecoportal/api/graphql/fragment/location_node.rb +1 -1
  243. data/lib/ecoportal/api/graphql/fragment/locations_error.rb +1 -1
  244. data/lib/ecoportal/api/graphql/fragment/page.rb +85 -0
  245. data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +395 -0
  246. data/lib/ecoportal/api/graphql/fragment/pages.rb +15 -0
  247. data/lib/ecoportal/api/graphql/fragment/pages_workflow.rb +172 -0
  248. data/lib/ecoportal/api/graphql/fragment/pagination.rb +1 -1
  249. data/lib/ecoportal/api/graphql/fragment.rb +37 -71
  250. data/lib/ecoportal/api/graphql/helpers/locations_tree.rb +1 -0
  251. data/lib/ecoportal/api/graphql/helpers.rb +1 -1
  252. data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +25 -0
  253. data/lib/ecoportal/api/graphql/input/delta_input.rb +16 -0
  254. data/lib/ecoportal/api/graphql/input/page/archive.rb +14 -0
  255. data/lib/ecoportal/api/graphql/input/page/build_from_template.rb +13 -0
  256. data/lib/ecoportal/api/graphql/input/page/create_draft.rb +13 -0
  257. data/lib/ecoportal/api/graphql/input/page/create_from_template.rb +18 -0
  258. data/lib/ecoportal/api/graphql/input/page/delete_draft.rb +13 -0
  259. data/lib/ecoportal/api/graphql/input/page/publish_draft.rb +13 -0
  260. data/lib/ecoportal/api/graphql/input/page/review_task.rb +14 -0
  261. data/lib/ecoportal/api/graphql/input/page/unarchive.rb +14 -0
  262. data/lib/ecoportal/api/graphql/input/page/update.rb +140 -0
  263. data/lib/ecoportal/api/graphql/input/page.rb +26 -0
  264. data/lib/ecoportal/api/graphql/input/preset_view/create.rb +18 -0
  265. data/lib/ecoportal/api/graphql/input/preset_view/permission.rb +16 -0
  266. data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -0
  267. data/lib/ecoportal/api/graphql/input/preset_view.rb +14 -0
  268. data/lib/ecoportal/api/graphql/input/register/create.rb +18 -0
  269. data/lib/ecoportal/api/graphql/input/register/update.rb +15 -0
  270. data/lib/ecoportal/api/graphql/input/register.rb +13 -0
  271. data/lib/ecoportal/api/graphql/input/search_conf/ai_generator.rb +234 -0
  272. data/lib/ecoportal/api/graphql/input/search_conf.rb +367 -0
  273. data/lib/ecoportal/api/graphql/input/variable_binding.rb +20 -0
  274. data/lib/ecoportal/api/graphql/input/workflow_command/add_action_tag.rb +18 -0
  275. data/lib/ecoportal/api/graphql/input/workflow_command/add_binding.rb +18 -0
  276. data/lib/ecoportal/api/graphql/input/workflow_command/add_comment_tagging_user_group.rb +18 -0
  277. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_direct_strategy_user.rb +18 -0
  278. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_strategy.rb +18 -0
  279. data/lib/ecoportal/api/graphql/input/workflow_command/add_direct_strategy_user.rb +18 -0
  280. data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +18 -0
  281. data/lib/ecoportal/api/graphql/input/workflow_command/add_force.rb +18 -0
  282. data/lib/ecoportal/api/graphql/input/workflow_command/add_gauge_field_stop.rb +19 -0
  283. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_field_config.rb +23 -0
  284. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_helper.rb +18 -0
  285. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation.rb +18 -0
  286. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_direct_strategy_user.rb +18 -0
  287. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_strategy.rb +18 -0
  288. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_action_type.rb +18 -0
  289. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_filter.rb +18 -0
  290. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_people_field.rb +18 -0
  291. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_task_config.rb +18 -0
  292. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_user.rb +18 -0
  293. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback.rb +23 -0
  294. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback_action.rb +18 -0
  295. data/lib/ecoportal/api/graphql/input/workflow_command/add_section.rb +18 -0
  296. data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +19 -0
  297. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +18 -0
  298. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_section.rb +18 -0
  299. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_tag.rb +18 -0
  300. data/lib/ecoportal/api/graphql/input/workflow_command/add_strategy.rb +18 -0
  301. data/lib/ecoportal/api/graphql/input/workflow_command/add_task.rb +18 -0
  302. data/lib/ecoportal/api/graphql/input/workflow_command/add_task_assignment_user_group.rb +18 -0
  303. data/lib/ecoportal/api/graphql/input/workflow_command/add_workflow_callback.rb +18 -0
  304. data/lib/ecoportal/api/graphql/input/workflow_command/collapse_section.rb +18 -0
  305. data/lib/ecoportal/api/graphql/input/workflow_command/edit_binding.rb +18 -0
  306. data/lib/ecoportal/api/graphql/input/workflow_command/edit_creator_permissions.rb +18 -0
  307. data/lib/ecoportal/api/graphql/input/workflow_command/edit_default_strategy.rb +18 -0
  308. data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +21 -0
  309. data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +18 -0
  310. data/lib/ecoportal/api/graphql/input/workflow_command/edit_gauge_field_stop.rb +19 -0
  311. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_field_config.rb +19 -0
  312. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_helper.rb +18 -0
  313. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation.rb +18 -0
  314. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation_strategy.rb +18 -0
  315. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +28 -0
  316. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page_creator_permissions.rb +18 -0
  317. data/lib/ecoportal/api/graphql/input/workflow_command/edit_reminder.rb +18 -0
  318. data/lib/ecoportal/api/graphql/input/workflow_command/edit_required_sign_offs.rb +18 -0
  319. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_comment_tagging.rb +18 -0
  320. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_task_assignment.rb +18 -0
  321. data/lib/ecoportal/api/graphql/input/workflow_command/edit_scheduled_callback.rb +22 -0
  322. data/lib/ecoportal/api/graphql/input/workflow_command/edit_section_header.rb +18 -0
  323. data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +19 -0
  324. data/lib/ecoportal/api/graphql/input/workflow_command/edit_stage.rb +18 -0
  325. data/lib/ecoportal/api/graphql/input/workflow_command/edit_strategy.rb +18 -0
  326. data/lib/ecoportal/api/graphql/input/workflow_command/edit_task_due.rb +18 -0
  327. data/lib/ecoportal/api/graphql/input/workflow_command/edit_trigger.rb +18 -0
  328. data/lib/ecoportal/api/graphql/input/workflow_command/expand_section.rb +18 -0
  329. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/contractor_entities.rb +24 -0
  330. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +23 -0
  331. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +20 -0
  332. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/gauge.rb +20 -0
  333. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +20 -0
  334. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/location_field.rb +24 -0
  335. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +24 -0
  336. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +20 -0
  337. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +20 -0
  338. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +20 -0
  339. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/signature.rb +20 -0
  340. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb +25 -0
  341. data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +18 -0
  342. data/lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb +18 -0
  343. data/lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb +18 -0
  344. data/lib/ecoportal/api/graphql/input/workflow_command/remove_binding.rb +18 -0
  345. data/lib/ecoportal/api/graphql/input/workflow_command/remove_callback.rb +18 -0
  346. data/lib/ecoportal/api/graphql/input/workflow_command/remove_comment_tagging_user_group.rb +18 -0
  347. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_direct_strategy_user.rb +18 -0
  348. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_strategy.rb +18 -0
  349. data/lib/ecoportal/api/graphql/input/workflow_command/remove_direct_strategy_user.rb +18 -0
  350. data/lib/ecoportal/api/graphql/input/workflow_command/remove_field.rb +18 -0
  351. data/lib/ecoportal/api/graphql/input/workflow_command/remove_force.rb +18 -0
  352. data/lib/ecoportal/api/graphql/input/workflow_command/remove_gauge_field_stop.rb +17 -0
  353. data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_field_config.rb +17 -0
  354. data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_helper.rb +18 -0
  355. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation.rb +18 -0
  356. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_direct_strategy_user.rb +18 -0
  357. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_strategy.rb +18 -0
  358. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_action_type.rb +18 -0
  359. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_filter.rb +18 -0
  360. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_people_field.rb +18 -0
  361. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_task_config.rb +18 -0
  362. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_user.rb +18 -0
  363. data/lib/ecoportal/api/graphql/input/workflow_command/remove_scheduled_callback.rb +18 -0
  364. data/lib/ecoportal/api/graphql/input/workflow_command/remove_section.rb +18 -0
  365. data/lib/ecoportal/api/graphql/input/workflow_command/remove_select_field_option.rb +17 -0
  366. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage.rb +18 -0
  367. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_section.rb +18 -0
  368. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_tag.rb +18 -0
  369. data/lib/ecoportal/api/graphql/input/workflow_command/remove_strategy.rb +18 -0
  370. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task.rb +18 -0
  371. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_assignment_user_group.rb +18 -0
  372. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_due.rb +18 -0
  373. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_priority_level.rb +18 -0
  374. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +18 -0
  375. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +18 -0
  376. data/lib/ecoportal/api/graphql/input/workflow_command.rb +251 -0
  377. data/lib/ecoportal/api/graphql/input.rb +15 -7
  378. data/lib/ecoportal/api/graphql/interface/base_page.rb +100 -58
  379. data/lib/ecoportal/api/graphql/interface/location_structure/nodes.rb +27 -28
  380. data/lib/ecoportal/api/graphql/logic/base_model.rb +2 -0
  381. data/lib/ecoportal/api/graphql/logic/base_query.rb +45 -2
  382. data/lib/ecoportal/api/graphql/logic/input.rb +15 -0
  383. data/lib/ecoportal/api/graphql/logic/mutation.rb +6 -1
  384. data/lib/ecoportal/api/graphql/logic/query_array.rb +1 -0
  385. data/lib/ecoportal/api/graphql/logic/query_connection.rb +2 -0
  386. data/lib/ecoportal/api/graphql/logic.rb +9 -9
  387. data/lib/ecoportal/api/graphql/model/ai_summary_version.rb +10 -0
  388. data/lib/ecoportal/api/graphql/model/organization.rb +65 -52
  389. data/lib/ecoportal/api/graphql/model/page/basic.rb +14 -0
  390. data/lib/ecoportal/api/graphql/model/page/data_field.rb +12 -0
  391. data/lib/ecoportal/api/graphql/model/page/phased/stage.rb +14 -0
  392. data/lib/ecoportal/api/graphql/model/page/phased.rb +82 -0
  393. data/lib/ecoportal/api/graphql/model/page/section.rb +12 -0
  394. data/lib/ecoportal/api/graphql/model/page.rb +6 -7
  395. data/lib/ecoportal/api/graphql/model/page_union.rb +21 -0
  396. data/lib/ecoportal/api/graphql/model/pages_workflow.rb +20 -0
  397. data/lib/ecoportal/api/graphql/model/preset_view.rb +10 -0
  398. data/lib/ecoportal/api/graphql/model/preview_page.rb +10 -0
  399. data/lib/ecoportal/api/graphql/model/register.rb +10 -0
  400. data/lib/ecoportal/api/graphql/model/resource.rb +1 -1
  401. data/lib/ecoportal/api/graphql/model.rb +21 -13
  402. data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +45 -0
  403. data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +40 -0
  404. data/lib/ecoportal/api/graphql/mutation/ai_summary.rb +13 -0
  405. data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_jobs.rb +43 -0
  406. data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_workflows.rb +43 -0
  407. data/lib/ecoportal/api/graphql/mutation/kickstand/fail_job.rb +39 -0
  408. data/lib/ecoportal/api/graphql/mutation/kickstand/fail_workflow.rb +39 -0
  409. data/lib/ecoportal/api/graphql/mutation/kickstand/start_job.rb +39 -0
  410. data/lib/ecoportal/api/graphql/mutation/kickstand/start_workflow.rb +39 -0
  411. data/lib/ecoportal/api/graphql/mutation/kickstand/stop_workflow.rb +39 -0
  412. data/lib/ecoportal/api/graphql/mutation/kickstand.rb +18 -0
  413. data/lib/ecoportal/api/graphql/mutation/location_structure/apply_commands.rb +3 -3
  414. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/add_commands.rb +2 -2
  415. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/create.rb +2 -2
  416. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/drop_bad_commands.rb +3 -3
  417. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/publish.rb +3 -3
  418. data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +40 -0
  419. data/lib/ecoportal/api/graphql/mutation/page/archive.rb +40 -0
  420. data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +40 -0
  421. data/lib/ecoportal/api/graphql/mutation/page/build_from_template.rb +50 -0
  422. data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +40 -0
  423. data/lib/ecoportal/api/graphql/mutation/page/create_from_template.rb +43 -0
  424. data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +40 -0
  425. data/lib/ecoportal/api/graphql/mutation/page/execute_force_commands.rb +69 -0
  426. data/lib/ecoportal/api/graphql/mutation/page/execute_workflow_commands.rb +51 -0
  427. data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +40 -0
  428. data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +40 -0
  429. data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +40 -0
  430. data/lib/ecoportal/api/graphql/mutation/page/unarchive.rb +40 -0
  431. data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +40 -0
  432. data/lib/ecoportal/api/graphql/mutation/page/update.rb +40 -0
  433. data/lib/ecoportal/api/graphql/mutation/page/update_variable_bindings.rb +44 -0
  434. data/lib/ecoportal/api/graphql/mutation/page.rb +28 -0
  435. data/lib/ecoportal/api/graphql/mutation/preset_view/create.rb +35 -0
  436. data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +35 -0
  437. data/lib/ecoportal/api/graphql/mutation/preset_view/permission.rb +37 -0
  438. data/lib/ecoportal/api/graphql/mutation/preset_view/update.rb +35 -0
  439. data/lib/ecoportal/api/graphql/mutation/preset_view.rb +15 -0
  440. data/lib/ecoportal/api/graphql/mutation/register/create.rb +35 -0
  441. data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +35 -0
  442. data/lib/ecoportal/api/graphql/mutation/register/update.rb +35 -0
  443. data/lib/ecoportal/api/graphql/mutation/register.rb +14 -0
  444. data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +36 -0
  445. data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +40 -0
  446. data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +13 -0
  447. data/lib/ecoportal/api/graphql/mutation/template/create.rb +39 -0
  448. data/lib/ecoportal/api/graphql/mutation/template/create_related_page.rb +46 -0
  449. data/lib/ecoportal/api/graphql/mutation/template/destroy_related_page.rb +43 -0
  450. data/lib/ecoportal/api/graphql/mutation/template/publish.rb +39 -0
  451. data/lib/ecoportal/api/graphql/mutation/template/unpublish.rb +39 -0
  452. data/lib/ecoportal/api/graphql/mutation/template/update.rb +43 -0
  453. data/lib/ecoportal/api/graphql/mutation/template/update_information.rb +43 -0
  454. data/lib/ecoportal/api/graphql/mutation/template.rb +18 -0
  455. data/lib/ecoportal/api/graphql/mutation.rb +11 -3
  456. data/lib/ecoportal/api/graphql/payload/ai_summary_generate.rb +12 -0
  457. data/lib/ecoportal/api/graphql/payload/execute_workflow_commands.rb +36 -0
  458. data/lib/ecoportal/api/graphql/payload/force_commands.rb +31 -0
  459. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_jobs.rb +36 -0
  460. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_workflows.rb +36 -0
  461. data/lib/ecoportal/api/graphql/payload/kickstand/job.rb +13 -0
  462. data/lib/ecoportal/api/graphql/payload/kickstand/workflow.rb +13 -0
  463. data/lib/ecoportal/api/graphql/payload/kickstand.rb +15 -0
  464. data/lib/ecoportal/api/graphql/payload/location_structure/draft/create.rb +33 -34
  465. data/lib/ecoportal/api/graphql/payload/ok_payload.rb +21 -0
  466. data/lib/ecoportal/api/graphql/payload/page/archive.rb +13 -0
  467. data/lib/ecoportal/api/graphql/payload/page/build_from_template.rb +13 -0
  468. data/lib/ecoportal/api/graphql/payload/page/create_from_template.rb +13 -0
  469. data/lib/ecoportal/api/graphql/payload/page/draft.rb +13 -0
  470. data/lib/ecoportal/api/graphql/payload/page/review_task.rb +13 -0
  471. data/lib/ecoportal/api/graphql/payload/page/unarchive.rb +13 -0
  472. data/lib/ecoportal/api/graphql/payload/page/update.rb +13 -0
  473. data/lib/ecoportal/api/graphql/payload/page/update_variable_bindings.rb +13 -0
  474. data/lib/ecoportal/api/graphql/payload/page.rb +19 -0
  475. data/lib/ecoportal/api/graphql/payload/preset_view.rb +11 -0
  476. data/lib/ecoportal/api/graphql/payload/register.rb +11 -0
  477. data/lib/ecoportal/api/graphql/payload/template/create.rb +13 -0
  478. data/lib/ecoportal/api/graphql/payload/template/create_related_page.rb +13 -0
  479. data/lib/ecoportal/api/graphql/payload/template/destroy_related_page.rb +13 -0
  480. data/lib/ecoportal/api/graphql/payload/template/publish.rb +13 -0
  481. data/lib/ecoportal/api/graphql/payload/template/unpublish.rb +13 -0
  482. data/lib/ecoportal/api/graphql/payload/template/update.rb +13 -0
  483. data/lib/ecoportal/api/graphql/payload/template/update_information.rb +13 -0
  484. data/lib/ecoportal/api/graphql/payload/template.rb +18 -0
  485. data/lib/ecoportal/api/graphql/payload.rb +14 -3
  486. data/lib/ecoportal/api/graphql/query/action.rb +1 -1
  487. data/lib/ecoportal/api/graphql/query/action_categories.rb +2 -1
  488. data/lib/ecoportal/api/graphql/query/actions.rb +2 -2
  489. data/lib/ecoportal/api/graphql/query/contractor_entities.rb +2 -1
  490. data/lib/ecoportal/api/graphql/query/file_upload_signature.rb +76 -0
  491. data/lib/ecoportal/api/graphql/query/location_structure/draft.rb +2 -2
  492. data/lib/ecoportal/api/graphql/query/location_structure.rb +1 -1
  493. data/lib/ecoportal/api/graphql/query/location_structures.rb +1 -1
  494. data/lib/ecoportal/api/graphql/query/page.rb +45 -0
  495. data/lib/ecoportal/api/graphql/query/page_delta.rb +47 -0
  496. data/lib/ecoportal/api/graphql/query/page_with_forces.rb +43 -0
  497. data/lib/ecoportal/api/graphql/query/pages.rb +59 -0
  498. data/lib/ecoportal/api/graphql/query/pages_workflow_commands.rb +59 -0
  499. data/lib/ecoportal/api/graphql/query/register_preset_views.rb +78 -0
  500. data/lib/ecoportal/api/graphql/query/register_preview_pages.rb +83 -0
  501. data/lib/ecoportal/api/graphql/query/templates.rb +53 -0
  502. data/lib/ecoportal/api/graphql/query.rb +18 -7
  503. data/lib/ecoportal/api/graphql.rb +70 -2
  504. data/lib/ecoportal/api/graphql_version.rb +5 -5
  505. data/scripts/auto-worker-scheduler.sh +386 -0
  506. data/tests/contractor_entity_create.rb +19 -19
  507. data/tests/contractor_entity_udpate.rb +20 -20
  508. data/tests/dump_page_model.rb +74 -0
  509. data/tests/loc_structure_get.rb +1 -2
  510. data/tests/loc_structure_update.rb +51 -51
  511. data/tests/loc_structures_get.rb +15 -15
  512. data/tests/local_libs.rb +7 -7
  513. 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,13 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Base
5
+ module Kickstand
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ require_relative 'kickstand/workflow'
13
+ require_relative 'kickstand/job'
@@ -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