ecoportal-api-graphql 2.0.0 → 3.0.0

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 (393) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +793 -14
  3. data/LICENSE +21 -21
  4. data/README.gem.md +53 -0
  5. data/lib/ecoportal/api/common/graphql/auth_service.rb +115 -115
  6. data/lib/ecoportal/api/common/graphql/class_helpers.rb +46 -46
  7. data/lib/ecoportal/api/common/graphql/client.rb +107 -69
  8. data/lib/ecoportal/api/common/graphql/hash_helpers.rb +105 -105
  9. data/lib/ecoportal/api/common/graphql/http_client.rb +124 -8
  10. data/lib/ecoportal/api/common/graphql/model/as_input.rb +54 -54
  11. data/lib/ecoportal/api/common/graphql/model/diffable/classic_diff_service.rb +49 -49
  12. data/lib/ecoportal/api/common/graphql/model/diffable/diff_service.rb +188 -188
  13. data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff.rb +55 -55
  14. data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff_nesting.rb +295 -295
  15. data/lib/ecoportal/api/common/graphql/model/diffable/leaf_diff_service.rb +1 -1
  16. data/lib/ecoportal/api/common/graphql/model.rb +17 -17
  17. data/lib/ecoportal/api/common/graphql/patches.rb +1 -1
  18. data/lib/ecoportal/api/common/graphql/query_integration.rb +45 -45
  19. data/lib/ecoportal/api/common/graphql.rb +16 -16
  20. data/lib/ecoportal/api/common.graphql.rb +8 -8
  21. data/lib/ecoportal/api/graphql/base/action_category.rb +15 -15
  22. data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +1 -1
  23. data/lib/ecoportal/api/graphql/base/contractor_entity.rb +24 -24
  24. data/lib/ecoportal/api/graphql/base/date_time.rb +12 -12
  25. data/lib/ecoportal/api/graphql/base/delta_result.rb +16 -16
  26. data/lib/ecoportal/api/graphql/base/field.rb +12 -12
  27. data/lib/ecoportal/api/graphql/base/file_attachment.rb +15 -15
  28. data/lib/ecoportal/api/graphql/base/location_node.rb +14 -14
  29. data/lib/ecoportal/api/graphql/base/location_structure/draft/structure.rb +37 -37
  30. data/lib/ecoportal/api/graphql/base/location_structure/draft.rb +93 -93
  31. data/lib/ecoportal/api/graphql/base/page/data_field/actions_list.rb +9 -9
  32. data/lib/ecoportal/api/graphql/base/page/data_field/ai_summary.rb +18 -18
  33. data/lib/ecoportal/api/graphql/base/page/data_field/checklist.rb +29 -29
  34. data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +1 -1
  35. data/lib/ecoportal/api/graphql/base/page/data_field/cross_reference.rb +1 -1
  36. data/lib/ecoportal/api/graphql/base/page/data_field/date_field.rb +23 -23
  37. data/lib/ecoportal/api/graphql/base/page/data_field/geo.rb +24 -24
  38. data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +160 -12
  39. data/lib/ecoportal/api/graphql/base/page/data_field/law.rb +8 -8
  40. data/lib/ecoportal/api/graphql/base/page/data_field/mailbox.rb +9 -9
  41. data/lib/ecoportal/api/graphql/base/page/data_field/plain_text.rb +17 -17
  42. data/lib/ecoportal/api/graphql/base/page/data_field/rich_text.rb +26 -26
  43. data/lib/ecoportal/api/graphql/base/page/data_field/signature.rb +9 -9
  44. data/lib/ecoportal/api/graphql/base/page/data_field/smart_fill.rb +17 -17
  45. data/lib/ecoportal/api/graphql/base/page/data_field/table.rb +9 -9
  46. data/lib/ecoportal/api/graphql/base/page/data_field/tag_field.rb +21 -21
  47. data/lib/ecoportal/api/graphql/base/page/phased/stage.rb +51 -0
  48. data/lib/ecoportal/api/graphql/base/page/phased.rb +15 -15
  49. data/lib/ecoportal/api/graphql/base/page/section.rb +48 -48
  50. data/lib/ecoportal/api/graphql/base/page_info.rb +12 -12
  51. data/lib/ecoportal/api/graphql/base/pages_workflow/operation_interface.rb +39 -39
  52. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/assign_to.rb +27 -27
  53. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/send_notification.rb +30 -30
  54. data/lib/ecoportal/api/graphql/base/pages_workflow/recipient_config.rb +34 -34
  55. data/lib/ecoportal/api/graphql/base/pages_workflow.rb +35 -35
  56. data/lib/ecoportal/api/graphql/base/person_member.rb +22 -22
  57. data/lib/ecoportal/api/graphql/base/preview_page.rb +23 -23
  58. data/lib/ecoportal/api/graphql/base/register.rb +1 -1
  59. data/lib/ecoportal/api/graphql/base/resource.rb +13 -13
  60. data/lib/ecoportal/api/graphql/base/temp_image.rb +28 -0
  61. data/lib/ecoportal/api/graphql/base/template/change_log_entry.rb +118 -0
  62. data/lib/ecoportal/api/graphql/base/template.rb +2 -0
  63. data/lib/ecoportal/api/graphql/base.rb +1 -0
  64. data/lib/ecoportal/api/graphql/builder/action.rb +41 -41
  65. data/lib/ecoportal/api/graphql/builder/location_structure/draft.rb +64 -64
  66. data/lib/ecoportal/api/graphql/builder/location_structure.rb +40 -40
  67. data/lib/ecoportal/api/graphql/builder/register/preset_view.rb +84 -84
  68. data/lib/ecoportal/api/graphql/builder/register.rb +49 -49
  69. data/lib/ecoportal/api/graphql/builder/template.rb +37 -4
  70. data/lib/ecoportal/api/graphql/builder/template_builder.rb +21 -2
  71. data/lib/ecoportal/api/graphql/compat/filter_translator.rb +1 -1
  72. data/lib/ecoportal/api/graphql/compat/page_reference.rb +23 -23
  73. data/lib/ecoportal/api/graphql/compat/registers.rb +84 -84
  74. data/lib/ecoportal/api/graphql/compat/search_results.rb +33 -33
  75. data/lib/ecoportal/api/graphql/compat.rb +17 -17
  76. data/lib/ecoportal/api/graphql/concerns/data_field_access.rb +71 -71
  77. data/lib/ecoportal/api/graphql/concerns/fragment_definitions.rb +68 -68
  78. data/lib/ecoportal/api/graphql/concerns/snake_camel_access.rb +60 -60
  79. data/lib/ecoportal/api/graphql/connection/preset_view.rb +11 -11
  80. data/lib/ecoportal/api/graphql/connection/template_change_log.rb +19 -0
  81. data/lib/ecoportal/api/graphql/connection.rb +1 -0
  82. data/lib/ecoportal/api/graphql/diff/change.rb +7 -2
  83. data/lib/ecoportal/api/graphql/diff/command_synthesizer.rb +19 -1
  84. data/lib/ecoportal/api/graphql/diff/version_diff.rb +13 -6
  85. data/lib/ecoportal/api/graphql/error/locations_error/fetch_nested.rb +51 -51
  86. data/lib/ecoportal/api/graphql/error/locations_error.rb +28 -28
  87. data/lib/ecoportal/api/graphql/error/locations_validation_error.rb +20 -20
  88. data/lib/ecoportal/api/graphql/error/validation_errors.rb +28 -28
  89. data/lib/ecoportal/api/graphql/error.rb +12 -12
  90. data/lib/ecoportal/api/graphql/file_upload/client.rb +140 -35
  91. data/lib/ecoportal/api/graphql/file_upload.rb +10 -10
  92. data/lib/ecoportal/api/graphql/fragment/action.rb +65 -65
  93. data/lib/ecoportal/api/graphql/fragment/action_category.rb +17 -17
  94. data/lib/ecoportal/api/graphql/fragment/contractor_entity.rb +20 -20
  95. data/lib/ecoportal/api/graphql/fragment/locations_error.rb +19 -19
  96. data/lib/ecoportal/api/graphql/fragment/page.rb +1 -0
  97. data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +10 -3
  98. data/lib/ecoportal/api/graphql/fragment/pages.rb +15 -15
  99. data/lib/ecoportal/api/graphql/fragment/pagination.rb +17 -17
  100. data/lib/ecoportal/api/graphql/fragment/permissions.rb +0 -2
  101. data/lib/ecoportal/api/graphql/fragment/template_change_log.rb +102 -0
  102. data/lib/ecoportal/api/graphql/fragment.rb +1 -0
  103. data/lib/ecoportal/api/graphql/helpers/locations_tree.rb +41 -41
  104. data/lib/ecoportal/api/graphql/helpers.rb +10 -10
  105. data/lib/ecoportal/api/graphql/input/action/archive.rb +14 -14
  106. data/lib/ecoportal/api/graphql/input/action/create.rb +13 -13
  107. data/lib/ecoportal/api/graphql/input/action.rb +14 -14
  108. data/lib/ecoportal/api/graphql/input/contractor_entity/create.rb +14 -14
  109. data/lib/ecoportal/api/graphql/input/contractor_entity/destroy.rb +13 -13
  110. data/lib/ecoportal/api/graphql/input/delta_input.rb +16 -16
  111. data/lib/ecoportal/api/graphql/input/id_diff.rb +11 -11
  112. data/lib/ecoportal/api/graphql/input/location_structure/archive_command.rb +13 -13
  113. data/lib/ecoportal/api/graphql/input/location_structure/delete_command.rb +13 -13
  114. data/lib/ecoportal/api/graphql/input/location_structure/draft/create.rb +15 -15
  115. data/lib/ecoportal/api/graphql/input/location_structure/draft/delete.rb +15 -15
  116. data/lib/ecoportal/api/graphql/input/location_structure/draft/drop_bad_commands.rb +16 -16
  117. data/lib/ecoportal/api/graphql/input/location_structure/draft/publish.rb +16 -16
  118. data/lib/ecoportal/api/graphql/input/location_structure/draft.rb +19 -19
  119. data/lib/ecoportal/api/graphql/input/location_structure/insert_command.rb +21 -13
  120. data/lib/ecoportal/api/graphql/input/location_structure/move_command.rb +14 -14
  121. data/lib/ecoportal/api/graphql/input/location_structure/reorder_command.rb +13 -13
  122. data/lib/ecoportal/api/graphql/input/location_structure/unarchive_command.rb +13 -13
  123. data/lib/ecoportal/api/graphql/input/location_structure.rb +20 -20
  124. data/lib/ecoportal/api/graphql/input/page/archive.rb +14 -14
  125. data/lib/ecoportal/api/graphql/input/page/build_from_template.rb +13 -13
  126. data/lib/ecoportal/api/graphql/input/page/create_draft.rb +13 -13
  127. data/lib/ecoportal/api/graphql/input/page/create_from_template.rb +18 -18
  128. data/lib/ecoportal/api/graphql/input/page/delete_draft.rb +13 -13
  129. data/lib/ecoportal/api/graphql/input/page/publish_draft.rb +13 -13
  130. data/lib/ecoportal/api/graphql/input/page/review_task.rb +27 -14
  131. data/lib/ecoportal/api/graphql/input/page/unarchive.rb +14 -14
  132. data/lib/ecoportal/api/graphql/input/page/update.rb +109 -6
  133. data/lib/ecoportal/api/graphql/input/page.rb +26 -26
  134. data/lib/ecoportal/api/graphql/input/preset_view/create.rb +18 -18
  135. data/lib/ecoportal/api/graphql/input/preset_view/permission.rb +16 -16
  136. data/lib/ecoportal/api/graphql/input/preset_view/update.rb +1 -1
  137. data/lib/ecoportal/api/graphql/input/preset_view.rb +14 -14
  138. data/lib/ecoportal/api/graphql/input/register/create.rb +18 -18
  139. data/lib/ecoportal/api/graphql/input/register/update.rb +15 -15
  140. data/lib/ecoportal/api/graphql/input/register.rb +13 -13
  141. data/lib/ecoportal/api/graphql/input/search.rb +13 -13
  142. data/lib/ecoportal/api/graphql/input/search_conf/ai_generator.rb +234 -234
  143. data/lib/ecoportal/api/graphql/input/search_conf.rb +1 -1
  144. data/lib/ecoportal/api/graphql/input/search_filter.rb +12 -12
  145. data/lib/ecoportal/api/graphql/input/search_sorter.rb +11 -11
  146. data/lib/ecoportal/api/graphql/input/workflow_command/add_action_tag.rb +18 -18
  147. data/lib/ecoportal/api/graphql/input/workflow_command/add_binding.rb +18 -18
  148. data/lib/ecoportal/api/graphql/input/workflow_command/add_comment_tagging_user_group.rb +18 -18
  149. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_direct_strategy_user.rb +18 -18
  150. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_strategy.rb +18 -18
  151. data/lib/ecoportal/api/graphql/input/workflow_command/add_direct_strategy_user.rb +18 -18
  152. data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +10 -9
  153. data/lib/ecoportal/api/graphql/input/workflow_command/add_force.rb +18 -18
  154. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_field_config.rb +23 -23
  155. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_helper.rb +18 -18
  156. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation.rb +18 -18
  157. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_direct_strategy_user.rb +18 -18
  158. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_strategy.rb +18 -18
  159. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_action_type.rb +18 -18
  160. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_filter.rb +18 -18
  161. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_people_field.rb +18 -18
  162. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_task_config.rb +18 -18
  163. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_user.rb +18 -18
  164. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback.rb +23 -23
  165. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback_action.rb +18 -18
  166. data/lib/ecoportal/api/graphql/input/workflow_command/add_section.rb +18 -18
  167. data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +25 -19
  168. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_section.rb +18 -18
  169. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_tag.rb +18 -18
  170. data/lib/ecoportal/api/graphql/input/workflow_command/add_strategy.rb +18 -18
  171. data/lib/ecoportal/api/graphql/input/workflow_command/add_task.rb +18 -18
  172. data/lib/ecoportal/api/graphql/input/workflow_command/add_task_assignment_user_group.rb +18 -18
  173. data/lib/ecoportal/api/graphql/input/workflow_command/add_workflow_callback.rb +18 -18
  174. data/lib/ecoportal/api/graphql/input/workflow_command/collapse_section.rb +18 -18
  175. data/lib/ecoportal/api/graphql/input/workflow_command/edit_binding.rb +18 -18
  176. data/lib/ecoportal/api/graphql/input/workflow_command/edit_creator_permissions.rb +18 -18
  177. data/lib/ecoportal/api/graphql/input/workflow_command/edit_default_strategy.rb +18 -18
  178. data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +7 -2
  179. data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +21 -18
  180. data/lib/ecoportal/api/graphql/input/workflow_command/edit_gauge_field_stop.rb +19 -19
  181. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_field_config.rb +19 -19
  182. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_helper.rb +18 -18
  183. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation.rb +18 -18
  184. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation_strategy.rb +18 -18
  185. data/lib/ecoportal/api/graphql/input/workflow_command/edit_reminder.rb +18 -18
  186. data/lib/ecoportal/api/graphql/input/workflow_command/edit_required_sign_offs.rb +18 -18
  187. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_comment_tagging.rb +18 -18
  188. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_task_assignment.rb +18 -18
  189. data/lib/ecoportal/api/graphql/input/workflow_command/edit_scheduled_callback.rb +22 -22
  190. data/lib/ecoportal/api/graphql/input/workflow_command/edit_section_header.rb +18 -18
  191. data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +23 -19
  192. data/lib/ecoportal/api/graphql/input/workflow_command/edit_stage.rb +18 -18
  193. data/lib/ecoportal/api/graphql/input/workflow_command/edit_strategy.rb +18 -18
  194. data/lib/ecoportal/api/graphql/input/workflow_command/edit_task_due.rb +18 -18
  195. data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_basic_settings.rb +7 -2
  196. data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_container_uid.rb +1 -1
  197. data/lib/ecoportal/api/graphql/input/workflow_command/edit_trigger.rb +18 -18
  198. data/lib/ecoportal/api/graphql/input/workflow_command/expand_section.rb +18 -18
  199. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/contractor_entities.rb +28 -24
  200. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +8 -2
  201. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/gauge.rb +20 -20
  202. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/location_field.rb +24 -24
  203. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +8 -2
  204. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/signature.rb +20 -20
  205. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb +25 -25
  206. data/lib/ecoportal/api/graphql/input/workflow_command/manage_copy_page_configuration.rb +47 -0
  207. data/lib/ecoportal/api/graphql/input/workflow_command/move_section_to_stage.rb +33 -0
  208. data/lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb +18 -18
  209. data/lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb +18 -18
  210. data/lib/ecoportal/api/graphql/input/workflow_command/remove_binding.rb +18 -18
  211. data/lib/ecoportal/api/graphql/input/workflow_command/remove_callback.rb +18 -18
  212. data/lib/ecoportal/api/graphql/input/workflow_command/remove_comment_tagging_user_group.rb +18 -18
  213. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_direct_strategy_user.rb +18 -18
  214. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_strategy.rb +18 -18
  215. data/lib/ecoportal/api/graphql/input/workflow_command/remove_direct_strategy_user.rb +18 -18
  216. data/lib/ecoportal/api/graphql/input/workflow_command/remove_field.rb +18 -18
  217. data/lib/ecoportal/api/graphql/input/workflow_command/remove_force.rb +18 -18
  218. data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_helper.rb +18 -18
  219. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation.rb +18 -18
  220. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_direct_strategy_user.rb +18 -18
  221. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_strategy.rb +18 -18
  222. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_action_type.rb +18 -18
  223. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_filter.rb +18 -18
  224. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_people_field.rb +18 -18
  225. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_task_config.rb +18 -18
  226. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_user.rb +18 -18
  227. data/lib/ecoportal/api/graphql/input/workflow_command/remove_scheduled_callback.rb +18 -18
  228. data/lib/ecoportal/api/graphql/input/workflow_command/remove_section.rb +18 -18
  229. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage.rb +18 -18
  230. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_section.rb +18 -18
  231. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_tag.rb +18 -18
  232. data/lib/ecoportal/api/graphql/input/workflow_command/remove_strategy.rb +18 -18
  233. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task.rb +18 -18
  234. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_assignment_user_group.rb +18 -18
  235. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_due.rb +18 -18
  236. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_priority_level.rb +18 -18
  237. data/lib/ecoportal/api/graphql/input/workflow_command.rb +5 -0
  238. data/lib/ecoportal/api/graphql/interface/base_page.rb +14 -0
  239. data/lib/ecoportal/api/graphql/interface/location_structure/node.rb +43 -43
  240. data/lib/ecoportal/api/graphql/interface/location_structure.rb +14 -14
  241. data/lib/ecoportal/api/graphql/interface.rb +11 -11
  242. data/lib/ecoportal/api/graphql/logic/base_model.rb +15 -15
  243. data/lib/ecoportal/api/graphql/logic/base_query.rb +260 -193
  244. data/lib/ecoportal/api/graphql/logic/mutation.rb +59 -59
  245. data/lib/ecoportal/api/graphql/logic/payload.rb +42 -42
  246. data/lib/ecoportal/api/graphql/logic/query.rb +23 -23
  247. data/lib/ecoportal/api/graphql/logic/query_array.rb +30 -30
  248. data/lib/ecoportal/api/graphql/logic/query_connection.rb +48 -48
  249. data/lib/ecoportal/api/graphql/logic.rb +18 -18
  250. data/lib/ecoportal/api/graphql/model/account.rb +15 -15
  251. data/lib/ecoportal/api/graphql/model/action.rb +22 -22
  252. data/lib/ecoportal/api/graphql/model/ai_summary_version.rb +10 -10
  253. data/lib/ecoportal/api/graphql/model/contractor_entity.rb +12 -12
  254. data/lib/ecoportal/api/graphql/model/field.rb +10 -10
  255. data/lib/ecoportal/api/graphql/model/file_attachment.rb +10 -10
  256. data/lib/ecoportal/api/graphql/model/file_container.rb +11 -11
  257. data/lib/ecoportal/api/graphql/model/location_node.rb +14 -14
  258. data/lib/ecoportal/api/graphql/model/location_structure/draft/structure.rb +15 -15
  259. data/lib/ecoportal/api/graphql/model/location_structure/draft.rb +15 -15
  260. data/lib/ecoportal/api/graphql/model/location_structure.rb +16 -16
  261. data/lib/ecoportal/api/graphql/model/organization.rb +9 -0
  262. data/lib/ecoportal/api/graphql/model/page/basic.rb +14 -14
  263. data/lib/ecoportal/api/graphql/model/page/data_field.rb +12 -12
  264. data/lib/ecoportal/api/graphql/model/page/phased/stage.rb +14 -14
  265. data/lib/ecoportal/api/graphql/model/page/phased.rb +17 -0
  266. data/lib/ecoportal/api/graphql/model/page/section.rb +12 -12
  267. data/lib/ecoportal/api/graphql/model/page_union.rb +21 -21
  268. data/lib/ecoportal/api/graphql/model/pages_workflow.rb +20 -20
  269. data/lib/ecoportal/api/graphql/model/permissions.rb +6 -0
  270. data/lib/ecoportal/api/graphql/model/preset_view.rb +10 -10
  271. data/lib/ecoportal/api/graphql/model/preview_page.rb +10 -10
  272. data/lib/ecoportal/api/graphql/model/register.rb +10 -10
  273. data/lib/ecoportal/api/graphql/model/resource.rb +13 -13
  274. data/lib/ecoportal/api/graphql/model/temp_image.rb +10 -0
  275. data/lib/ecoportal/api/graphql/model/template/binding.rb +60 -0
  276. data/lib/ecoportal/api/graphql/model/template/change_log_entry.rb +19 -0
  277. data/lib/ecoportal/api/graphql/model/template/command_grouper.rb +107 -0
  278. data/lib/ecoportal/api/graphql/model/template/command_normalizer.rb +116 -0
  279. data/lib/ecoportal/api/graphql/model/template/command_synthesis.rb +262 -0
  280. data/lib/ecoportal/api/graphql/model/template/field.rb +68 -0
  281. data/lib/ecoportal/api/graphql/model/template/force.rb +65 -0
  282. data/lib/ecoportal/api/graphql/model/template/helper.rb +32 -0
  283. data/lib/ecoportal/api/graphql/model/template/instance.rb +202 -0
  284. data/lib/ecoportal/api/graphql/model/template/node.rb +78 -0
  285. data/lib/ecoportal/api/graphql/model/template/option.rb +49 -0
  286. data/lib/ecoportal/api/graphql/model/template/read.rb +164 -0
  287. data/lib/ecoportal/api/graphql/model/template/section.rb +82 -0
  288. data/lib/ecoportal/api/graphql/model/template/stage.rb +49 -0
  289. data/lib/ecoportal/api/graphql/model/template/staged_executor.rb +236 -0
  290. data/lib/ecoportal/api/graphql/model/template.rb +37 -1
  291. data/lib/ecoportal/api/graphql/model/user.rb +14 -14
  292. data/lib/ecoportal/api/graphql/model.rb +1 -0
  293. data/lib/ecoportal/api/graphql/mutation/action/archive.rb +41 -41
  294. data/lib/ecoportal/api/graphql/mutation/action/create.rb +40 -40
  295. data/lib/ecoportal/api/graphql/mutation/action/update.rb +40 -40
  296. data/lib/ecoportal/api/graphql/mutation/action.rb +14 -14
  297. data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +1 -1
  298. data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +1 -1
  299. data/lib/ecoportal/api/graphql/mutation/ai_summary.rb +13 -13
  300. data/lib/ecoportal/api/graphql/mutation/contractor_entity/create.rb +40 -40
  301. data/lib/ecoportal/api/graphql/mutation/contractor_entity/destroy.rb +40 -40
  302. data/lib/ecoportal/api/graphql/mutation/contractor_entity/update.rb +40 -40
  303. data/lib/ecoportal/api/graphql/mutation/file_container/upload.rb +11 -4
  304. data/lib/ecoportal/api/graphql/mutation/image/upload.rb +88 -0
  305. data/lib/ecoportal/api/graphql/mutation/image.rb +14 -0
  306. data/lib/ecoportal/api/graphql/mutation/location_structure/apply_commands.rb +54 -54
  307. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/add_commands.rb +55 -55
  308. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/create.rb +54 -54
  309. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/delete.rb +43 -43
  310. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/drop_bad_commands.rb +56 -56
  311. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/publish.rb +66 -66
  312. data/lib/ecoportal/api/graphql/mutation/location_structure/draft.rb +18 -18
  313. data/lib/ecoportal/api/graphql/mutation/location_structure.rb +13 -13
  314. data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +1 -1
  315. data/lib/ecoportal/api/graphql/mutation/page/archive.rb +40 -40
  316. data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +1 -1
  317. data/lib/ecoportal/api/graphql/mutation/page/build_from_template.rb +50 -50
  318. data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +1 -1
  319. data/lib/ecoportal/api/graphql/mutation/page/create_from_template.rb +43 -43
  320. data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +1 -1
  321. data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +1 -1
  322. data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +1 -1
  323. data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +1 -1
  324. data/lib/ecoportal/api/graphql/mutation/page/unarchive.rb +40 -40
  325. data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +1 -1
  326. data/lib/ecoportal/api/graphql/mutation/page/update.rb +40 -40
  327. data/lib/ecoportal/api/graphql/mutation/page.rb +28 -28
  328. data/lib/ecoportal/api/graphql/mutation/preset_view/create.rb +35 -35
  329. data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +1 -1
  330. data/lib/ecoportal/api/graphql/mutation/preset_view/permission.rb +37 -37
  331. data/lib/ecoportal/api/graphql/mutation/preset_view/update.rb +35 -35
  332. data/lib/ecoportal/api/graphql/mutation/preset_view.rb +15 -15
  333. data/lib/ecoportal/api/graphql/mutation/register/create.rb +35 -35
  334. data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +1 -1
  335. data/lib/ecoportal/api/graphql/mutation/register/update.rb +35 -35
  336. data/lib/ecoportal/api/graphql/mutation/register.rb +14 -14
  337. data/lib/ecoportal/api/graphql/mutation/template/create.rb +35 -3
  338. data/lib/ecoportal/api/graphql/mutation/template/update.rb +4 -2
  339. data/lib/ecoportal/api/graphql/mutation.rb +1 -0
  340. data/lib/ecoportal/api/graphql/payload/action/archive.rb +13 -13
  341. data/lib/ecoportal/api/graphql/payload/action/create.rb +13 -13
  342. data/lib/ecoportal/api/graphql/payload/action/update.rb +13 -13
  343. data/lib/ecoportal/api/graphql/payload/action.rb +14 -14
  344. data/lib/ecoportal/api/graphql/payload/ai_summary_generate.rb +12 -12
  345. data/lib/ecoportal/api/graphql/payload/contractor_entity/create.rb +13 -13
  346. data/lib/ecoportal/api/graphql/payload/contractor_entity/destroy.rb +12 -12
  347. data/lib/ecoportal/api/graphql/payload/contractor_entity/update.rb +12 -12
  348. data/lib/ecoportal/api/graphql/payload/images_upload.rb +14 -0
  349. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_jobs.rb +2 -2
  350. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_workflows.rb +2 -2
  351. data/lib/ecoportal/api/graphql/payload/location_structure/apply_commands.rb +51 -51
  352. data/lib/ecoportal/api/graphql/payload/location_structure/command_execution_result.rb +50 -50
  353. data/lib/ecoportal/api/graphql/payload/location_structure/draft/add_commands.rb +30 -30
  354. data/lib/ecoportal/api/graphql/payload/location_structure/draft/delete.rb +30 -30
  355. data/lib/ecoportal/api/graphql/payload/location_structure/draft/drop_bad_commands.rb +43 -43
  356. data/lib/ecoportal/api/graphql/payload/location_structure/draft/publish.rb +63 -63
  357. data/lib/ecoportal/api/graphql/payload/location_structure/draft.rb +18 -18
  358. data/lib/ecoportal/api/graphql/payload/location_structure.rb +14 -14
  359. data/lib/ecoportal/api/graphql/payload/ok_payload.rb +1 -1
  360. data/lib/ecoportal/api/graphql/payload/page/archive.rb +13 -13
  361. data/lib/ecoportal/api/graphql/payload/page/build_from_template.rb +13 -13
  362. data/lib/ecoportal/api/graphql/payload/page/create_from_template.rb +13 -13
  363. data/lib/ecoportal/api/graphql/payload/page/draft.rb +1 -1
  364. data/lib/ecoportal/api/graphql/payload/page/review_task.rb +1 -1
  365. data/lib/ecoportal/api/graphql/payload/page/unarchive.rb +13 -13
  366. data/lib/ecoportal/api/graphql/payload/page/update.rb +13 -13
  367. data/lib/ecoportal/api/graphql/payload/preset_view.rb +1 -1
  368. data/lib/ecoportal/api/graphql/payload/register.rb +1 -1
  369. data/lib/ecoportal/api/graphql/payload.rb +1 -0
  370. data/lib/ecoportal/api/graphql/query/action.rb +33 -33
  371. data/lib/ecoportal/api/graphql/query/action_categories.rb +53 -53
  372. data/lib/ecoportal/api/graphql/query/actions.rb +43 -43
  373. data/lib/ecoportal/api/graphql/query/contractor_entities.rb +53 -53
  374. data/lib/ecoportal/api/graphql/query/file_upload_signature.rb +76 -76
  375. data/lib/ecoportal/api/graphql/query/location_classifications.rb +39 -39
  376. data/lib/ecoportal/api/graphql/query/page_delta.rb +47 -47
  377. data/lib/ecoportal/api/graphql/query/pages.rb +59 -59
  378. data/lib/ecoportal/api/graphql/query/permissions.rb +1 -1
  379. data/lib/ecoportal/api/graphql/query/person_members.rb +76 -0
  380. data/lib/ecoportal/api/graphql/query/register_preset_views.rb +1 -1
  381. data/lib/ecoportal/api/graphql/query/register_preview_pages.rb +83 -83
  382. data/lib/ecoportal/api/graphql/query/template_change_log.rb +118 -0
  383. data/lib/ecoportal/api/graphql/query/templates.rb +53 -53
  384. data/lib/ecoportal/api/graphql/query.rb +2 -0
  385. data/lib/ecoportal/api/graphql_version.rb +1 -1
  386. data/lib/ecoportal/api-graphql.rb +10 -10
  387. metadata +45 -9
  388. data/README.md +0 -24
  389. data/lib/ecoportal/api/common/graphql/CLAUDE.md +0 -36
  390. data/lib/ecoportal/api/common/graphql/model/CLAUDE.md +0 -28
  391. data/lib/ecoportal/api/graphql/CLAUDE.md +0 -37
  392. data/lib/ecoportal/api/graphql/base/CLAUDE.md +0 -50
  393. data/lib/ecoportal/api/graphql/builder/CLAUDE.md +0 -65
@@ -1,18 +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
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
@@ -1,29 +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
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
@@ -31,7 +31,7 @@ module Ecoportal::API::GraphQL::Base::Page
31
31
 
32
32
  # Find first field matching label (case-insensitive). Optional type: restricts to
33
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).
34
+ # a customer cutover use case which calls it directly, not via OozeRedirect).
35
35
  def get_by_name(label, type: nil)
36
36
  pool = type ? get_by_type(type) : @fields
37
37
  pool.find { |f| f.label.to_s.downcase == label.to_s.downcase }
@@ -1,4 +1,4 @@
1
- module Ecoportal::API::GraphQL::Base::Page
1
+ module Ecoportal::API::GraphQL::Base::Page
2
2
  class DataField
3
3
  # Cross-reference field — links to pages in another register.
4
4
  class CrossReference < DataField
@@ -1,23 +1,23 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # Wraps Date data field. Mapped from __typename 'Date'.
4
- # value is an ISO8601DateTime string (e.g. "2024-11-25T08:30:00+13:00").
5
- class DateField < DataField
6
- # value is nested: { dateTime: "...", timeZone: "..." } or raw string
7
- def value
8
- v = doc['value']
9
- v.is_a?(Hash) ? v['dateTime'] : v
10
- end
11
-
12
- def value=(iso8601_string)
13
- doc['value'] = iso8601_string
14
- end
15
-
16
- def as_input
17
- return nil unless dirty?
18
-
19
- { date: { id: id, value: value } }
20
- end
21
- end
22
- end
23
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # Wraps Date data field. Mapped from __typename 'Date'.
4
+ # value is an ISO8601DateTime string (e.g. "2024-11-25T08:30:00+13:00").
5
+ class DateField < DataField
6
+ # value is nested: { dateTime: "...", timeZone: "..." } or raw string
7
+ def value
8
+ v = doc['value']
9
+ v.is_a?(Hash) ? v['dateTime'] : v
10
+ end
11
+
12
+ def value=(iso8601_string)
13
+ doc['value'] = iso8601_string
14
+ end
15
+
16
+ def as_input
17
+ return nil unless dirty?
18
+
19
+ { date: { id: id, value: value } }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,24 +1,24 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- class Geo < DataField
4
- passthrough :address, :coordinates # coordinates: { lat:, lon: }
5
-
6
- def address=(new_address)
7
- doc['address'] = new_address
8
- end
9
-
10
- def coordinates=(lat_lon_hash)
11
- doc['coordinates'] = lat_lon_hash
12
- end
13
-
14
- def as_input
15
- return nil unless dirty?
16
-
17
- payload = { id: id }
18
- payload[:address] = address if address
19
- payload[:coordinates] = coordinates if coordinates
20
- { geo: payload }
21
- end
22
- end
23
- end
24
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ class Geo < DataField
4
+ passthrough :address, :coordinates # coordinates: { lat:, lon: }
5
+
6
+ def address=(new_address)
7
+ doc['address'] = new_address
8
+ end
9
+
10
+ def coordinates=(lat_lon_hash)
11
+ doc['coordinates'] = lat_lon_hash
12
+ end
13
+
14
+ def as_input
15
+ return nil unless dirty?
16
+
17
+ payload = { id: id }
18
+ payload[:address] = address if address
19
+ payload[:coordinates] = coordinates if coordinates
20
+ { geo: payload }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,26 +1,174 @@
1
- module Ecoportal::API::GraphQL::Base::Page
1
+ module Ecoportal::API::GraphQL::Base::Page
2
2
  class DataField
3
3
  # Image gallery field.
4
- # ★ WRITE PATH BROKEN (schema-invalid, live-verified 2026-08): `ImageGalleryInput` has no
5
- # `fileContainerIds` — it takes `images: [ImageInput]`, attaching via `sourceId`, which is
6
- # an `Enzyme::ImageReference::TempImage` (a DIFFERENT upload pipeline than file containers).
7
- # Fixing this needs its own design — see the DataField shape-asymmetry review project.
8
- # The reader is equally stale: live responses carry `images`, not `fileContainers`.
4
+ #
5
+ # ★ FIXED 2026-09 (previously broken -- see `spec/.../image_gallery_characterization_spec.rb`
6
+ # git history for the prior "WRITE PATH BROKEN" documentation of this defect). Confirmed
7
+ # against the LIVE ecoPortal server source (read-only, /tmp/work/ecoPortal) that a
8
+ # gallery image is genuinely NOT a `FileContainer`:
9
+ # * `app/graphql/types/fill_in_page/inputs/data_fields/image_gallery_input.rb:5-11` --
10
+ # `ImageGalleryInput` has NO `fileContainerIds`; it takes `images: [ImageInput]`.
11
+ # * `.../image_galleries/image_input.rb:6-15` -- `ImageInput` takes `sourceId` (a
12
+ # `TempImage` id, from the SEPARATE `uploadImage` mutation -- see
13
+ # `Mutation::Image::Upload` / `FileUpload::Client#upload_image`), never
14
+ # `fileContainerId`.
15
+ # * `app/services/new_ep/pages/assign_attributes_service.rb:152-176`
16
+ # (`set_image_gallery_attrs`) -- full-replace-by-omission, the SAME trap as
17
+ # `FileField`: any current image whose `id` is not echoed back in the write is
18
+ # destroyed (`format_removed_ids`).
19
+ # * `app/graphql/types/pages/data_fields/image_galleries/image_type.rb` -- `fileName`/
20
+ # `fileSize` are NULLABLE even on a successful upload -- a documented upstream bug
21
+ # ("images are successfully uploaded but the file name and size are not set in the
22
+ # database", per the live schema's own field comment). Any comparison built on these
23
+ # two fields must treat a nil on either side as "not a confident match", never a
24
+ # positive one.
25
+ #
26
+ # READ: `images { id weight downloadUrl caption fileName fileSize uploadId }`
27
+ # (`imageGalleryField` fragment, `fragment/pages/common_page_union.rb` -- `id`/`weight`
28
+ # were ADDED alongside this fix; the fragment previously omitted both, which is why no
29
+ # correct reader was possible before now).
30
+ #
31
+ # WRITE: `ImageGalleryInput { id images: [ImageInput] }`; `ImageInput { id weight
32
+ # sourceId caption fileName sensitiveContent inaccurateDescription
33
+ # inaccurateExtractedText }`. `as_input` sends every KEPT image back with its FULL
34
+ # `ImageInput` field set (`#kept_image_input`) -- NOT a bare `{id:}` -- and every NEW one
35
+ # as `{sourceId:, weight:, fileName:}` -- see `#add_source_images`, the merge-safe writer
36
+ # (mirrors `FileField#file_container_ids=`'s kept-vs-new split).
37
+ #
38
+ # ★ CORRECTED 2026-09 (pre-release, MR !278 unreleased): the bare `{id:}` echo for a kept
39
+ # image, above, silently dropped every OTHER attribute on that image on the NEXT write
40
+ # server-side -- `assign_attributes_service.rb#set_image_gallery_attrs` applies `images`
41
+ # as a FULL REPLACE (see the class header above), so a bare `{id:}` is indistinguishable
42
+ # from "clear caption/sensitiveContent/etc back to their defaults" for that image, not
43
+ # "leave it as it is". Matches the org-side reference implementation (a downstream script repo,
44
+ # commit 482db9c) and the live schema's own `ImageInput` argument list -- the shipped
45
+ # `ep-api-collections` sample only demonstrates the NEW-image shape (no existing images to
46
+ # keep), so this shape is pinned to server source + that proven reference, not a captured
47
+ # kept-echo payload (see EVIDENCE PRECEDENCE note on `#kept_image_input`).
48
+ #
49
+ # `images` is deliberately a PLAIN doc reader, not `passarray` -- same reasoning as
50
+ # `FileField#items` (see that class's header): materialising an ArrayModel writes
51
+ # `images: []` into the doc of a field read without `$content`, and a phantom-dirty empty
52
+ # `images` here doesn't always no-op (only the empty-vs-missing-key case is neutralised
53
+ # by `Diffable::LeafDiffService`'s array-diff fix, MR !106) -- it can still synthesise an
54
+ # unwanted write for a non-empty phantom read. A plain reader has no such hazard.
9
55
  class ImageGallery < DataField
10
- passarray :fileContainers # each: { id:, fileName:, url:, ... }
56
+ # each: { 'id' =>, 'weight' =>, 'downloadUrl' =>, 'caption' =>, 'fileName' =>,
57
+ # 'fileSize' =>, 'uploadId' => }
58
+ def images
59
+ Array(doc['images'])
60
+ end
61
+
62
+ # @return [Array<String>] every image's own item id (its server-assigned id, NOT the
63
+ # `uploadId`/`TempImage` id it was created from).
64
+ def image_ids
65
+ images.filter_map { |image| image['id'] if image.is_a?(Hash) }
66
+ end
11
67
 
12
- def file_container_ids
13
- Array(fileContainers).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
68
+ # @return [Integer] one past the highest `weight` currently on the field (`0` if the
69
+ # field is empty). There is no server-side auto-increment for `weight` (a plain
70
+ # Integer field, default `0`) -- callers that want sequential ordering for several new
71
+ # images in one write should still call this ONCE and increment locally
72
+ # (`#add_source_images` already does).
73
+ def next_weight
74
+ return 0 if images.empty?
75
+
76
+ images.map { |image| image.is_a?(Hash) ? image['weight'].to_i : 0 }.max + 1
14
77
  end
15
78
 
16
- def file_container_ids=(ids)
17
- doc['fileContainers'] = Array(ids).map { |id_val| { 'id' => id_val } }
79
+ # Merge-safe write: adds NEW images (each referenced by `source_id`, the `TempImage`
80
+ # id from `FileUpload::Client#upload_image`) while KEEPING every image already loaded
81
+ # on this field. `images` on `ImageGalleryInput` is a FULL REPLACE server-side -- any
82
+ # current image whose `id` is not echoed back is destroyed -- so this always keeps
83
+ # every currently-loaded image's FULL doc entry (untouched -- `#images_input` picks the
84
+ # `ImageInput`-writable subset out of it later; kept HERE in full so that subset still
85
+ # has every field to read, rather than collapsing to a bare `{'id' => ...}` that would
86
+ # throw the other attributes away before `#as_input` ever runs) and appends the new
87
+ # ones after it, at sequential weights starting at `#next_weight`. Marks the field dirty
88
+ # (same underlying mechanism as `FileField#file_container_ids=` -- a raw `doc` mutation,
89
+ # picked up by the generic diff regardless of the `passarray`/plain-reader choice above).
90
+ #
91
+ # @param sources [Array<Hash>] one entry per NEW image. Accepts either key style:
92
+ # `{source_id:, file_name:}` or `{'sourceId' =>, 'fileName' =>}`. `weight` is assigned
93
+ # here, not read from the input -- the caller does not need to compute it.
94
+ # @return [Array<Hash>] the full resulting `images` doc (kept + added), same value now
95
+ # readable via `#images`.
96
+ def add_source_images(sources)
97
+ kept = images.select { |image| image.is_a?(Hash) && image['id'] }
98
+ start = next_weight
99
+ added = Array(sources).each_with_index.map do |source, index|
100
+ {
101
+ 'sourceId' => fetch_key(source, :source_id, 'sourceId'),
102
+ 'weight' => start + index,
103
+ 'fileName' => fetch_key(source, :file_name, 'fileName')
104
+ }.compact
105
+ end
106
+ doc['images'] = kept + added
18
107
  end
19
108
 
20
109
  def as_input
21
110
  return nil unless dirty?
22
111
 
23
- { imageGallery: { id: id, fileContainerIds: file_container_ids } }
112
+ {imageGallery: {id: id, images: images_input}}
113
+ end
114
+
115
+ private
116
+
117
+ # `images` holds the write shape for a NEW item (`{'sourceId' =>, 'weight' =>,
118
+ # 'fileName' =>}`, from `#add_source_images`) as-is, and the FULL read doc for a KEPT
119
+ # item (untouched since the last read) -- `#kept_image_input` narrows the latter down to
120
+ # exactly what `ImageInput` accepts.
121
+ def images_input
122
+ images.filter_map do |image|
123
+ next unless image.is_a?(Hash)
124
+
125
+ if image['sourceId']
126
+ {sourceId: image['sourceId'], weight: image['weight'], fileName: image['fileName']}.compact
127
+ elsif image['id']
128
+ kept_image_input(image)
129
+ end
130
+ end
131
+ end
132
+
133
+ # Full-field echo for a KEPT (currently-existing, untouched) image -- REQUIRED because
134
+ # `ImageGalleryInput.images` is a full replace server-side (`assign_attributes_service.
135
+ # rb#set_image_gallery_attrs` -> `format_removed_ids`): a bare `{id:}` is read by the
136
+ # server as "clear every other attribute", not "leave this image as it is".
137
+ #
138
+ # EVIDENCE PRECEDENCE (shipped sample -> server source -> gem model): the shipped
139
+ # a customer collection's "Attach Image to Gallery Field"
140
+ # sample only demonstrates a BRAND-NEW image (`sourceId`/`weight`/`fileName`, no
141
+ # existing images on the field to keep) -- it does not capture a kept-image echo. This
142
+ # shape is therefore pinned to the next level down: the live schema's own `ImageInput`
143
+ # argument list (`app/graphql/types/fill_in_page/inputs/data_fields/image_galleries/
144
+ # image_input.rb`: `id weight sourceId caption fileName sensitiveContent
145
+ # inaccurateDescription inaccurateExtractedText`) plus the org-side reference
146
+ # implementation already built against those same server facts and merged
147
+ # (a downstream script repo, commit 482db9c, `#kept_gallery_image_input`) -- not an inference
148
+ # from this gem's own prior (incorrect) behaviour.
149
+ #
150
+ # `sourceId` here is read back from the CURRENT read's `uploadId` -- the read-side name
151
+ # for the same identifier (a customer collection's integration guide
152
+ # section 7: "the id changes name between reading and writing"). Every key is sent as
153
+ # read (never `.compact`-ed away) -- this is an ECHO of the field's current state, so a
154
+ # nil here means "this attribute is genuinely unset", which is exactly what should be
155
+ # (re-)written to preserve it unset, not omitted and misread as "clear it".
156
+ def kept_image_input(image)
157
+ {
158
+ id: image['id'],
159
+ sourceId: image['uploadId'],
160
+ weight: image['weight'],
161
+ caption: image['caption'],
162
+ fileName: image['fileName'],
163
+ sensitiveContent: image['sensitiveContent'],
164
+ inaccurateDescription: image['inaccurateDescription'],
165
+ inaccurateExtractedText: image['inaccurateExtractedText']
166
+ }
167
+ end
168
+
169
+ def fetch_key(hash, *keys)
170
+ keys.each { |k| return hash[k] if hash.is_a?(Hash) && hash.key?(k) }
171
+ nil
24
172
  end
25
173
  end
26
174
  end
@@ -1,8 +1,8 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # Legal obligation / law snippets field — read access only.
4
- class Law < DataField
5
- passarray :laws # each: { id:, content: }
6
- end
7
- end
8
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # Legal obligation / law snippets field — read access only.
4
+ class Law < DataField
5
+ passarray :laws # each: { id:, content: }
6
+ end
7
+ end
8
+ end
@@ -1,9 +1,9 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # Mailbox field — email inbox linked to this field.
4
- # Managed by the system; not settable via script.
5
- class Mailbox < DataField
6
- passthrough :email, :enabled
7
- end
8
- end
9
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # Mailbox field — email inbox linked to this field.
4
+ # Managed by the system; not settable via script.
5
+ class Mailbox < DataField
6
+ passthrough :email, :enabled
7
+ end
8
+ end
9
+ end
@@ -1,17 +1,17 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- class PlainText < DataField
4
- passthrough :value
5
-
6
- def value=(new_value)
7
- doc['value'] = new_value
8
- end
9
-
10
- def as_input
11
- return nil unless dirty?
12
-
13
- { plainText: { id: id, value: value } }
14
- end
15
- end
16
- end
17
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ class PlainText < DataField
4
+ passthrough :value
5
+
6
+ def value=(new_value)
7
+ doc['value'] = new_value
8
+ end
9
+
10
+ def as_input
11
+ return nil unless dirty?
12
+
13
+ { plainText: { id: id, value: value } }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,26 +1,26 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- class RichText < DataField
4
- passthrough :content
5
-
6
- def content=(new_content)
7
- doc['content'] = new_content
8
- end
9
-
10
- # v2 compat alias — RichText value is stored as content
11
- def value
12
- content
13
- end
14
-
15
- def value=(new_value)
16
- self.content = new_value
17
- end
18
-
19
- def as_input
20
- return nil unless dirty?
21
-
22
- { richText: { id: id, content: content } }
23
- end
24
- end
25
- end
26
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ class RichText < DataField
4
+ passthrough :content
5
+
6
+ def content=(new_content)
7
+ doc['content'] = new_content
8
+ end
9
+
10
+ # v2 compat alias — RichText value is stored as content
11
+ def value
12
+ content
13
+ end
14
+
15
+ def value=(new_value)
16
+ self.content = new_value
17
+ end
18
+
19
+ def as_input
20
+ return nil unless dirty?
21
+
22
+ { richText: { id: id, content: content } }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,9 +1,9 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # Digital signature capture field — read access only.
4
- # Signatures are captured through the UI; not settable via script.
5
- class Signature < DataField
6
- passthrough :signedAt, :signerName
7
- end
8
- end
9
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # Digital signature capture field — read access only.
4
+ # Signatures are captured through the UI; not settable via script.
5
+ class Signature < DataField
6
+ passthrough :signedAt, :signerName
7
+ end
8
+ end
9
+ end
@@ -1,17 +1,17 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # SmartFill field — AI-auto-populated field using a template-defined prompt.
4
- # Value is generated server-side via Bedrock; trigger_type controls when.
5
- #
6
- # Read-only for DataFieldInput — use the generateSmartFill GraphQL mutation
7
- # (or its trigger) to populate. The instructions field is template-configured
8
- # and can be reviewed/updated via template management.
9
- class SmartFill < DataField
10
- passthrough :status # pending | generating | success | failed
11
- passthrough :trigger_type # manual | snapshot | live
12
- passthrough :instructions # the AI prompt configured on the template field
13
- passboolean :edit_enabled
14
- passthrough :generated_at
15
- end
16
- end
17
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # SmartFill field — AI-auto-populated field using a template-defined prompt.
4
+ # Value is generated server-side via Bedrock; trigger_type controls when.
5
+ #
6
+ # Read-only for DataFieldInput — use the generateSmartFill GraphQL mutation
7
+ # (or its trigger) to populate. The instructions field is template-configured
8
+ # and can be reviewed/updated via template management.
9
+ class SmartFill < DataField
10
+ passthrough :status # pending | generating | success | failed
11
+ passthrough :trigger_type # manual | snapshot | live
12
+ passthrough :instructions # the AI prompt configured on the template field
13
+ passboolean :edit_enabled
14
+ passthrough :generated_at
15
+ end
16
+ end
17
+ end
@@ -1,9 +1,9 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # Table / embedded structure field — read access only.
4
- # Complex structured data managed via its own mutation path.
5
- class Table < DataField
6
- passarray :rows
7
- end
8
- end
9
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # Table / embedded structure field — read access only.
4
+ # Complex structured data managed via its own mutation path.
5
+ class Table < DataField
6
+ passarray :rows
7
+ end
8
+ end
9
+ end
@@ -1,21 +1,21 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # Location/tag field — mapped from __typename 'TagField'.
4
- class TagField < DataField
5
- passarray :locations # each: { id:, name: }
6
-
7
- def location_ids
8
- Array(locations).map { |l| l['id'] }.compact
9
- end
10
-
11
- def location_ids=(ids)
12
- doc['locations'] = Array(ids).map { |id_val| { 'id' => id_val } }
13
- end
14
-
15
- # NOTE: LocationFieldInput has NO location-value field — page locations are set at the
16
- # PAGE level (UpdatePageInput.page.locations, via Interface::BasePage#location_ids=),
17
- # not via the data field. So this field contributes no value to dataFields.updates;
18
- # it inherits DataField#as_input (nil). location_ids/= stay as field-level read/staging.
19
- end
20
- end
21
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # Location/tag field — mapped from __typename 'TagField'.
4
+ class TagField < DataField
5
+ passarray :locations # each: { id:, name: }
6
+
7
+ def location_ids
8
+ Array(locations).map { |l| l['id'] }.compact
9
+ end
10
+
11
+ def location_ids=(ids)
12
+ doc['locations'] = Array(ids).map { |id_val| { 'id' => id_val } }
13
+ end
14
+
15
+ # NOTE: LocationFieldInput has NO location-value field — page locations are set at the
16
+ # PAGE level (UpdatePageInput.page.locations, via Interface::BasePage#location_ids=),
17
+ # not via the data field. So this field contributes no value to dataFields.updates;
18
+ # it inherits DataField#as_input (nil). location_ids/= stay as field-level read/staging.
19
+ end
20
+ end
21
+ end