ecoportal-api-graphql 2.0.0 → 2.2.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 (355) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +363 -1
  3. data/LICENSE +21 -21
  4. data/README.md +24 -24
  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 +69 -69
  8. data/lib/ecoportal/api/common/graphql/hash_helpers.rb +105 -105
  9. data/lib/ecoportal/api/common/graphql/http_client.rb +85 -2
  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.rb +17 -17
  16. data/lib/ecoportal/api/common/graphql/patches.rb +1 -1
  17. data/lib/ecoportal/api/common/graphql/query_integration.rb +45 -45
  18. data/lib/ecoportal/api/common/graphql.rb +16 -16
  19. data/lib/ecoportal/api/common.graphql.rb +8 -8
  20. data/lib/ecoportal/api/graphql/base/action_category.rb +15 -15
  21. data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +1 -1
  22. data/lib/ecoportal/api/graphql/base/contractor_entity.rb +24 -24
  23. data/lib/ecoportal/api/graphql/base/date_time.rb +12 -12
  24. data/lib/ecoportal/api/graphql/base/delta_result.rb +16 -16
  25. data/lib/ecoportal/api/graphql/base/field.rb +12 -12
  26. data/lib/ecoportal/api/graphql/base/file_attachment.rb +15 -15
  27. data/lib/ecoportal/api/graphql/base/location_node.rb +14 -14
  28. data/lib/ecoportal/api/graphql/base/location_structure/draft/structure.rb +37 -37
  29. data/lib/ecoportal/api/graphql/base/location_structure/draft.rb +93 -93
  30. data/lib/ecoportal/api/graphql/base/page/data_field/actions_list.rb +9 -9
  31. data/lib/ecoportal/api/graphql/base/page/data_field/ai_summary.rb +18 -18
  32. data/lib/ecoportal/api/graphql/base/page/data_field/checklist.rb +29 -29
  33. data/lib/ecoportal/api/graphql/base/page/data_field/cross_reference.rb +1 -1
  34. data/lib/ecoportal/api/graphql/base/page/data_field/date_field.rb +23 -23
  35. data/lib/ecoportal/api/graphql/base/page/data_field/geo.rb +24 -24
  36. data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +1 -1
  37. data/lib/ecoportal/api/graphql/base/page/data_field/law.rb +8 -8
  38. data/lib/ecoportal/api/graphql/base/page/data_field/mailbox.rb +9 -9
  39. data/lib/ecoportal/api/graphql/base/page/data_field/plain_text.rb +17 -17
  40. data/lib/ecoportal/api/graphql/base/page/data_field/rich_text.rb +26 -26
  41. data/lib/ecoportal/api/graphql/base/page/data_field/signature.rb +9 -9
  42. data/lib/ecoportal/api/graphql/base/page/data_field/smart_fill.rb +17 -17
  43. data/lib/ecoportal/api/graphql/base/page/data_field/table.rb +9 -9
  44. data/lib/ecoportal/api/graphql/base/page/data_field/tag_field.rb +21 -21
  45. data/lib/ecoportal/api/graphql/base/page/phased/stage.rb +51 -0
  46. data/lib/ecoportal/api/graphql/base/page/phased.rb +15 -15
  47. data/lib/ecoportal/api/graphql/base/page/section.rb +48 -48
  48. data/lib/ecoportal/api/graphql/base/page_info.rb +12 -12
  49. data/lib/ecoportal/api/graphql/base/pages_workflow/operation_interface.rb +39 -39
  50. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/assign_to.rb +27 -27
  51. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/send_notification.rb +30 -30
  52. data/lib/ecoportal/api/graphql/base/pages_workflow/recipient_config.rb +34 -34
  53. data/lib/ecoportal/api/graphql/base/pages_workflow.rb +35 -35
  54. data/lib/ecoportal/api/graphql/base/person_member.rb +22 -22
  55. data/lib/ecoportal/api/graphql/base/preview_page.rb +23 -23
  56. data/lib/ecoportal/api/graphql/base/register.rb +1 -1
  57. data/lib/ecoportal/api/graphql/base/resource.rb +13 -13
  58. data/lib/ecoportal/api/graphql/base/template/change_log_entry.rb +118 -0
  59. data/lib/ecoportal/api/graphql/base/template.rb +2 -0
  60. data/lib/ecoportal/api/graphql/builder/action.rb +41 -41
  61. data/lib/ecoportal/api/graphql/builder/location_structure/draft.rb +64 -64
  62. data/lib/ecoportal/api/graphql/builder/location_structure.rb +40 -40
  63. data/lib/ecoportal/api/graphql/builder/register/preset_view.rb +84 -84
  64. data/lib/ecoportal/api/graphql/builder/register.rb +49 -49
  65. data/lib/ecoportal/api/graphql/builder/template.rb +28 -0
  66. data/lib/ecoportal/api/graphql/builder/template_builder.rb +21 -2
  67. data/lib/ecoportal/api/graphql/compat/page_reference.rb +23 -23
  68. data/lib/ecoportal/api/graphql/compat/registers.rb +84 -84
  69. data/lib/ecoportal/api/graphql/compat/search_results.rb +33 -33
  70. data/lib/ecoportal/api/graphql/compat.rb +17 -17
  71. data/lib/ecoportal/api/graphql/concerns/data_field_access.rb +71 -71
  72. data/lib/ecoportal/api/graphql/concerns/fragment_definitions.rb +68 -68
  73. data/lib/ecoportal/api/graphql/concerns/snake_camel_access.rb +60 -60
  74. data/lib/ecoportal/api/graphql/connection/preset_view.rb +11 -11
  75. data/lib/ecoportal/api/graphql/connection/template_change_log.rb +19 -0
  76. data/lib/ecoportal/api/graphql/connection.rb +1 -0
  77. data/lib/ecoportal/api/graphql/diff/change.rb +7 -2
  78. data/lib/ecoportal/api/graphql/diff/command_synthesizer.rb +19 -1
  79. data/lib/ecoportal/api/graphql/diff/version_diff.rb +13 -6
  80. data/lib/ecoportal/api/graphql/error/locations_error/fetch_nested.rb +51 -51
  81. data/lib/ecoportal/api/graphql/error/locations_error.rb +28 -28
  82. data/lib/ecoportal/api/graphql/error/locations_validation_error.rb +20 -20
  83. data/lib/ecoportal/api/graphql/error/validation_errors.rb +28 -28
  84. data/lib/ecoportal/api/graphql/error.rb +12 -12
  85. data/lib/ecoportal/api/graphql/file_upload.rb +10 -10
  86. data/lib/ecoportal/api/graphql/fragment/action.rb +65 -65
  87. data/lib/ecoportal/api/graphql/fragment/action_category.rb +17 -17
  88. data/lib/ecoportal/api/graphql/fragment/contractor_entity.rb +20 -20
  89. data/lib/ecoportal/api/graphql/fragment/locations_error.rb +19 -19
  90. data/lib/ecoportal/api/graphql/fragment/page.rb +1 -0
  91. data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +2 -0
  92. data/lib/ecoportal/api/graphql/fragment/pages.rb +15 -15
  93. data/lib/ecoportal/api/graphql/fragment/pagination.rb +17 -17
  94. data/lib/ecoportal/api/graphql/fragment/template_change_log.rb +102 -0
  95. data/lib/ecoportal/api/graphql/fragment.rb +1 -0
  96. data/lib/ecoportal/api/graphql/helpers/locations_tree.rb +41 -41
  97. data/lib/ecoportal/api/graphql/helpers.rb +10 -10
  98. data/lib/ecoportal/api/graphql/input/action/archive.rb +14 -14
  99. data/lib/ecoportal/api/graphql/input/action/create.rb +13 -13
  100. data/lib/ecoportal/api/graphql/input/action.rb +14 -14
  101. data/lib/ecoportal/api/graphql/input/contractor_entity/create.rb +14 -14
  102. data/lib/ecoportal/api/graphql/input/contractor_entity/destroy.rb +13 -13
  103. data/lib/ecoportal/api/graphql/input/delta_input.rb +16 -16
  104. data/lib/ecoportal/api/graphql/input/id_diff.rb +11 -11
  105. data/lib/ecoportal/api/graphql/input/location_structure/archive_command.rb +13 -13
  106. data/lib/ecoportal/api/graphql/input/location_structure/delete_command.rb +13 -13
  107. data/lib/ecoportal/api/graphql/input/location_structure/draft/create.rb +15 -15
  108. data/lib/ecoportal/api/graphql/input/location_structure/draft/delete.rb +15 -15
  109. data/lib/ecoportal/api/graphql/input/location_structure/draft/drop_bad_commands.rb +16 -16
  110. data/lib/ecoportal/api/graphql/input/location_structure/draft/publish.rb +16 -16
  111. data/lib/ecoportal/api/graphql/input/location_structure/draft.rb +19 -19
  112. data/lib/ecoportal/api/graphql/input/location_structure/insert_command.rb +21 -13
  113. data/lib/ecoportal/api/graphql/input/location_structure/move_command.rb +14 -14
  114. data/lib/ecoportal/api/graphql/input/location_structure/reorder_command.rb +13 -13
  115. data/lib/ecoportal/api/graphql/input/location_structure/unarchive_command.rb +13 -13
  116. data/lib/ecoportal/api/graphql/input/location_structure.rb +20 -20
  117. data/lib/ecoportal/api/graphql/input/page/archive.rb +14 -14
  118. data/lib/ecoportal/api/graphql/input/page/build_from_template.rb +13 -13
  119. data/lib/ecoportal/api/graphql/input/page/create_draft.rb +13 -13
  120. data/lib/ecoportal/api/graphql/input/page/create_from_template.rb +18 -18
  121. data/lib/ecoportal/api/graphql/input/page/delete_draft.rb +13 -13
  122. data/lib/ecoportal/api/graphql/input/page/publish_draft.rb +13 -13
  123. data/lib/ecoportal/api/graphql/input/page/review_task.rb +27 -14
  124. data/lib/ecoportal/api/graphql/input/page/unarchive.rb +14 -14
  125. data/lib/ecoportal/api/graphql/input/page.rb +26 -26
  126. data/lib/ecoportal/api/graphql/input/preset_view/create.rb +18 -18
  127. data/lib/ecoportal/api/graphql/input/preset_view/permission.rb +16 -16
  128. data/lib/ecoportal/api/graphql/input/preset_view/update.rb +1 -1
  129. data/lib/ecoportal/api/graphql/input/preset_view.rb +14 -14
  130. data/lib/ecoportal/api/graphql/input/register/create.rb +18 -18
  131. data/lib/ecoportal/api/graphql/input/register/update.rb +15 -15
  132. data/lib/ecoportal/api/graphql/input/register.rb +13 -13
  133. data/lib/ecoportal/api/graphql/input/search.rb +13 -13
  134. data/lib/ecoportal/api/graphql/input/search_conf/ai_generator.rb +234 -234
  135. data/lib/ecoportal/api/graphql/input/search_filter.rb +12 -12
  136. data/lib/ecoportal/api/graphql/input/search_sorter.rb +11 -11
  137. data/lib/ecoportal/api/graphql/input/workflow_command/add_action_tag.rb +18 -18
  138. data/lib/ecoportal/api/graphql/input/workflow_command/add_binding.rb +18 -18
  139. data/lib/ecoportal/api/graphql/input/workflow_command/add_comment_tagging_user_group.rb +18 -18
  140. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_direct_strategy_user.rb +18 -18
  141. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_strategy.rb +18 -18
  142. data/lib/ecoportal/api/graphql/input/workflow_command/add_direct_strategy_user.rb +18 -18
  143. data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +10 -9
  144. data/lib/ecoportal/api/graphql/input/workflow_command/add_force.rb +18 -18
  145. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_field_config.rb +23 -23
  146. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_helper.rb +18 -18
  147. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation.rb +18 -18
  148. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_direct_strategy_user.rb +18 -18
  149. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_strategy.rb +18 -18
  150. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_action_type.rb +18 -18
  151. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_filter.rb +18 -18
  152. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_people_field.rb +18 -18
  153. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_task_config.rb +18 -18
  154. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_user.rb +18 -18
  155. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback.rb +23 -23
  156. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback_action.rb +18 -18
  157. data/lib/ecoportal/api/graphql/input/workflow_command/add_section.rb +18 -18
  158. data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +25 -19
  159. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_section.rb +18 -18
  160. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_tag.rb +18 -18
  161. data/lib/ecoportal/api/graphql/input/workflow_command/add_strategy.rb +18 -18
  162. data/lib/ecoportal/api/graphql/input/workflow_command/add_task.rb +18 -18
  163. data/lib/ecoportal/api/graphql/input/workflow_command/add_task_assignment_user_group.rb +18 -18
  164. data/lib/ecoportal/api/graphql/input/workflow_command/add_workflow_callback.rb +18 -18
  165. data/lib/ecoportal/api/graphql/input/workflow_command/collapse_section.rb +18 -18
  166. data/lib/ecoportal/api/graphql/input/workflow_command/edit_binding.rb +18 -18
  167. data/lib/ecoportal/api/graphql/input/workflow_command/edit_creator_permissions.rb +18 -18
  168. data/lib/ecoportal/api/graphql/input/workflow_command/edit_default_strategy.rb +18 -18
  169. data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +7 -2
  170. data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +21 -18
  171. data/lib/ecoportal/api/graphql/input/workflow_command/edit_gauge_field_stop.rb +19 -19
  172. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_field_config.rb +19 -19
  173. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_helper.rb +18 -18
  174. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation.rb +18 -18
  175. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation_strategy.rb +18 -18
  176. data/lib/ecoportal/api/graphql/input/workflow_command/edit_reminder.rb +18 -18
  177. data/lib/ecoportal/api/graphql/input/workflow_command/edit_required_sign_offs.rb +18 -18
  178. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_comment_tagging.rb +18 -18
  179. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_task_assignment.rb +18 -18
  180. data/lib/ecoportal/api/graphql/input/workflow_command/edit_scheduled_callback.rb +22 -22
  181. data/lib/ecoportal/api/graphql/input/workflow_command/edit_section_header.rb +18 -18
  182. data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +23 -19
  183. data/lib/ecoportal/api/graphql/input/workflow_command/edit_stage.rb +18 -18
  184. data/lib/ecoportal/api/graphql/input/workflow_command/edit_strategy.rb +18 -18
  185. data/lib/ecoportal/api/graphql/input/workflow_command/edit_task_due.rb +18 -18
  186. data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_basic_settings.rb +7 -2
  187. data/lib/ecoportal/api/graphql/input/workflow_command/edit_trigger.rb +18 -18
  188. data/lib/ecoportal/api/graphql/input/workflow_command/expand_section.rb +18 -18
  189. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/contractor_entities.rb +28 -24
  190. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +8 -2
  191. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/gauge.rb +20 -20
  192. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/location_field.rb +24 -24
  193. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +8 -2
  194. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/signature.rb +20 -20
  195. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb +25 -25
  196. data/lib/ecoportal/api/graphql/input/workflow_command/manage_copy_page_configuration.rb +47 -0
  197. data/lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb +18 -18
  198. data/lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb +18 -18
  199. data/lib/ecoportal/api/graphql/input/workflow_command/remove_binding.rb +18 -18
  200. data/lib/ecoportal/api/graphql/input/workflow_command/remove_callback.rb +18 -18
  201. data/lib/ecoportal/api/graphql/input/workflow_command/remove_comment_tagging_user_group.rb +18 -18
  202. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_direct_strategy_user.rb +18 -18
  203. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_strategy.rb +18 -18
  204. data/lib/ecoportal/api/graphql/input/workflow_command/remove_direct_strategy_user.rb +18 -18
  205. data/lib/ecoportal/api/graphql/input/workflow_command/remove_field.rb +18 -18
  206. data/lib/ecoportal/api/graphql/input/workflow_command/remove_force.rb +18 -18
  207. data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_helper.rb +18 -18
  208. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation.rb +18 -18
  209. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_direct_strategy_user.rb +18 -18
  210. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_strategy.rb +18 -18
  211. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_action_type.rb +18 -18
  212. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_filter.rb +18 -18
  213. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_people_field.rb +18 -18
  214. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_task_config.rb +18 -18
  215. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_user.rb +18 -18
  216. data/lib/ecoportal/api/graphql/input/workflow_command/remove_scheduled_callback.rb +18 -18
  217. data/lib/ecoportal/api/graphql/input/workflow_command/remove_section.rb +18 -18
  218. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage.rb +18 -18
  219. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_section.rb +18 -18
  220. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_tag.rb +18 -18
  221. data/lib/ecoportal/api/graphql/input/workflow_command/remove_strategy.rb +18 -18
  222. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task.rb +18 -18
  223. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_assignment_user_group.rb +18 -18
  224. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_due.rb +18 -18
  225. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_priority_level.rb +18 -18
  226. data/lib/ecoportal/api/graphql/input/workflow_command.rb +3 -0
  227. data/lib/ecoportal/api/graphql/interface/base_page.rb +14 -0
  228. data/lib/ecoportal/api/graphql/interface/location_structure/node.rb +43 -43
  229. data/lib/ecoportal/api/graphql/interface/location_structure.rb +14 -14
  230. data/lib/ecoportal/api/graphql/interface.rb +11 -11
  231. data/lib/ecoportal/api/graphql/logic/base_model.rb +15 -15
  232. data/lib/ecoportal/api/graphql/logic/base_query.rb +260 -193
  233. data/lib/ecoportal/api/graphql/logic/mutation.rb +59 -59
  234. data/lib/ecoportal/api/graphql/logic/payload.rb +42 -42
  235. data/lib/ecoportal/api/graphql/logic/query.rb +23 -23
  236. data/lib/ecoportal/api/graphql/logic/query_array.rb +30 -30
  237. data/lib/ecoportal/api/graphql/logic/query_connection.rb +48 -48
  238. data/lib/ecoportal/api/graphql/logic.rb +18 -18
  239. data/lib/ecoportal/api/graphql/model/account.rb +15 -15
  240. data/lib/ecoportal/api/graphql/model/action.rb +22 -22
  241. data/lib/ecoportal/api/graphql/model/ai_summary_version.rb +10 -10
  242. data/lib/ecoportal/api/graphql/model/contractor_entity.rb +12 -12
  243. data/lib/ecoportal/api/graphql/model/field.rb +10 -10
  244. data/lib/ecoportal/api/graphql/model/file_attachment.rb +10 -10
  245. data/lib/ecoportal/api/graphql/model/file_container.rb +11 -11
  246. data/lib/ecoportal/api/graphql/model/location_node.rb +14 -14
  247. data/lib/ecoportal/api/graphql/model/location_structure/draft/structure.rb +15 -15
  248. data/lib/ecoportal/api/graphql/model/location_structure/draft.rb +15 -15
  249. data/lib/ecoportal/api/graphql/model/location_structure.rb +16 -16
  250. data/lib/ecoportal/api/graphql/model/organization.rb +9 -0
  251. data/lib/ecoportal/api/graphql/model/page/basic.rb +14 -14
  252. data/lib/ecoportal/api/graphql/model/page/data_field.rb +12 -12
  253. data/lib/ecoportal/api/graphql/model/page/phased/stage.rb +14 -14
  254. data/lib/ecoportal/api/graphql/model/page/phased.rb +17 -0
  255. data/lib/ecoportal/api/graphql/model/page/section.rb +12 -12
  256. data/lib/ecoportal/api/graphql/model/page_union.rb +21 -21
  257. data/lib/ecoportal/api/graphql/model/pages_workflow.rb +20 -20
  258. data/lib/ecoportal/api/graphql/model/preset_view.rb +10 -10
  259. data/lib/ecoportal/api/graphql/model/preview_page.rb +10 -10
  260. data/lib/ecoportal/api/graphql/model/register.rb +10 -10
  261. data/lib/ecoportal/api/graphql/model/resource.rb +13 -13
  262. data/lib/ecoportal/api/graphql/model/template/change_log_entry.rb +19 -0
  263. data/lib/ecoportal/api/graphql/model/template.rb +4 -1
  264. data/lib/ecoportal/api/graphql/model/user.rb +14 -14
  265. data/lib/ecoportal/api/graphql/mutation/action/archive.rb +41 -41
  266. data/lib/ecoportal/api/graphql/mutation/action/create.rb +40 -40
  267. data/lib/ecoportal/api/graphql/mutation/action/update.rb +40 -40
  268. data/lib/ecoportal/api/graphql/mutation/action.rb +14 -14
  269. data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +1 -1
  270. data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +1 -1
  271. data/lib/ecoportal/api/graphql/mutation/ai_summary.rb +13 -13
  272. data/lib/ecoportal/api/graphql/mutation/contractor_entity/create.rb +40 -40
  273. data/lib/ecoportal/api/graphql/mutation/contractor_entity/destroy.rb +40 -40
  274. data/lib/ecoportal/api/graphql/mutation/contractor_entity/update.rb +40 -40
  275. data/lib/ecoportal/api/graphql/mutation/location_structure/apply_commands.rb +54 -54
  276. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/add_commands.rb +55 -55
  277. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/create.rb +54 -54
  278. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/delete.rb +43 -43
  279. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/drop_bad_commands.rb +56 -56
  280. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/publish.rb +66 -66
  281. data/lib/ecoportal/api/graphql/mutation/location_structure/draft.rb +18 -18
  282. data/lib/ecoportal/api/graphql/mutation/location_structure.rb +13 -13
  283. data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +1 -1
  284. data/lib/ecoportal/api/graphql/mutation/page/archive.rb +40 -40
  285. data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +1 -1
  286. data/lib/ecoportal/api/graphql/mutation/page/build_from_template.rb +50 -50
  287. data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +1 -1
  288. data/lib/ecoportal/api/graphql/mutation/page/create_from_template.rb +43 -43
  289. data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +1 -1
  290. data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +1 -1
  291. data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +1 -1
  292. data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +1 -1
  293. data/lib/ecoportal/api/graphql/mutation/page/unarchive.rb +40 -40
  294. data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +1 -1
  295. data/lib/ecoportal/api/graphql/mutation/page/update.rb +40 -40
  296. data/lib/ecoportal/api/graphql/mutation/page.rb +28 -28
  297. data/lib/ecoportal/api/graphql/mutation/preset_view/create.rb +35 -35
  298. data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +1 -1
  299. data/lib/ecoportal/api/graphql/mutation/preset_view/permission.rb +37 -37
  300. data/lib/ecoportal/api/graphql/mutation/preset_view/update.rb +35 -35
  301. data/lib/ecoportal/api/graphql/mutation/preset_view.rb +15 -15
  302. data/lib/ecoportal/api/graphql/mutation/register/create.rb +35 -35
  303. data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +1 -1
  304. data/lib/ecoportal/api/graphql/mutation/register/update.rb +35 -35
  305. data/lib/ecoportal/api/graphql/mutation/register.rb +14 -14
  306. data/lib/ecoportal/api/graphql/payload/action/archive.rb +13 -13
  307. data/lib/ecoportal/api/graphql/payload/action/create.rb +13 -13
  308. data/lib/ecoportal/api/graphql/payload/action/update.rb +13 -13
  309. data/lib/ecoportal/api/graphql/payload/action.rb +14 -14
  310. data/lib/ecoportal/api/graphql/payload/ai_summary_generate.rb +12 -12
  311. data/lib/ecoportal/api/graphql/payload/contractor_entity/create.rb +13 -13
  312. data/lib/ecoportal/api/graphql/payload/contractor_entity/destroy.rb +12 -12
  313. data/lib/ecoportal/api/graphql/payload/contractor_entity/update.rb +12 -12
  314. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_jobs.rb +2 -2
  315. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_workflows.rb +2 -2
  316. data/lib/ecoportal/api/graphql/payload/location_structure/apply_commands.rb +51 -51
  317. data/lib/ecoportal/api/graphql/payload/location_structure/command_execution_result.rb +50 -50
  318. data/lib/ecoportal/api/graphql/payload/location_structure/draft/add_commands.rb +30 -30
  319. data/lib/ecoportal/api/graphql/payload/location_structure/draft/delete.rb +30 -30
  320. data/lib/ecoportal/api/graphql/payload/location_structure/draft/drop_bad_commands.rb +43 -43
  321. data/lib/ecoportal/api/graphql/payload/location_structure/draft/publish.rb +63 -63
  322. data/lib/ecoportal/api/graphql/payload/location_structure/draft.rb +18 -18
  323. data/lib/ecoportal/api/graphql/payload/location_structure.rb +14 -14
  324. data/lib/ecoportal/api/graphql/payload/ok_payload.rb +1 -1
  325. data/lib/ecoportal/api/graphql/payload/page/archive.rb +13 -13
  326. data/lib/ecoportal/api/graphql/payload/page/build_from_template.rb +13 -13
  327. data/lib/ecoportal/api/graphql/payload/page/create_from_template.rb +13 -13
  328. data/lib/ecoportal/api/graphql/payload/page/draft.rb +1 -1
  329. data/lib/ecoportal/api/graphql/payload/page/review_task.rb +1 -1
  330. data/lib/ecoportal/api/graphql/payload/page/unarchive.rb +13 -13
  331. data/lib/ecoportal/api/graphql/payload/page/update.rb +13 -13
  332. data/lib/ecoportal/api/graphql/payload/preset_view.rb +1 -1
  333. data/lib/ecoportal/api/graphql/payload/register.rb +1 -1
  334. data/lib/ecoportal/api/graphql/query/action.rb +33 -33
  335. data/lib/ecoportal/api/graphql/query/action_categories.rb +53 -53
  336. data/lib/ecoportal/api/graphql/query/actions.rb +43 -43
  337. data/lib/ecoportal/api/graphql/query/contractor_entities.rb +53 -53
  338. data/lib/ecoportal/api/graphql/query/file_upload_signature.rb +76 -76
  339. data/lib/ecoportal/api/graphql/query/location_classifications.rb +39 -39
  340. data/lib/ecoportal/api/graphql/query/page_delta.rb +47 -47
  341. data/lib/ecoportal/api/graphql/query/pages.rb +59 -59
  342. data/lib/ecoportal/api/graphql/query/person_members.rb +76 -0
  343. data/lib/ecoportal/api/graphql/query/register_preset_views.rb +1 -1
  344. data/lib/ecoportal/api/graphql/query/register_preview_pages.rb +83 -83
  345. data/lib/ecoportal/api/graphql/query/template_change_log.rb +118 -0
  346. data/lib/ecoportal/api/graphql/query/templates.rb +53 -53
  347. data/lib/ecoportal/api/graphql/query.rb +2 -0
  348. data/lib/ecoportal/api/graphql_version.rb +1 -1
  349. data/lib/ecoportal/api-graphql.rb +10 -10
  350. metadata +10 -8
  351. data/lib/ecoportal/api/common/graphql/CLAUDE.md +0 -36
  352. data/lib/ecoportal/api/common/graphql/model/CLAUDE.md +0 -28
  353. data/lib/ecoportal/api/graphql/CLAUDE.md +0 -37
  354. data/lib/ecoportal/api/graphql/base/CLAUDE.md +0 -50
  355. data/lib/ecoportal/api/graphql/builder/CLAUDE.md +0 -65
@@ -1,234 +1,234 @@
1
- module Ecoportal
2
- module API
3
- class GraphQL
4
- module Input
5
- class SearchConf
6
- # AI-assisted filter generation — builds a SearchConf from a natural-language
7
- # description using Claude (Anthropic API) with structured tool use output.
8
- #
9
- # Requires the `anthropic` gem to be available in the caller's environment.
10
- # No hard dependency is added to ecoportal-api-graphql's gemspec.
11
- #
12
- # Usage:
13
- # require 'anthropic'
14
- #
15
- # conf = SearchConf.from_description(
16
- # "find active pages in the Safety register updated in the last month",
17
- # api_key: ENV['ANTHROPIC_API_KEY'],
18
- # register_id: 'REG_SAFETY_123'
19
- # )
20
- # # => #<SearchConf filters=[...] sorters=...>
21
- #
22
- # # Then use it:
23
- # org.pages(searchConf: conf.to_h, first: 50)
24
- #
25
- # Options:
26
- # api_key: Anthropic API key (default: ENV['ANTHROPIC_API_KEY'])
27
- # model: Claude model ID (default: 'claude-sonnet-4-6')
28
- # register_id: Scope results to this register (adds register_filter)
29
- # context: Hash of extra context passed to the prompt (e.g. available states)
30
- # validate: Boolean — if true, raises on ambiguous/empty result (default: false)
31
- module AIGenerator
32
- TOOL_NAME = 'build_search_conf'.freeze
33
- DEFAULT_MODEL = 'claude-sonnet-4-6'.freeze
34
-
35
- SYSTEM_PROMPT = <<~PROMPT.freeze
36
- You are a search query translator for the EcoPortal GraphQL API.
37
- Convert natural-language descriptions into structured searchConf filter specifications.
38
-
39
- ## Available filter operations (snake_case strings — case-sensitive)
40
-
41
- | operation | params | notes |
42
- |---------------------|---------------------------------------------|--------------------------------|
43
- | exact_filter | key, value | equality match |
44
- | one_of_filter | key, values (array) | any of N values |
45
- | none_of_filter | key, values (array) | exclude all values |
46
- | date_filter | key, gte, lte, time_zone (UTC default) | ISO8601 or mode |
47
- | date_filter (mode) | key, mode, time_zone | modes: last_month, last_week, current_year, past, future, etc. |
48
- | register_filter | ids (array) | scope to register(s) |
49
- | has_any_filter | key | field has any non-empty value |
50
- | match_filter | key, value | partial text match |
51
- | and_filter | filters (array of filter objects) | explicit AND group |
52
- | or_filter | filters (array of filter objects) | OR group |
53
- | boolean_filter | key, value (true/false) | boolean field |
54
- | numeric_range_filter| key, gte, lte | numeric bounds |
55
- | isnt_exact_filter | key, value | negated equality |
56
-
57
- ## Common page field names (key values)
58
-
59
- | fieldName | type | common values |
60
- |-----------------|---------|----------------------------------------|
61
- | state | string | "active", "inactive", "complete" |
62
- | external_id | string | unique identifier |
63
- | name | string | page name (use match_filter for partial)|
64
- | creator_id | string | PersonMember ID |
65
- | created_at | date | ISO8601 datetime |
66
- | updated_at | date | ISO8601 datetime |
67
- | all_location_ids| string | location node ID (includes ancestors) |
68
- | location_id | string | exact location node ID |
69
- | other_tags | string | tag string values |
70
- | archived | boolean | true/false |
71
- | draft | boolean | true/false |
72
-
73
- ## Rules
74
- - Top-level filters array is implicitly AND — no need to wrap in and_filter unless nesting inside or_filter
75
- - Use register_filter when a specific register is mentioned or provided in context
76
- - Use date_filter with mode (e.g. "last_month") for relative dates; ISO8601 for absolute dates
77
- - Default sort is created_at desc unless the user specifies otherwise
78
- - If the description is too vague to produce a useful filter, produce an empty filters array and explain in the reasoning field
79
- - snake_case operation names are MANDATORY — CamelCase returns no results silently
80
-
81
- Call the build_search_conf tool with your result.
82
- PROMPT
83
-
84
- module_function
85
-
86
- # Build a SearchConf from a natural-language description via Claude API.
87
- def from_description(text, api_key: nil, model: DEFAULT_MODEL,
88
- register_id: nil, context: {}, validate: false)
89
- require_anthropic!
90
-
91
- client = ::Anthropic::Client.new(api_key: api_key || ENV.fetch('ANTHROPIC_API_KEY'))
92
-
93
- user_message = build_user_message(text, register_id: register_id, context: context)
94
- response = client.messages.create(
95
- model: model,
96
- max_tokens: 1024,
97
- system: SYSTEM_PROMPT,
98
- tools: [SEARCH_CONF_TOOL],
99
- messages: [{ role: 'user', content: user_message }]
100
- )
101
-
102
- result = extract_tool_result(response)
103
- conf = build_search_conf(result, register_id: register_id)
104
-
105
- if validate && conf.to_h.empty?
106
- raise ArgumentError, "AI could not produce filters for: #{text.inspect}. " \
107
- "Reasoning: #{result['reasoning']}"
108
- end
109
-
110
- conf
111
- end
112
-
113
- def require_anthropic!
114
- require 'anthropic'
115
- rescue LoadError
116
- raise LoadError,
117
- "SearchConf.from_description requires the 'anthropic' gem. " \
118
- "Add `gem 'anthropic'` to your Gemfile and run `bundle install`."
119
- end
120
-
121
- def build_user_message(text, register_id:, context:)
122
- parts = ["Convert this description to a searchConf filter: #{text.inspect}"]
123
- parts << "Register ID to scope results: #{register_id}" if register_id
124
- context.each { |k, v| parts << "Context — #{k}: #{v}" }
125
- parts.join("\n")
126
- end
127
-
128
- def extract_tool_result(response)
129
- tool_use = response.content.find { |b| b.type == 'tool_use' && b.name == TOOL_NAME }
130
- raise "AI did not call #{TOOL_NAME} — response: #{response.content.map(&:type)}" unless tool_use
131
-
132
- tool_use.input
133
- end
134
-
135
- def build_search_conf(result, register_id:)
136
- conf = SearchConf.new
137
- conf = apply_register(conf, result, register_id)
138
- conf = apply_filters(conf, result['filters'])
139
- conf = apply_sorters(conf, result['sorters'])
140
- apply_query(conf, result['query'])
141
- end
142
-
143
- def apply_register(conf, result, register_id)
144
- ids = result['register_ids']&.compact&.reject(&:empty?)
145
- if ids && !ids.empty?
146
- conf.filter(SearchConf::Register.new(*ids))
147
- elsif register_id
148
- conf.filter(SearchConf::Register.new(register_id))
149
- else
150
- conf
151
- end
152
- end
153
-
154
- def apply_filters(conf, filters)
155
- Array(filters).reduce(conf) do |c, f|
156
- c.filter(SearchConf::RawFilter.new(f['operation'], **symbolize(f['params'] || {})))
157
- end
158
- end
159
-
160
- def apply_sorters(conf, sorters)
161
- Array(sorters).reduce(conf) do |c, s|
162
- c.sort(s['key'].to_sym, s['direction']&.to_sym || :desc)
163
- end
164
- end
165
-
166
- def apply_query(conf, query)
167
- return conf unless query && !query.strip.empty?
168
-
169
- conf.query(query)
170
- end
171
-
172
- def symbolize(hash)
173
- hash.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
174
- end
175
-
176
- # JSON Schema for the tool — Claude must call this with the filter spec.
177
- SEARCH_CONF_TOOL = {
178
- name: TOOL_NAME,
179
- description: 'Output a structured searchConf filter specification',
180
- input_schema: {
181
- type: 'object',
182
- required: %w[filters],
183
- properties: {
184
- reasoning: {
185
- type: 'string',
186
- description: 'Brief explanation of the chosen filters'
187
- },
188
- register_ids: {
189
- type: 'array',
190
- description: 'Register IDs to scope the search (leave empty for org-wide)',
191
- items: { type: 'string' }
192
- },
193
- filters: {
194
- type: 'array',
195
- description: 'Array of filter objects (top-level is implicit AND)',
196
- items: {
197
- type: 'object',
198
- required: %w[operation params],
199
- properties: {
200
- operation: {
201
- type: 'string',
202
- description: 'Filter operation name (snake_case)'
203
- },
204
- params: {
205
- type: 'object',
206
- description: 'Operation parameters (key, value, ids, filters, gte, lte, etc.)'
207
- }
208
- }
209
- }
210
- },
211
- sorters: {
212
- type: 'array',
213
- items: {
214
- type: 'object',
215
- required: %w[key direction],
216
- properties: {
217
- key: { type: 'string' },
218
- direction: { type: 'string', enum: %w[asc desc] }
219
- }
220
- }
221
- },
222
- query: {
223
- type: 'string',
224
- description: 'Full-text search string (optional)'
225
- }
226
- }
227
- }
228
- }.freeze
229
- end
230
- end
231
- end
232
- end
233
- end
234
- end
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Input
5
+ class SearchConf
6
+ # AI-assisted filter generation — builds a SearchConf from a natural-language
7
+ # description using Claude (Anthropic API) with structured tool use output.
8
+ #
9
+ # Requires the `anthropic` gem to be available in the caller's environment.
10
+ # No hard dependency is added to ecoportal-api-graphql's gemspec.
11
+ #
12
+ # Usage:
13
+ # require 'anthropic'
14
+ #
15
+ # conf = SearchConf.from_description(
16
+ # "find active pages in the Safety register updated in the last month",
17
+ # api_key: ENV['ANTHROPIC_API_KEY'],
18
+ # register_id: 'REG_SAFETY_123'
19
+ # )
20
+ # # => #<SearchConf filters=[...] sorters=...>
21
+ #
22
+ # # Then use it:
23
+ # org.pages(searchConf: conf.to_h, first: 50)
24
+ #
25
+ # Options:
26
+ # api_key: Anthropic API key (default: ENV['ANTHROPIC_API_KEY'])
27
+ # model: Claude model ID (default: 'claude-sonnet-4-6')
28
+ # register_id: Scope results to this register (adds register_filter)
29
+ # context: Hash of extra context passed to the prompt (e.g. available states)
30
+ # validate: Boolean — if true, raises on ambiguous/empty result (default: false)
31
+ module AIGenerator
32
+ TOOL_NAME = 'build_search_conf'.freeze
33
+ DEFAULT_MODEL = 'claude-sonnet-4-6'.freeze
34
+
35
+ SYSTEM_PROMPT = <<~PROMPT.freeze
36
+ You are a search query translator for the EcoPortal GraphQL API.
37
+ Convert natural-language descriptions into structured searchConf filter specifications.
38
+
39
+ ## Available filter operations (snake_case strings — case-sensitive)
40
+
41
+ | operation | params | notes |
42
+ |---------------------|---------------------------------------------|--------------------------------|
43
+ | exact_filter | key, value | equality match |
44
+ | one_of_filter | key, values (array) | any of N values |
45
+ | none_of_filter | key, values (array) | exclude all values |
46
+ | date_filter | key, gte, lte, time_zone (UTC default) | ISO8601 or mode |
47
+ | date_filter (mode) | key, mode, time_zone | modes: last_month, last_week, current_year, past, future, etc. |
48
+ | register_filter | ids (array) | scope to register(s) |
49
+ | has_any_filter | key | field has any non-empty value |
50
+ | match_filter | key, value | partial text match |
51
+ | and_filter | filters (array of filter objects) | explicit AND group |
52
+ | or_filter | filters (array of filter objects) | OR group |
53
+ | boolean_filter | key, value (true/false) | boolean field |
54
+ | numeric_range_filter| key, gte, lte | numeric bounds |
55
+ | isnt_exact_filter | key, value | negated equality |
56
+
57
+ ## Common page field names (key values)
58
+
59
+ | fieldName | type | common values |
60
+ |-----------------|---------|----------------------------------------|
61
+ | state | string | "active", "inactive", "complete" |
62
+ | external_id | string | unique identifier |
63
+ | name | string | page name (use match_filter for partial)|
64
+ | creator_id | string | PersonMember ID |
65
+ | created_at | date | ISO8601 datetime |
66
+ | updated_at | date | ISO8601 datetime |
67
+ | all_location_ids| string | location node ID (includes ancestors) |
68
+ | location_id | string | exact location node ID |
69
+ | other_tags | string | tag string values |
70
+ | archived | boolean | true/false |
71
+ | draft | boolean | true/false |
72
+
73
+ ## Rules
74
+ - Top-level filters array is implicitly AND — no need to wrap in and_filter unless nesting inside or_filter
75
+ - Use register_filter when a specific register is mentioned or provided in context
76
+ - Use date_filter with mode (e.g. "last_month") for relative dates; ISO8601 for absolute dates
77
+ - Default sort is created_at desc unless the user specifies otherwise
78
+ - If the description is too vague to produce a useful filter, produce an empty filters array and explain in the reasoning field
79
+ - snake_case operation names are MANDATORY — CamelCase returns no results silently
80
+
81
+ Call the build_search_conf tool with your result.
82
+ PROMPT
83
+
84
+ module_function
85
+
86
+ # Build a SearchConf from a natural-language description via Claude API.
87
+ def from_description(text, api_key: nil, model: DEFAULT_MODEL,
88
+ register_id: nil, context: {}, validate: false)
89
+ require_anthropic!
90
+
91
+ client = ::Anthropic::Client.new(api_key: api_key || ENV.fetch('ANTHROPIC_API_KEY'))
92
+
93
+ user_message = build_user_message(text, register_id: register_id, context: context)
94
+ response = client.messages.create(
95
+ model: model,
96
+ max_tokens: 1024,
97
+ system: SYSTEM_PROMPT,
98
+ tools: [SEARCH_CONF_TOOL],
99
+ messages: [{ role: 'user', content: user_message }]
100
+ )
101
+
102
+ result = extract_tool_result(response)
103
+ conf = build_search_conf(result, register_id: register_id)
104
+
105
+ if validate && conf.to_h.empty?
106
+ raise ArgumentError, "AI could not produce filters for: #{text.inspect}. " \
107
+ "Reasoning: #{result['reasoning']}"
108
+ end
109
+
110
+ conf
111
+ end
112
+
113
+ def require_anthropic!
114
+ require 'anthropic'
115
+ rescue LoadError
116
+ raise LoadError,
117
+ "SearchConf.from_description requires the 'anthropic' gem. " \
118
+ "Add `gem 'anthropic'` to your Gemfile and run `bundle install`."
119
+ end
120
+
121
+ def build_user_message(text, register_id:, context:)
122
+ parts = ["Convert this description to a searchConf filter: #{text.inspect}"]
123
+ parts << "Register ID to scope results: #{register_id}" if register_id
124
+ context.each { |k, v| parts << "Context — #{k}: #{v}" }
125
+ parts.join("\n")
126
+ end
127
+
128
+ def extract_tool_result(response)
129
+ tool_use = response.content.find { |b| b.type == 'tool_use' && b.name == TOOL_NAME }
130
+ raise "AI did not call #{TOOL_NAME} — response: #{response.content.map(&:type)}" unless tool_use
131
+
132
+ tool_use.input
133
+ end
134
+
135
+ def build_search_conf(result, register_id:)
136
+ conf = SearchConf.new
137
+ conf = apply_register(conf, result, register_id)
138
+ conf = apply_filters(conf, result['filters'])
139
+ conf = apply_sorters(conf, result['sorters'])
140
+ apply_query(conf, result['query'])
141
+ end
142
+
143
+ def apply_register(conf, result, register_id)
144
+ ids = result['register_ids']&.compact&.reject(&:empty?)
145
+ if ids && !ids.empty?
146
+ conf.filter(SearchConf::Register.new(*ids))
147
+ elsif register_id
148
+ conf.filter(SearchConf::Register.new(register_id))
149
+ else
150
+ conf
151
+ end
152
+ end
153
+
154
+ def apply_filters(conf, filters)
155
+ Array(filters).reduce(conf) do |c, f|
156
+ c.filter(SearchConf::RawFilter.new(f['operation'], **symbolize(f['params'] || {})))
157
+ end
158
+ end
159
+
160
+ def apply_sorters(conf, sorters)
161
+ Array(sorters).reduce(conf) do |c, s|
162
+ c.sort(s['key'].to_sym, s['direction']&.to_sym || :desc)
163
+ end
164
+ end
165
+
166
+ def apply_query(conf, query)
167
+ return conf unless query && !query.strip.empty?
168
+
169
+ conf.query(query)
170
+ end
171
+
172
+ def symbolize(hash)
173
+ hash.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
174
+ end
175
+
176
+ # JSON Schema for the tool — Claude must call this with the filter spec.
177
+ SEARCH_CONF_TOOL = {
178
+ name: TOOL_NAME,
179
+ description: 'Output a structured searchConf filter specification',
180
+ input_schema: {
181
+ type: 'object',
182
+ required: %w[filters],
183
+ properties: {
184
+ reasoning: {
185
+ type: 'string',
186
+ description: 'Brief explanation of the chosen filters'
187
+ },
188
+ register_ids: {
189
+ type: 'array',
190
+ description: 'Register IDs to scope the search (leave empty for org-wide)',
191
+ items: { type: 'string' }
192
+ },
193
+ filters: {
194
+ type: 'array',
195
+ description: 'Array of filter objects (top-level is implicit AND)',
196
+ items: {
197
+ type: 'object',
198
+ required: %w[operation params],
199
+ properties: {
200
+ operation: {
201
+ type: 'string',
202
+ description: 'Filter operation name (snake_case)'
203
+ },
204
+ params: {
205
+ type: 'object',
206
+ description: 'Operation parameters (key, value, ids, filters, gte, lte, etc.)'
207
+ }
208
+ }
209
+ }
210
+ },
211
+ sorters: {
212
+ type: 'array',
213
+ items: {
214
+ type: 'object',
215
+ required: %w[key direction],
216
+ properties: {
217
+ key: { type: 'string' },
218
+ direction: { type: 'string', enum: %w[asc desc] }
219
+ }
220
+ }
221
+ },
222
+ query: {
223
+ type: 'string',
224
+ description: 'Full-text search string (optional)'
225
+ }
226
+ }
227
+ }
228
+ }.freeze
229
+ end
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
@@ -1,12 +1,12 @@
1
- module Ecoportal
2
- module API
3
- class GraphQL
4
- module Input
5
- class SearchFilter < Logic::BaseModel
6
- passthrough :id, :fieldName, :key, :operation
7
- passthrough :params, :path
8
- end
9
- end
10
- end
11
- end
12
- end
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Input
5
+ class SearchFilter < Logic::BaseModel
6
+ passthrough :id, :fieldName, :key, :operation
7
+ passthrough :params, :path
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,11 +1,11 @@
1
- module Ecoportal
2
- module API
3
- class GraphQL
4
- module Input
5
- class SearchSorter < Logic::BaseModel
6
- passthrough :direction, :key, :missing
7
- end
8
- end
9
- end
10
- end
11
- end
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Input
5
+ class SearchSorter < Logic::BaseModel
6
+ passthrough :direction, :key, :missing
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,18 +1,18 @@
1
- module Ecoportal
2
- module API
3
- class GraphQL
4
- module Input
5
- class WorkflowCommand
6
- module AddActionTag
7
- SCHEMA_VERSION = '20260605'.freeze
8
- VALID_KEYS = %i[stageId taskId scheduledCallbackId actionId tag].freeze
9
-
10
- def self.build(**kwargs)
11
- kwargs.slice(*VALID_KEYS).compact
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Input
5
+ class WorkflowCommand
6
+ module AddActionTag
7
+ SCHEMA_VERSION = '20260605'.freeze
8
+ VALID_KEYS = %i[stageId taskId scheduledCallbackId actionId tag].freeze
9
+
10
+ def self.build(**kwargs)
11
+ kwargs.slice(*VALID_KEYS).compact
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,18 +1,18 @@
1
- module Ecoportal
2
- module API
3
- class GraphQL
4
- module Input
5
- class WorkflowCommand
6
- module AddBinding
7
- SCHEMA_VERSION = '20260605'.freeze
8
- VALID_KEYS = %i[placeholderId forceId name referenceId type].freeze
9
-
10
- def self.build(**kwargs)
11
- kwargs.slice(*VALID_KEYS).compact
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Input
5
+ class WorkflowCommand
6
+ module AddBinding
7
+ SCHEMA_VERSION = '20260605'.freeze
8
+ VALID_KEYS = %i[placeholderId forceId name referenceId type].freeze
9
+
10
+ def self.build(**kwargs)
11
+ kwargs.slice(*VALID_KEYS).compact
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,18 +1,18 @@
1
- module Ecoportal
2
- module API
3
- class GraphQL
4
- module Input
5
- class WorkflowCommand
6
- module AddCommentTaggingUserGroup
7
- SCHEMA_VERSION = '20260605'.freeze
8
- VALID_KEYS = %i[stageId userGroupId].freeze
9
-
10
- def self.build(**kwargs)
11
- kwargs.slice(*VALID_KEYS).compact
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Input
5
+ class WorkflowCommand
6
+ module AddCommentTaggingUserGroup
7
+ SCHEMA_VERSION = '20260605'.freeze
8
+ VALID_KEYS = %i[stageId userGroupId].freeze
9
+
10
+ def self.build(**kwargs)
11
+ kwargs.slice(*VALID_KEYS).compact
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end