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
@@ -0,0 +1,196 @@
1
+ # EcoPortal People, Contractors, and Locations
2
+
3
+ ---
4
+
5
+ ## People (PersonMember)
6
+
7
+ ### GraphQL Type
8
+
9
+ `PersonMember` — represents a user in the ecoPortal platform.
10
+
11
+ Key fields: `id`, `name`, `email`, `externalId`, `archived`, `publicFields`, `privateFields`,
12
+ `supervisor_id`, `organizationHierarchy`
13
+
14
+ ### Query
15
+
16
+ ```graphql
17
+ query GetPeople($filters: [SearchFilter!], $includeArchived: Boolean) {
18
+ currentOrganization {
19
+ personMembers(
20
+ first: 20,
21
+ includeArchived: $includeArchived,
22
+ searchConf: {
23
+ filters: $filters,
24
+ sorters: [{ key: "created_at", direction: "desc" }]
25
+ }
26
+ ) {
27
+ totalCount
28
+ pageInfo { hasNextPage endCursor }
29
+ nodes { id name email externalId publicFields privateFields }
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ ### Finding a Person by externalId
36
+
37
+ ```json
38
+ {
39
+ "filters": [
40
+ { "operation": "exact_filter", "params": { "key": "external_id", "value": "FRODO" } }
41
+ ]
42
+ }
43
+ ```
44
+
45
+ Note: The `searchConf` for `personMembers` uses the ARRAY format for `filters` and
46
+ sorters use `key:` not `fieldName:`.
47
+
48
+ ---
49
+
50
+ ## Contractor Entities
51
+
52
+ ### GraphQL Type
53
+
54
+ `ContractorEntity` — represents an external contractor/supplier in the system.
55
+
56
+ Key fields: `id`, `externalId`, `name`, `schemaId`, `active`, `approved`,
57
+ `associatedPeopleIds`, `leadContractorIds`
58
+
59
+ ### Query
60
+
61
+ ```graphql
62
+ query Contractors($searchConf: Search) {
63
+ currentOrganization {
64
+ contractorEntities(searchConf: $searchConf) {
65
+ totalCount
66
+ nodes { id externalId name active approved associatedPeopleIds leadContractorIds }
67
+ pageInfo { endCursor hasNextPage }
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Find by externalId
74
+
75
+ ```json
76
+ { "searchConf": { "filters": [{ "operation": "exact_filter", "params": { "key": "external_id", "value": "9429041280072" } }] } }
77
+ ```
78
+
79
+ ### Update: IdDiffInput Pattern
80
+
81
+ Contractor's `associatedPeopleIds` and `leadContractorIds` use the **IdDiff pattern**
82
+ for updates — instead of sending the full array, send additions and removals:
83
+
84
+ ```json
85
+ {
86
+ "associatedPeopleIds": { "additions": ["new_person_id"], "removals": ["old_person_id"] }
87
+ }
88
+ ```
89
+
90
+ **Gem class:** `Input::ContractorEntity::Update` handles this via `from_model`
91
+ which reads `doc` vs `original_doc` to compute the diff.
92
+
93
+ ### Mutations
94
+
95
+ ```graphql
96
+ mutation CreateContractor($input: CreateContractorEntityInput!) {
97
+ createContractorEntity(input: $input) {
98
+ item { id externalId name schemaId active approved associatedPeopleIds leadContractorIds }
99
+ errors { details fullMessages }
100
+ }
101
+ }
102
+
103
+ mutation UpdateContractor($input: UpdateContractorEntityInput!) {
104
+ updateContractorEntity(input: $input) {
105
+ item { ... }
106
+ errors { ... }
107
+ }
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Location Structure (Reporting Structure / RS)
114
+
115
+ ### Concept
116
+
117
+ The location structure is a hierarchical tree used to tag pages and scope analytics.
118
+ Also called "Reporting Structure" (RS) internally.
119
+
120
+ Used for:
121
+ - Assigning pages to locations/departments (`locations: [LocationNodeInterface]`)
122
+ - Filtering searches by location (`location_ids` filter)
123
+ - Analytics and dashboard scoping
124
+ - Permission scoping (some permissions are location-based)
125
+
126
+ ### GraphQL Access
127
+
128
+ ```graphql
129
+ query GetLocationStructure($id: ID!) {
130
+ currentOrganization {
131
+ locationStructure(id: $id) {
132
+ id name
133
+ nodes {
134
+ id name weight archived
135
+ classifications { name }
136
+ ancestors { id name }
137
+ }
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ ### Draft-Based Edits
144
+
145
+ Location structure changes go through a **draft** system:
146
+ 1. `createLocationDraft(...)` — create an edit draft
147
+ 2. Apply commands: `insertNode`, `moveNode`, `archiveNode`, `renameNode`, etc.
148
+ 3. `publishDraft(...)` — apply to production
149
+
150
+ This is the most complex part of the GraphQL API. The gem has full coverage in
151
+ `Mutation::LocationStructure::Draft::*` and `Input::LocationStructure::Draft::*`.
152
+
153
+ ### LocationNode Type
154
+
155
+ ```graphql
156
+ type LocationNodeInterface {
157
+ id: ID!
158
+ name: String!
159
+ weight: Int!
160
+ archived: Boolean!
161
+ archivedToken: ID
162
+ parent: LocationNodeInterface
163
+ children: [LocationNodeInterface!]!
164
+ classifications: [LocationClassificationType!]!
165
+ ancestors: [LocationNodeInterface!]!
166
+ }
167
+ ```
168
+
169
+ ### TagField (Location Picker Data Field)
170
+
171
+ `TagField` on a page is the location tag input. It stores `locations: [LocationNodeInterface]`
172
+ — the selected location nodes for that field. Multiple pages can have different location
173
+ tags from the same RS tree.
174
+
175
+ ---
176
+
177
+ ## IdDiff Pattern
178
+
179
+ Used whenever an array relationship is updated. Instead of sending the full new array,
180
+ send only what changed:
181
+
182
+ ```graphql
183
+ input IdDiffInput {
184
+ additions: [ID!]!
185
+ removals: [ID!]!
186
+ }
187
+ ```
188
+
189
+ Used in:
190
+ - `ContractorEntity` `associatedPeopleIds` and `leadContractorIds` updates
191
+ - Potentially other relationship updates
192
+
193
+ **Gem support:**
194
+ - `Input::IdDiff` — the input class
195
+ - `Input::ContractorEntity::Update.from_model` — auto-computes additions/removals
196
+ from `doc` vs `original_doc` comparison
@@ -0,0 +1,132 @@
1
+ # EcoPortal Forces and Workflow Builder
2
+
3
+ ---
4
+
5
+ ## Forces (Legacy Front-End Snippets — Being Replaced)
6
+
7
+ ### What They Are
8
+
9
+ Forces are AngularJS embedded code snippets that are attached to pages and stages.
10
+ They implement **conditional field behaviour** — things like:
11
+ - Show/hide sections based on field values
12
+ - Compute risk ratings (e.g. `likelihood × severity = risk_score`)
13
+ - Fill gauge values based on select field selections
14
+ - Conditional required field logic
15
+
16
+ ### How They Attach
17
+
18
+ Forces have **bindings** — connections to specific fields and sections within a stage.
19
+ A force appears in the front-end on a specific stage only if ALL its bindings are
20
+ present in that stage (the bound fields and sections exist in that stage).
21
+
22
+ ### Technical Details
23
+
24
+ - Backend: `Force` type in GraphQL (`id`, `name`, `script`, `bindings`, `globalBindings`)
25
+ - Front-end: AngularJS components embedded in the stage view
26
+
27
+ ### Forces on GraphQL — CORRECTED (verified, Oscar + code, 2026-07-01)
28
+
29
+ > ⚠️ An earlier version of this doc (2026-06-09) claimed forces were "not yet scriptable —
30
+ > blocked until a dedicated legacy-forces GraphQL endpoint lands." **That was wrong**, and it
31
+ > persisted because the fact below was only ever captured in machine-local memory. There is no
32
+ > separate "forces endpoint" — forces are managed through the **WorkflowCommandInput command-bus**,
33
+ > the same imperative mechanism used for all template/workflow edits. Full root-cause:
34
+ > `.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-07-01-forces-via-workflow-commands-miss-rca.md`.
35
+
36
+ **MUTATING forces — AVAILABLE NOW.** Done via `Workflow*` commands (`WorkflowAddForceInput`,
37
+ `WorkflowEditForceInput`, `WorkflowRemoveForceInput`, `reorderForces`, `addBinding`/`editBinding`/
38
+ `removeBinding`) submitted through `executeWorkflowCommands`. The gem already ships this:
39
+ - Inputs: `lib/ecoportal/api/graphql/input/workflow_command/{add_force,edit_force,remove_force,reorder_forces,add_binding}.rb`
40
+ - Wiring: `input/workflow_command.rb`; mutation `mutation/page/execute_workflow_commands.rb`
41
+ - Model: `base/force.rb` queues `editForce` / `addBinding` commands
42
+ - eco-helpers: `OozeRedirect::ForceCompat#save_force_changes!` already submits them via
43
+ `graphql.page.execute_force_commands` → `executeWorkflowCommands` (the "to-be-built" sketch was
44
+ already built).
45
+
46
+ **READING forces on a page — the only WIP part.** `Query::PageWithForces` (used by
47
+ `ForceCompat#with_each_entry`) currently fails client-side schema validation (PageUnion selections,
48
+ `id` on binding types). This is the genuinely-blocked piece.
49
+
50
+ **Why scripts still appear "blocked":** `OozeRedirect.force_support?` hard-returns `false`, gating
51
+ read AND write together — so the broken READ disables the working WRITE as collateral. Correcting
52
+ it means splitting the gate (enable writes; gate only the `PageWithForces` fetch) and/or fixing the
53
+ read query. Until then the ~20 force-dependent ooze scripts stay off, but they are **not**
54
+ fundamentally blocked — the write path exists.
55
+
56
+ **Scripts interact with forces as in v2** (the compat API is real, not a sketch):
57
+ `force.custom_script = new_script` (→ `editForce`), `force.bindings.add(...)` (→ `addBinding`),
58
+ `force.bindings.delete!(...)` (→ `removeBinding`); commands accumulate and submit in one
59
+ `executeWorkflowCommands` call after `process_ooze`.
60
+
61
+ ### Status
62
+
63
+ **Forces are being replaced** by the Workflow Builder. New templates should use Workflow Builder
64
+ instead of Forces. Existing templates with Forces continue to work and are now editable via the
65
+ command-bus (above).
66
+
67
+ ---
68
+
69
+ ## Workflow Builder (`PagesWorkflow`)
70
+
71
+ ### What It Is
72
+
73
+ The Workflow Builder is the replacement for Forces. It provides server-side (and
74
+ eventually client-side via React) automation configuration for pages.
75
+
76
+ ### Currently Deployed Features
77
+
78
+ | Feature | Status |
79
+ |---------|--------|
80
+ | Automated notifications | ✅ Deployed |
81
+ | Automated page creation | ✅ Deployed (from workflow triggers) |
82
+ | Task assignments | ✅ Deployed (per workflow rules) |
83
+ | Conditional field/section workflows | 🔄 In development |
84
+ | Custom computed values (risk matrices) | 🔄 In development |
85
+
86
+ ### Conditional Field Workflows (Not Yet Deployed)
87
+
88
+ This is the AngularJS Forces replacement. Will enable:
89
+ - Show/hide sections based on field values
90
+ - Computed gauge values from select + number field matrices
91
+ - Conditional required fields
92
+ - Section visibility rules
93
+
94
+ **Why it matters for scripting:** Once deployed, the server may automatically
95
+ update field values or show/hide sections when a page is updated. Scripts that
96
+ update a field may trigger downstream Workflow Builder effects server-side.
97
+
98
+ ### Recent Status (2026-06-07)
99
+
100
+ The Workflow Builder was recently refactored. New customers have it deployed for
101
+ their templates. Engineering is doing quick fixes via CI/CD. The Workflow Builder
102
+ API is **not stable enough for scripting against its internals** — use the standard
103
+ `updatePage` mutation and let the server trigger workflow effects as side effects.
104
+
105
+ ### GraphQL Access
106
+
107
+ The `PagesWorkflow` type is queryable, and its mutations **ARE covered in this gem** — via the
108
+ `WorkflowCommandInput` command-bus (~80 command types under `input/workflow_command/`, applied by
109
+ `executeWorkflowCommands`). This is the imperative mechanism for editing workflows, forces, stages,
110
+ sections, fields, strategies, operations, recipients, etc. (NOT a diff-based update). Key types:
111
+
112
+ - `PagesWorkflow` — the workflow configuration attached to a register
113
+ - `PagesWorkflowCallbackType` — triggers and operations
114
+ - `PagesWorkflowCommandInterface` — commands that were executed
115
+ - `PagesWorkflowOperationsCreatePage` — auto-create operation
116
+ - `PagesWorkflowOperationsAssignTo` — task assignment operation
117
+ - `PagesWorkflowOperationsSendNotification` — notification operation
118
+
119
+ The command-bus (`input/workflow_command/*.rb` + `mutation/page/execute_workflow_commands.rb`) is
120
+ the same machinery the templates-maintenance project builds on. The API is volatile — design for
121
+ change. (Earlier "not covered in this gem" was wrong — corrected 2026-07-01 alongside the forces fix.)
122
+
123
+ ### Task Side Effects of `updatePage`
124
+
125
+ When submitting a stage (`submit: true` in `updatePage`), the server may:
126
+ 1. Create/assign a `ReviewPage` or `CompletePage` task for the next stage
127
+ 2. Create related pages (if workflow has auto-create configured)
128
+ 3. Send notifications to relevant users
129
+ 4. Trigger time-delay operations for future tasks
130
+
131
+ Scripts should check mutation payloads for errors but should NOT attempt to manually
132
+ manage workflow state — the server handles it.
@@ -0,0 +1,187 @@
1
+ # EcoPortal Integration Gem Stack
2
+
3
+ ---
4
+
5
+ ## Dependency Chain
6
+
7
+ ```
8
+ [graphql-ruby] [graphql-client] [graphlient (forked)] (upstream, external/forked)
9
+
10
+ ecoportal-api / ecoportal-api-v2 (upstream, team-managed)
11
+
12
+ ecoportal-api-graphql ← THIS REPO
13
+
14
+ eco-helpers (downstream, team-managed)
15
+ ```
16
+
17
+ ---
18
+
19
+ ## graphlient (Forked)
20
+
21
+ **Purpose:** GraphQL DSL for building and executing queries.
22
+ **Fork:** `C:\ruby_scripts\git\graphlient` (Oscar's fork of `ashkan18/graphlient`)
23
+ **Branch:** `feature/dsl-only-mode`
24
+
25
+ **Custom additions to the fork:**
26
+ - `Client#to_query_string(&block)` — builds a full query document from the DSL block
27
+ and returns a `String` WITHOUT touching Faraday/HTTP. Keystone for the schema-less
28
+ dispatch mode.
29
+ - `Query#spread(name)` — DSL helper that emits `...FragmentName` in the query string.
30
+ Replaced the `___Ecoportal__API__GraphQL__Fragment__X` convention from graphql-client.
31
+
32
+ ---
33
+
34
+ ## ecoportal-api (Upstream)
35
+
36
+ **Purpose:** Core base models, auth, content model, base HTTP client.
37
+ **Local path:** `C:\ruby_scripts\git\ecoportal-api`
38
+
39
+ Provides:
40
+ - `Ecoportal::API::Common::BaseModel` — base model with passthrough, passkey, etc.
41
+ - `Ecoportal::API::Common::Content::DoubleModel` — dirty tracking base
42
+ - `Ecoportal::API::Common::BaseClass` — class_resolver, resolve_class DSL
43
+ - `Ecoportal::API::Common::GraphQL::AuthService` — OAuth authentication
44
+ - `Ecoportal::API::Common::GraphQL::HashHelpers` — deep_dup, etc.
45
+
46
+ ---
47
+
48
+ ## ecoportal-api-v2 (Upstream, Being Retired)
49
+
50
+ **Purpose:** REST API v2 client gem (Page, Register, PersonMember, etc.)
51
+ **Local path:** `C:\ruby_scripts\git\ecoportal-api-v2`
52
+
53
+ Key things to look for in the source:
54
+ - `Ecoportal::API::Common::Content::StringDigest` — Field ID / ref formula
55
+ - `HashDiffPatch` — the diff algorithm the GraphQL gem adapted
56
+ - `passthrough`, `passarray`, `passboolean`, `passdate` DSL macros
57
+ - Page model with `.as_update` and dirty tracking
58
+
59
+ ---
60
+
61
+ ## ecoportal-api-graphql (THIS GEM)
62
+
63
+ **Local path:** `C:\ruby_scripts\git\ecoportal-api-graphql`
64
+ **Branch:** `pages` (primary development branch)
65
+
66
+ ### Namespace Structure
67
+
68
+ ```
69
+ Ecoportal::API::GraphQL::
70
+ Logic:: Base classes (BaseModel, BaseQuery, Query, Mutation, etc.)
71
+ Common:: Shared utilities (DiffService, HashHelpers, etc.)
72
+ Interface:: GraphQL interfaces (BasePage, LocationStructure)
73
+ Base:: Concrete base model classes (Page::Basic, Page::Phased, DataField::*)
74
+ Model:: Domain model classes (inherits from Base::, adds resolvers)
75
+ Fragment:: GraphQL fragment definitions
76
+ Fragment::Pages Sub-namespace for customer-facing fragments (CommonPageUnion)
77
+ Connection:: Connection classes for paginated results
78
+ Query:: Query classes (Page, Pages, Templates, RegisterPreviewPages, etc.)
79
+ Mutation:: Mutation classes (Page::Update, Page::Archive, etc.)
80
+ Payload:: Mutation payload classes
81
+ Input:: Input object classes (Page::Update, SearchConf, DeltaInput, etc.)
82
+ Builder:: Builder pattern (Page, Action, ContractorEntity, LocationStructure)
83
+ Compat:: v2 compatibility layer (Pages, Registers, StageView, StageCollection, etc.)
84
+ Concerns:: Shared modules (PageCompat, DataFieldAccess, SnakeCamelAccess, etc.)
85
+ ```
86
+
87
+ ### Key Conventions
88
+
89
+ **passthrough vs passboolean vs passdate vs passarray:**
90
+ All macros from ecoportal-api that create read/write accessors:
91
+ - `passthrough :externalId` → `def externalId; doc['externalId']; end` + setter
92
+ - `passboolean :archived` → same but returns `true/false` cast
93
+ - `passdate :createdAt` → same but wraps in DateTime model
94
+ - `passarray :stages` → returns Array from doc
95
+
96
+ **SnakeCamelAccess concern:** Included in `Logic::BaseModel`. All GraphQL model objects
97
+ respond to snake_case versions of camelCase methods via `method_missing`:
98
+ - `page.external_id` → `page.externalId`
99
+ - `page.patch_ver` → `page.patchVer`
100
+ - `page.source_template_id` → `page.sourceTemplateId`
101
+ - `page.time_zone = 'UTC'` → `page.timeZone = 'UTC'`
102
+
103
+ **class_resolver pattern:** Used to lazily resolve class references (avoids circular
104
+ requires):
105
+ ```ruby
106
+ class_resolver :item_class, 'Ecoportal::API::GraphQL::Model::PageUnion'
107
+ ```
108
+ `resolve_class` accepts String (const_get), Symbol (send), or Class.
109
+
110
+ **Fragment assembly:** `BaseQuery#assemble_fragments` recursively scans query strings
111
+ for `...FragmentName` spreads and appends all needed fragment definitions. Fragment
112
+ sub-namespaces registered via `Fragment.register_namespace(klass)`.
113
+
114
+ ### eco-helpers Compat Layer
115
+
116
+ ```
117
+ Compat::Pages — graphql.pages (matches apiv2.pages interface)
118
+ Compat::Registers — graphql.registers (matches apiv2.registers interface)
119
+ Compat::StageView — page view filtered to one stage (matches v2 stage fetch)
120
+ Compat::StageCollection — stages[name], get_by_name, ordered
121
+ Compat::SearchResults — .total, .total_before_filtering
122
+ Compat::PageReference — .page_id, .active_stage_id
123
+ Compat::Response — .success?, .status, .body
124
+ ```
125
+
126
+ **Concerns included in Interface::BasePage (all page models):**
127
+ - `PageCompat` — v2 method aliases (external_id, template_id, components, stages?, consolidate!, dirty?, validate)
128
+ - `DataFieldAccess` — components, sections, field_collection, section_collection, data_fields_updates, data_fields_additions
129
+ - `SnakeCamelAccess` — camelCase→snake_case method delegation
130
+
131
+ **Data field types with full read/write:**
132
+ PlainText, RichText, DateField, Number, Gauge, People, Select, Checklist, TagField, Geo
133
+
134
+ ---
135
+
136
+ ## eco-helpers (Downstream)
137
+
138
+ **Purpose:** Integration script framework for the ecoPortal Integrations Team.
139
+ **Local path:** `C:\ruby_scripts\git\eco-helpers`
140
+
141
+ Key patterns:
142
+ - Script use case classes inherit from `OozeBase` or `RegisterUpdate`
143
+ - `RegisterUpdate` manages a loop: search register → fetch page → modify → save
144
+ - `RegisterUpdate` tracks changes: if `dirty?(page)`, triggers `pages.update(page)`
145
+ - `RegisterUpdate` tracks stage changes: if stage changes, fetches new stage view
146
+
147
+ **Stage iteration pattern:**
148
+ ```ruby
149
+ # In RegisterUpdate
150
+ apiv2.registers.search(register_id, search_options) do |page_result|
151
+ ooze = apiv2.pages.get(page_result.id)
152
+ stage = ooze.stages.get_by_name('Risk Assessment')
153
+ apiv2.pages.get(ooze.id, stage_id: stage.id).tap do |stage_view|
154
+ with_fields(stage_view, type: :plain_text) { |f| f.value = 'Updated' }
155
+ apiv2.pages.update(stage_view)
156
+ end
157
+ end
158
+ ```
159
+
160
+ With GraphQL compat, `apiv2` is replaced by `graphql` and the pattern works unchanged.
161
+
162
+ ### Filter helpers (eco-helpers)
163
+
164
+ ```ruby
165
+ date_range_filter(from: Date.today - 7, to: Date.today, key: :updated_at)
166
+ # → { type: "date_filter", key: "updated_at", lbound: "ISO8601", ubound: "ISO8601", time_zone: "..." }
167
+
168
+ tags_filter(['Auckland', 'Wellington'], any: true)
169
+ # → { type: "tag_filter", tags: [...], mode: "any", negate: false, key: "tags" }
170
+ ```
171
+
172
+ The GraphQL compat layer translates `date_filter` lbound/ubound → gte/lte.
173
+ Other filter types pass through to the ES backend unchanged.
174
+
175
+ ---
176
+
177
+ ## Backend Source (ecoPortal Rails)
178
+
179
+ **Local path:** `C:\docker\ecoPortal_master\`
180
+
181
+ Key namespaces and files to look up:
182
+ - `Enzyme::` — old Rails models (AngularJS era, being replaced)
183
+ - `NewEp::` — current Rails models (React era)
184
+ - `NewEp::DataField` — current data field model (was `Enzyme::Membrane`)
185
+ - `Ecoportal::API::Common::Content::StringDigest` (actually in ecoportal-api-v2) — Field ID formula
186
+ - Rails `services/` loadable path — Migrator and other background services
187
+ - `.graphql` files — front-end React component GraphQL queries/fragments